aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArne Schwabe2022-05-12 14:14:28 +0200
committerGert Doering2022-05-13 09:06:57 +0200
commit3690939126cf84b166157bad96e724caea61346d (patch)
treed4d4896d7ff47762bf9048272c79dfc0d61d9256
parentc5d61b345e21860b2357206848535a8452754ad8 (diff)
downloadopenvpn-3690939126cf84b166157bad96e724caea61346d.zip
openvpn-3690939126cf84b166157bad96e724caea61346d.tar.gz
Fix allowing/showing unsupported ciphers and digests
This is a minimal version to hide the non-supported ciphers in these show-cipher/show-digests listings. It also adds code to the kt_md_get/ kt_cipher_get functions to error out early instead of getting an ugly backtrace with OpenSSL errors later when actually trying to use the ciphers. This allows make check to work again on with OpenSSL 3.0. The changes are kept minimal to avoid pulling in all the other refactoring for OpenSSL 3.0. This commit is partly cherry-picked from ab3f32b9. Signed-off-by: Arne Schwabe <arne@rfc2549.org> Acked-by: Gert Doering <gert@greenie.muc.de> Message-Id: <20220512121429.2096164-7-arne@rfc2549.org> URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg24334.html Signed-off-by: Gert Doering <gert@greenie.muc.de>
-rw-r--r--src/openvpn/crypto_openssl.c52
1 files changed, 48 insertions, 4 deletions
diff --git a/src/openvpn/crypto_openssl.c b/src/openvpn/crypto_openssl.c
index beeaee4..74685b3 100644
--- a/src/openvpn/crypto_openssl.c
+++ b/src/openvpn/crypto_openssl.c
@@ -166,7 +166,8 @@ crypto_load_provider(const char *provider)
#endif
}
-void crypto_unload_provider(const char *provname, provider_t *provider)
+void
+crypto_unload_provider(const char *provname, provider_t *provider)
{
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
if (!OSSL_PROVIDER_unload(provider))
@@ -339,7 +340,11 @@ show_available_ciphers(void)
|| cipher_kt_mode_aead(cipher)
))
{
- cipher_list[num_ciphers++] = cipher;
+ /* Check explicit availibility (for OpenSSL 3.0) */
+ if (cipher_kt_get(cipher_kt_name(cipher)))
+ {
+ cipher_list[num_ciphers++] = cipher;
+ }
}
if (num_ciphers == (sizeof(cipher_list)/sizeof(*cipher_list)))
{
@@ -372,6 +377,13 @@ show_available_ciphers(void)
}
void
+print_digest(EVP_MD *digest, void *unused)
+{
+ printf("%s %d bit digest size\n", EVP_MD_name(digest),
+ EVP_MD_size(digest) * 8);
+}
+
+void
show_available_digests(void)
{
int nid;
@@ -384,16 +396,21 @@ show_available_digests(void)
"the --auth option.\n\n");
#endif
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+ EVP_MD_do_all_provided(NULL, print_digest, NULL);
+#else
for (nid = 0; nid < 10000; ++nid)
{
const EVP_MD *digest = EVP_get_digestbynid(nid);
if (digest)
{
- printf("%s %d bit digest size\n",
- OBJ_nid2sn(nid), EVP_MD_size(digest) * 8);
+ /* We cast the const away so we can keep the function prototype
+ * compatible with EVP_MD_do_all_provided */
+ print_digest((EVP_MD *)digest, NULL);
}
}
printf("\n");
+#endif
}
void
@@ -624,6 +641,19 @@ cipher_kt_get(const char *ciphername)
ciphername = translate_cipher_name_from_openvpn(ciphername);
cipher = EVP_get_cipherbyname(ciphername);
+ /* This is a workaround for OpenSSL 3.0 to infer if the cipher is valid
+ * without doing all the refactoring that OpenVPN 2.6 has. This will
+ * not support custom algorithm from providers but at least ignore
+ * algorithms that are not available without providers (legacy) */
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+ EVP_CIPHER *tmpcipher = EVP_CIPHER_fetch(NULL, ciphername, NULL);
+ if (!tmpcipher)
+ {
+ cipher = NULL;
+ }
+ EVP_CIPHER_free(tmpcipher);
+#endif
+
if (NULL == cipher)
{
crypto_msg(D_LOW, "Cipher algorithm '%s' not found", ciphername);
@@ -924,6 +954,20 @@ md_kt_get(const char *digest)
const EVP_MD *md = NULL;
ASSERT(digest);
md = EVP_get_digestbyname(digest);
+
+ /* This is a workaround for OpenSSL 3.0 to infer if the digest is valid
+ * without doing all the refactoring that OpenVPN 2.6 has. This will
+ * not support custom algorithm from providers but at least ignore
+ * algorithms that are not available without providers (legacy) */
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+ EVP_MD *tmpmd = EVP_MD_fetch(NULL, digest, NULL);
+ if (!tmpmd)
+ {
+ md = NULL;
+ }
+ EVP_MD_free(tmpmd);
+#endif
+
if (!md)
{
crypto_msg(M_FATAL, "Message hash algorithm '%s' not found", digest);