Skip to content

Commit db482c4

Browse files
authored
Merge pull request ClickHouse#78520 from ClickHouse/openssl-modernize-functions-hashing
Modernize OpenSSL usage in hash functions
2 parents c5bf4db + 2678143 commit db482c4

File tree

5 files changed

+134
-108
lines changed

5 files changed

+134
-108
lines changed

base/poco/Crypto/include/Poco/Crypto/OpenSSLInitializer.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020

2121
#include <openssl/crypto.h>
22+
#include <openssl/provider.h>
2223
#include "Poco/AtomicCounter.h"
2324
#include "Poco/Crypto/Crypto.h"
2425
#include "Poco/Mutex.h"
@@ -83,6 +84,8 @@ namespace Crypto
8384
private:
8485
static Poco::FastMutex * _mutexes;
8586
static Poco::AtomicCounter _rc;
87+
88+
static OSSL_PROVIDER * legacy_provider;
8689
};
8790

8891

base/poco/Crypto/src/OpenSSLInitializer.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <openssl/rand.h>
2020
#include <openssl/crypto.h>
2121
#include <openssl/err.h>
22+
#include <openssl/provider.h>
2223
#if OPENSSL_VERSION_NUMBER >= 0x0907000L
2324
#include <openssl/conf.h>
2425
#endif
@@ -36,6 +37,7 @@ namespace Crypto {
3637

3738
Poco::FastMutex* OpenSSLInitializer::_mutexes(0);
3839
Poco::AtomicCounter OpenSSLInitializer::_rc;
40+
OSSL_PROVIDER * OpenSSLInitializer::legacy_provider;
3941

4042

4143
OpenSSLInitializer::OpenSSLInitializer()
@@ -67,21 +69,25 @@ void OpenSSLInitializer::initialize()
6769
SSL_library_init();
6870
SSL_load_error_strings();
6971
OpenSSL_add_all_algorithms();
70-
72+
7173
char seed[SEEDSIZE];
7274
RandomInputStream rnd;
7375
rnd.read(seed, sizeof(seed));
7476
RAND_seed(seed, SEEDSIZE);
75-
77+
78+
legacy_provider = OSSL_PROVIDER_load(NULL, "legacy");
79+
if (!legacy_provider)
80+
throw std::runtime_error("Failed to load OpenSSL legacy provider");
81+
7682
int nMutexes = CRYPTO_num_locks();
7783
_mutexes = new Poco::FastMutex[nMutexes];
7884
CRYPTO_set_locking_callback(&OpenSSLInitializer::lock);
7985
// Not needed on Windows (see SF #110: random unhandled exceptions when linking with ssl).
8086
// https://sourceforge.net/p/poco/bugs/110/
8187
//
8288
// From http://www.openssl.org/docs/crypto/threads.html :
83-
// "If the application does not register such a callback using CRYPTO_THREADID_set_callback(),
84-
// then a default implementation is used - on Windows and BeOS this uses the system's
89+
// "If the application does not register such a callback using CRYPTO_THREADID_set_callback(),
90+
// then a default implementation is used - on Windows and BeOS this uses the system's
8591
// default thread identifying APIs"
8692
CRYPTO_set_id_callback(&OpenSSLInitializer::id);
8793
CRYPTO_set_dynlock_create_callback(&OpenSSLInitializer::dynlockCreate);
@@ -100,7 +106,8 @@ void OpenSSLInitializer::uninitialize()
100106
CRYPTO_set_locking_callback(0);
101107
CRYPTO_set_id_callback(0);
102108
delete [] _mutexes;
103-
109+
110+
OSSL_PROVIDER_unload(legacy_provider);
104111
CONF_modules_free();
105112
}
106113
}

contrib/openssl-cmake/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1171,6 +1171,7 @@ if(NOT ENABLE_OPENSSL_DYNAMIC)
11711171
set(CRYPTO_SRC ${CRYPTO_SRC}
11721172
${OPENSSL_SOURCE_DIR}/providers/fips/fips_entry.c
11731173
${OPENSSL_SOURCE_DIR}/providers/fips/fipsprov.c
1174+
${OPENSSL_SOURCE_DIR}/providers/legacyprov.c
11741175
)
11751176
endif()
11761177

@@ -1453,10 +1454,15 @@ if(ENABLE_OPENSSL_DYNAMIC)
14531454
set_target_properties(ssl PROPERTIES VERSION "${LIB_VERSION}" SOVERSION "${LIB_SOVERSION}")
14541455
set_target_properties(ssl PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/programs)
14551456
else()
1457+
# Enable legacy crypto support for OpenSSL 3.+
1458+
# to avoid `dlopen(legacy.so)`.
1459+
add_definitions(-DSTATIC_LEGACY)
1460+
14561461
add_library(crypto ${CRYPTO_SRC})
14571462
add_library(ssl ${SSL_SRC})
14581463
endif()
14591464

1465+
14601466
target_include_directories(crypto
14611467
SYSTEM PUBLIC "${PLATFORM_DIRECTORY}/include"
14621468
PRIVATE "${PLATFORM_DIRECTORY}/include_private")

src/Functions/FunctionsHashing.h

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
#include <Common/HashTable/Hash.h>
2020

2121
#if USE_SSL
22-
# include <openssl/md5.h>
22+
# include <openssl/evp.h>
2323
#endif
2424

2525
#include <bit>
@@ -62,6 +62,7 @@ namespace ErrorCodes
6262
extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
6363
extern const int NOT_IMPLEMENTED;
6464
extern const int ILLEGAL_COLUMN;
65+
extern const int OPENSSL_ERROR;
6566
}
6667

6768
namespace impl
@@ -245,12 +246,22 @@ struct HalfMD5Impl
245246
uint64_t uint64_data;
246247
} buf;
247248

248-
MD5_CTX ctx;
249-
MD5_Init(&ctx);
250-
MD5_Update(&ctx, reinterpret_cast<const unsigned char *>(begin), size);
251-
MD5_Final(buf.char_data, &ctx);
249+
using EVP_MD_CTX_ptr = std::unique_ptr<EVP_MD_CTX, decltype(&EVP_MD_CTX_free)>;
250+
const auto ctx = EVP_MD_CTX_ptr(EVP_MD_CTX_new(), EVP_MD_CTX_free);
252251

253-
/// Compatibility with existing code. Cast need for old poco AND macos where UInt64 != uint64_t
252+
if (!ctx)
253+
throw Exception(ErrorCodes::OPENSSL_ERROR, "EVP_MD_CTX_new failed");
254+
255+
if (!EVP_DigestInit_ex(ctx.get(), EVP_md5(), nullptr))
256+
throw Exception(ErrorCodes::OPENSSL_ERROR, "EVP_DigestInit_ex failed");
257+
258+
if (!EVP_DigestUpdate(ctx.get(), begin, size))
259+
throw Exception(ErrorCodes::OPENSSL_ERROR, "EVP_DigestUpdate failed");
260+
261+
if (!EVP_DigestFinal_ex(ctx.get(), buf.char_data, nullptr))
262+
throw Exception(ErrorCodes::OPENSSL_ERROR, "EVP_DigestFinal_ex failed");
263+
264+
/// Compatibility with existing code. Cast is necessary for old poco AND macos where UInt64 != uint64_t
254265
transformEndianness<std::endian::big>(buf.uint64_data);
255266
return buf.uint64_data;
256267
}

0 commit comments

Comments
 (0)