summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorSimon Chopin <simon.chopin@canonical.com>2021-11-30 13:56:56 +0100
committerPatrick <tingping@tingping.se>2021-11-30 08:35:04 -0600
commitbbd60a96ecd0e190625c68bedca4e46928ee2b4d (patch)
tree13210fa25f482b13d732e4487b26fa5f00fe5aa2
parent8443755772160e61679e3122190da18ba10d8878 (diff)
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 <simon.chopin@canonical.com>

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()
-rw-r--r--plugins/fishlim/fish.c58
-rw-r--r--plugins/fishlim/fish.h2
-rw-r--r--plugins/fishlim/plugin_hexchat.c4
-rw-r--r--plugins/fishlim/tests/tests.c5
4 files changed, 68 insertions, 1 deletions
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 <openssl/provider.h>
+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;
 }