Fix openssl 3.0 support due changes on legacy algorithms. (#4215)

md4, md5 and other algorithms has been moved under the legacy provider
This commit is contained in:
Giovanni 2024-02-12 17:44:04 +08:00 committed by GitHub
parent 722de8bb0a
commit c5e787d867
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 69 additions and 2 deletions

View file

@ -9,6 +9,9 @@
#include <openssl/sha.h>
#include <openssl/md4.h>
#include <openssl/md5.h>
#include <openssl/err.h>
#include <rz_util.h>
#define rz_openssl_plugin_context_new(pluginname) \
static void *openssl_plugin_##pluginname##_context_new() { \
@ -35,6 +38,10 @@
static bool openssl_plugin_##pluginname##_init(void *context) { \
rz_return_val_if_fail(context, false); \
if (EVP_DigestInit_ex((EVP_MD_CTX *)context, evpmd(), NULL) != 1) { \
char emsg[256] = { 0 }; \
ERR_error_string_n(ERR_get_error(), emsg, sizeof(emsg)); \
RZ_LOG_ERROR("openssl: %s\n", emsg); \
ERR_clear_error(); \
return false; \
} \
return true; \
@ -47,6 +54,10 @@
return true; \
} \
if (EVP_DigestUpdate((EVP_MD_CTX *)context, data, size) != 1) { \
char emsg[256] = { 0 }; \
ERR_error_string_n(ERR_get_error(), emsg, sizeof(emsg)); \
RZ_LOG_ERROR("openssl: %s\n", emsg); \
ERR_clear_error(); \
return false; \
} \
return true; \
@ -56,6 +67,10 @@
static bool openssl_plugin_##pluginname##_final(void *context, ut8 *digest) { \
rz_return_val_if_fail((context) && (digest), false); \
if (EVP_DigestFinal_ex((EVP_MD_CTX *)context, digest, NULL) != 1) { \
char emsg[256] = { 0 }; \
ERR_error_string_n(ERR_get_error(), emsg, sizeof(emsg)); \
RZ_LOG_ERROR("openssl: %s\n", emsg); \
ERR_clear_error(); \
return false; \
} \
return true; \

View file

@ -24,6 +24,52 @@ typedef struct hash_cfg_config_t {
const RzHashPlugin *plugin;
} HashCfgConfig;
#if HAVE_LIB_SSL
#include <openssl/opensslv.h>
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
/**
* From openssl 3.0 some algos got moved to the legacy provider.
* this means that their availability requires to preload a provider
* before calling the initialization of each algorithms.
*/
#define REQUIRE_OPENSSL_PROVIDER 1
#include <openssl/provider.h>
typedef struct {
OSSL_PROVIDER *provider;
size_t counter;
} RzHashOpenSSL;
static RzHashOpenSSL *openssl_lib = NULL;
static void rz_hash_init_openssl_lib(void) {
if (!openssl_lib) {
openssl_lib = RZ_NEW0(RzHashOpenSSL);
if (!openssl_lib) {
RZ_LOG_ERROR("Cannot allocate RzHashOpenSSL\n");
return;
}
openssl_lib->provider = OSSL_PROVIDER_try_load(NULL, "legacy", 1);
if (!OSSL_PROVIDER_available(NULL, "legacy")) {
RZ_LOG_WARN("Cannot load openssl legacy provider. Some algorithm might not be available.\n");
}
}
openssl_lib->counter++;
}
static void rz_hash_fini_openssl_lib(void) {
if (!openssl_lib || (--openssl_lib->counter) > 0) {
return;
}
OSSL_PROVIDER_unload(openssl_lib->provider);
free(openssl_lib);
openssl_lib = NULL;
}
#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */
#endif /* HAVE_LIB_SSL */
static RzHashPlugin *hash_static_plugins[] = { RZ_HASH_STATIC_PLUGINS };
/**
@ -659,6 +705,9 @@ RZ_API RzHash *rz_hash_new(void) {
if (!rh) {
return NULL;
}
#if REQUIRE_OPENSSL_PROVIDER
rz_hash_init_openssl_lib();
#endif /* REQUIRE_OPENSSL_PROVIDER */
rh->plugins = rz_list_new();
for (int i = 0; i < RZ_ARRAY_SIZE(hash_static_plugins); i++) {
rz_hash_plugin_add(rh, hash_static_plugins[i]);
@ -666,12 +715,15 @@ RZ_API RzHash *rz_hash_new(void) {
return rh;
}
RZ_API void rz_hash_free(RzHash *rh) {
RZ_API void rz_hash_free(RZ_NULLABLE RzHash *rh) {
if (!rh) {
return;
}
rz_list_free(rh->plugins);
free(rh);
#if REQUIRE_OPENSSL_PROVIDER
rz_hash_fini_openssl_lib();
#endif /* REQUIRE_OPENSSL_PROVIDER */
}
/**

View file

@ -51,7 +51,7 @@ typedef struct rz_hash_cfg_t {
#ifdef RZ_API
RZ_API RzHash *rz_hash_new(void);
RZ_API void rz_hash_free(RzHash *rh);
RZ_API void rz_hash_free(RZ_NULLABLE RzHash *rh);
RZ_API bool rz_hash_plugin_add(RZ_NONNULL RzHash *rh, RZ_NONNULL RZ_OWN RzHashPlugin *plugin);
RZ_API bool rz_hash_plugin_del(RZ_NONNULL RzHash *rh, RZ_NONNULL RzHashPlugin *plugin);
RZ_API RZ_BORROW const RzHashPlugin *rz_hash_plugin_by_index(RZ_NONNULL RzHash *rh, size_t index);