From 8aed156be81a3bdd3098bfed5e8f95662d06633c Mon Sep 17 00:00:00 2001 From: Arne Schwabe Date: Thu, 9 May 2024 00:05:40 +0200 Subject: [PATCH] Workaround issue in LibreSSL crashing when enumerating digests/ciphers OpenBSD/LibreSSL reimplemented EVP_get_cipherbyname/EVP_get_digestbyname and broke calling EVP_get_cipherbynid/EVP_get_digestbyname with an invalid nid in the process so that it would segfault. Workaround but doing that NULL check in OpenVPN instead of leaving it to the library. Github: see also https://github.com/libressl/openbsd/issues/150 Change-Id: Ia08a9697d0ff41721fb0acf17ccb4cfa23cb3934 Signed-off-by: Arne Schwabe Acked-by: Gert Doering Message-Id: <20240508220540.12554-1-gert@greenie.muc.de> URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg28649.html Signed-off-by: Gert Doering (cherry picked from commit b3a271b11723cbe520ad4ce6b4b0459de57ade06) --- src/openvpn/crypto_openssl.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/openvpn/crypto_openssl.c b/src/openvpn/crypto_openssl.c index a773eeae..fbc95ff7 100644 --- a/src/openvpn/crypto_openssl.c +++ b/src/openvpn/crypto_openssl.c @@ -386,7 +386,19 @@ show_available_ciphers(void) #else for (int nid = 0; nid < 10000; ++nid) { +#if defined(LIBRESSL_VERSION_NUMBER) + /* OpenBSD/LibreSSL reimplemented EVP_get_cipherbyname and broke + * calling EVP_get_cipherbynid with an invalid nid in the process + * so that it would segfault. */ + const EVP_CIPHER *cipher = NULL; + const char *name = OBJ_nid2sn(nid); + if (name) + { + cipher = EVP_get_cipherbyname(name); + } +#else /* if defined(LIBRESSL_VERSION_NUMBER) */ const EVP_CIPHER *cipher = EVP_get_cipherbynid(nid); +#endif /* We cast the const away so we can keep the function prototype * compatible with EVP_CIPHER_do_all_provided */ collect_ciphers((EVP_CIPHER *) cipher, &cipher_list); @@ -440,7 +452,19 @@ show_available_digests(void) #else for (int nid = 0; nid < 10000; ++nid) { + /* OpenBSD/LibreSSL reimplemented EVP_get_digestbyname and broke + * calling EVP_get_digestbynid with an invalid nid in the process + * so that it would segfault. */ +#ifdef LIBRESSL_VERSION_NUMBER + const EVP_MD *digest = NULL; + const char *name = OBJ_nid2sn(nid); + if (name) + { + digest = EVP_get_digestbyname(name); + } +#else /* ifdef LIBRESSL_VERSION_NUMBER */ const EVP_MD *digest = EVP_get_digestbynid(nid); +#endif if (digest) { /* We cast the const away so we can keep the function prototype @@ -448,7 +472,7 @@ show_available_digests(void) print_digest((EVP_MD *)digest, NULL); } } -#endif +#endif /* if OPENSSL_VERSION_NUMBER >= 0x30000000L */ printf("\n"); }