From bbd60a96ecd0e190625c68bedca4e46928ee2b4d Mon Sep 17 00:00:00 2001 From: Simon Chopin Date: Tue, 30 Nov 2021 13:56:56 +0100 Subject: fish: enable the legacy provider if build against OpenSSL3 OpenSSL 3.0 disables a number of "legacy" algorithms by default, and we need to enable them manually using their provider system. Note that explicitly loading a provider will disable the implicit default provider, which is why we need to load it explicitly. Closes #2629 Signed-off-by: Simon Chopin V2: * use a local OSSL_LIB_CTX to avoid leaking the legacy algorithms into the main SSL context. * Simplify the fish_init() error paths by calling fish_deinit() --- plugins/fishlim/fish.c | 58 ++++++++++++++++++++++++++++++++++++++++ plugins/fishlim/fish.h | 2 ++ plugins/fishlim/plugin_hexchat.c | 4 +++ plugins/fishlim/tests/tests.c | 5 +++- 4 files changed, 68 insertions(+), 1 deletion(-) diff --git a/plugins/fishlim/fish.c b/plugins/fishlim/fish.c index c2c2b9da..5a27e4cb 100644 --- a/plugins/fishlim/fish.c +++ b/plugins/fishlim/fish.c @@ -87,6 +87,54 @@ static const signed char fish_unbase64[256] = { dest |= (uint8_t)*((source)++); \ } while (0); +#if OPENSSL_VERSION_NUMBER >= 0x30000000L +#include +static OSSL_PROVIDER *legacy_provider; +static OSSL_PROVIDER *default_provider; +static OSSL_LIB_CTX* *ossl_ctx; +#endif + +int fish_init(void) +{ +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + ossl_ctx = OSSL_LIB_CTX_new(); + if (!ossl_ctx) + return 0; + + legacy_provider = OSSL_PROVIDER_load(ossl_ctx, "legacy"); + if (!legacy_provider) { + fish_deinit(); + return 0; + } + + default_provider = OSSL_PROVIDER_load(ossl_ctx, "default"); + if (!default_provider) { + fish_deinit(); + return 0; + } +#endif + return 1; +} + +void fish_deinit(void) +{ +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + if (legacy_provider) { + OSSL_PROVIDER_unload(legacy_provider); + legacy_provider = NULL; + } + + if (default_provider) { + OSSL_PROVIDER_unload(default_provider); + default_provider = NULL; + } + + if (ossl_ctx) { + OSSL_LIB_CTX_free(ossl_ctx); + ossl_ctx = NULL; + } +#endif +} /** * Encode ECB FiSH Base64 @@ -228,9 +276,19 @@ char *fish_cipher(const char *plaintext, size_t plaintext_len, const char *key, plaintext_len -= 8; } +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + cipher = EVP_CIPHER_fetch(ossl_ctx, "BF-CBC", NULL); +#else cipher = (EVP_CIPHER *) EVP_bf_cbc(); +#endif + } else if (mode == EVP_CIPH_ECB_MODE) { + +#if OPENSSL_VERSION_NUMBER >= 0x30000000L + cipher = EVP_CIPHER_fetch(ossl_ctx, "BF-ECB", NULL); +#else cipher = (EVP_CIPHER *) EVP_bf_ecb(); +#endif } /* Zero Padding */ diff --git a/plugins/fishlim/fish.h b/plugins/fishlim/fish.h index 6a2e911c..75829061 100644 --- a/plugins/fishlim/fish.h +++ b/plugins/fishlim/fish.h @@ -35,6 +35,8 @@ enum fish_mode { FISH_CBC_MODE = 0x2 }; +int fish_init(void); +void fish_deinit(void); char *fish_base64_encode(const char *message, size_t message_len); char *fish_base64_decode(const char *message, size_t *final_len); char *fish_encrypt(const char *key, size_t keylen, const char *message, size_t message_len, enum fish_mode mode); diff --git a/plugins/fishlim/plugin_hexchat.c b/plugins/fishlim/plugin_hexchat.c index 93e28487..a8b127f2 100644 --- a/plugins/fishlim/plugin_hexchat.c +++ b/plugins/fishlim/plugin_hexchat.c @@ -815,6 +815,9 @@ int hexchat_plugin_init(hexchat_plugin *plugin_handle, hexchat_hook_server_attrs(ph, "TOPIC", HEXCHAT_PRI_NORM, handle_incoming, NULL); hexchat_hook_server_attrs(ph, "332", HEXCHAT_PRI_NORM, handle_incoming, NULL); + if (!fish_init()) + return 0; + if (!dh1080_init()) return 0; @@ -828,6 +831,7 @@ int hexchat_plugin_init(hexchat_plugin *plugin_handle, int hexchat_plugin_deinit(void) { g_clear_pointer(&pending_exchanges, g_hash_table_destroy); dh1080_deinit(); + fish_deinit(); hexchat_printf(ph, "%s plugin unloaded\n", plugin_name); return 1; diff --git a/plugins/fishlim/tests/tests.c b/plugins/fishlim/tests/tests.c index f3e852d2..12b10d1d 100644 --- a/plugins/fishlim/tests/tests.c +++ b/plugins/fishlim/tests/tests.c @@ -278,5 +278,8 @@ main(int argc, char *argv[]) { g_test_add_func("/fishlim/max_text_command_len", test_max_text_command_len); g_test_add_func("/fishlim/foreach_utf8_data_chunks", test_foreach_utf8_data_chunks); - return g_test_run(); + fish_init(); + int ret = g_test_run(); + fish_deinit(); + return ret; } -- cgit 1.4.1