From a6517130770656f5a3f76a75f4a8f14c828e6525 Mon Sep 17 00:00:00 2001 From: Ondrej Holy Date: Tue, 3 Aug 2021 16:24:40 +0200 Subject: [PATCH] Load legacy provider to fix rc4 with OpenSSL 3.0 Resolves: #1988443 --- freerdp.spec | 7 ++- ...t-cleanly-when-EVP_EncryptInit_ex-fa.patch | 47 +++++++++++++++++++ ...d-legacy-provider-to-fix-rc4-with-Op.patch | 47 +++++++++++++++++++ 3 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 winpr-crypto-Exit-cleanly-when-EVP_EncryptInit_ex-fa.patch create mode 100644 winpr-crypto-Load-legacy-provider-to-fix-rc4-with-Op.patch diff --git a/freerdp.spec b/freerdp.spec index 835f397..de1d3ae 100644 --- a/freerdp.spec +++ b/freerdp.spec @@ -22,7 +22,7 @@ Name: freerdp Version: 2.4.0 -Release: 1%{?dist} +Release: 2%{?dist} Epoch: 2 Summary: Free implementation of the Remote Desktop Protocol (RDP) License: ASL 2.0 @@ -31,6 +31,8 @@ URL: http://www.freerdp.com/ Source0: https://github.com/FreeRDP/FreeRDP/archive/%{version}/FreeRDP-%{version}.tar.gz Patch0: Fix-FIPS-mode-support-and-build-with-OpenSSL-3.0.patch +Patch1: winpr-crypto-Exit-cleanly-when-EVP_EncryptInit_ex-fa.patch +Patch2: winpr-crypto-Load-legacy-provider-to-fix-rc4-with-Op.patch BuildRequires: gcc BuildRequires: gcc-c++ @@ -297,6 +299,9 @@ find %{buildroot} -name "*.a" -delete %{_libdir}/pkgconfig/winpr-tools2.pc %changelog +* Tue Aug 03 2021 Ondrej Holy - 2:2.4.0-2 +- Load legacy provider to fix rc4 with OpenSSL 3.0 (#1988443). + * Thu Jul 29 2021 Ondrej Holy - 2:2.4.0-1 - Update to 2.4.0. diff --git a/winpr-crypto-Exit-cleanly-when-EVP_EncryptInit_ex-fa.patch b/winpr-crypto-Exit-cleanly-when-EVP_EncryptInit_ex-fa.patch new file mode 100644 index 0000000..65b4fe6 --- /dev/null +++ b/winpr-crypto-Exit-cleanly-when-EVP_EncryptInit_ex-fa.patch @@ -0,0 +1,47 @@ +From a79e09d97435bfdf4fdd439d76d847ba8dcbb445 Mon Sep 17 00:00:00 2001 +From: Ondrej Holy +Date: Tue, 3 Aug 2021 08:39:21 +0200 +Subject: [PATCH] winpr/crypto: Exit cleanly when EVP_EncryptInit_ex fails + +The `EVP_EncryptInit_ex` function may fail in certain configurations. +Consequently, FreeRDP segfaults in `EVP_CIPHER_CTX_set_key_length`. +Let's handle the `EVP_EncryptInit_ex` failures and exit cleanly in +such case. +--- + winpr/libwinpr/crypto/cipher.c | 13 +++++++++++-- + 1 file changed, 11 insertions(+), 2 deletions(-) + +diff --git a/winpr/libwinpr/crypto/cipher.c b/winpr/libwinpr/crypto/cipher.c +index c47595b14..bd52cfeed 100644 +--- a/winpr/libwinpr/crypto/cipher.c ++++ b/winpr/libwinpr/crypto/cipher.c +@@ -66,7 +66,12 @@ static WINPR_RC4_CTX* winpr_RC4_New_Internal(const BYTE* key, size_t keylen, BOO + return NULL; + + EVP_CIPHER_CTX_init((EVP_CIPHER_CTX*)ctx); +- EVP_EncryptInit_ex((EVP_CIPHER_CTX*)ctx, evp, NULL, NULL, NULL); ++ if (EVP_EncryptInit_ex((EVP_CIPHER_CTX*)ctx, evp, NULL, NULL, NULL) != 1) ++ { ++ EVP_CIPHER_CTX_free ((EVP_CIPHER_CTX*)ctx); ++ return NULL; ++ } ++ + /* EVP_CIPH_FLAG_NON_FIPS_ALLOW does not exist before openssl 1.0.1 */ + #if !(OPENSSL_VERSION_NUMBER < 0x10001000L) + +@@ -75,7 +80,11 @@ static WINPR_RC4_CTX* winpr_RC4_New_Internal(const BYTE* key, size_t keylen, BOO + + #endif + EVP_CIPHER_CTX_set_key_length((EVP_CIPHER_CTX*)ctx, (int)keylen); +- EVP_EncryptInit_ex((EVP_CIPHER_CTX*)ctx, NULL, NULL, key, NULL); ++ if (EVP_EncryptInit_ex((EVP_CIPHER_CTX*)ctx, NULL, NULL, key, NULL) != 1) ++ { ++ EVP_CIPHER_CTX_free ((EVP_CIPHER_CTX*)ctx); ++ return NULL; ++ } + #elif defined(WITH_MBEDTLS) && defined(MBEDTLS_ARC4_C) + + if (!(ctx = (WINPR_RC4_CTX*)calloc(1, sizeof(mbedtls_arc4_context)))) +-- +2.31.1 + diff --git a/winpr-crypto-Load-legacy-provider-to-fix-rc4-with-Op.patch b/winpr-crypto-Load-legacy-provider-to-fix-rc4-with-Op.patch new file mode 100644 index 0000000..b221d51 --- /dev/null +++ b/winpr-crypto-Load-legacy-provider-to-fix-rc4-with-Op.patch @@ -0,0 +1,47 @@ +From e1f63dba5c63302b8a5e9d33c9ffe5580105de72 Mon Sep 17 00:00:00 2001 +From: Ondrej Holy +Date: Tue, 3 Aug 2021 08:47:13 +0200 +Subject: [PATCH] winpr/crypto: Load legacy provider to fix rc4 with OpenSSL + 3.0 + +Currently, the `EVP_EncryptInit_ex` function fails for rc4 with OpenSSL 3.0. +This is becuase rc4 is provided by the legacy provider which is not loaded +by default. Let's explicitly load the legacy provider to make FreeRDP work +with OpenSSL 3.0. + +Relates: https://github.com/openssl/openssl/issues/14392 +Fixes: https://github.com/FreeRDP/FreeRDP/issues/6604 +--- + winpr/libwinpr/crypto/cipher.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/winpr/libwinpr/crypto/cipher.c b/winpr/libwinpr/crypto/cipher.c +index bd52cfeed..75d25a1c7 100644 +--- a/winpr/libwinpr/crypto/cipher.c ++++ b/winpr/libwinpr/crypto/cipher.c +@@ -29,6 +29,9 @@ + #include + #include + #include ++#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3) ++#include ++#endif + #endif + + #ifdef WITH_MBEDTLS +@@ -57,6 +60,12 @@ static WINPR_RC4_CTX* winpr_RC4_New_Internal(const BYTE* key, size_t keylen, BOO + + if (keylen > INT_MAX) + return NULL; ++ ++#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3) ++ if (OSSL_PROVIDER_load(NULL, "legacy") == NULL) ++ return NULL; ++#endif ++ + if (!(ctx = (WINPR_RC4_CTX*)EVP_CIPHER_CTX_new())) + return NULL; + +-- +2.31.1 +