From 7f171bb20e0816cd2d5af57437553f1a31a886af Mon Sep 17 00:00:00 2001 From: Jeremy Barton Date: Thu, 15 Apr 2021 08:06:27 -0700 Subject: [PATCH 07/11] OpenSSL3: Register legacy algorithms when needed --- .../Interop.LegacyAlgorithms.cs | 31 +++++++++++++++++++ .../openssl.c | 10 ++++++ .../openssl.h | 2 ++ .../opensslshim.h | 6 ++++ .../osslcompat_30.h | 4 +++ .../Cryptography/DesImplementation.Unix.cs | 2 ++ .../Cryptography/RC2Implementation.Unix.cs | 2 ++ ...em.Security.Cryptography.Algorithms.csproj | 3 ++ 8 files changed, 60 insertions(+) create mode 100644 src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.LegacyAlgorithms.cs diff --git a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.LegacyAlgorithms.cs b/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.LegacyAlgorithms.cs new file mode 100644 index 0000000000..800b14b788 --- /dev/null +++ b/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.LegacyAlgorithms.cs @@ -0,0 +1,31 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.InteropServices; + +internal static partial class Interop +{ + internal static partial class Crypto + { + private static volatile bool s_loadedLegacy; + private static readonly object s_legacyLoadLock = new object(); + + [DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_RegisterLegacyAlgorithms")] + private static extern void CryptoNative_RegisterLegacyAlgorithms(); + + internal static void EnsureLegacyAlgorithmsRegistered() + { + if (!s_loadedLegacy) + { + lock (s_legacyLoadLock) + { + if (!s_loadedLegacy) + { + CryptoNative_RegisterLegacyAlgorithms(); + s_loadedLegacy = true; + } + } + } + } + } +} diff --git a/src/Native/Unix/System.Security.Cryptography.Native/openssl.c b/src/Native/Unix/System.Security.Cryptography.Native/openssl.c index 456741360d..6792bdb1a1 100644 --- a/src/Native/Unix/System.Security.Cryptography.Native/openssl.c +++ b/src/Native/Unix/System.Security.Cryptography.Native/openssl.c @@ -1117,6 +1117,16 @@ int64_t CryptoNative_OpenSslVersionNumber() return (int64_t)OpenSSL_version_num(); } +void CryptoNative_RegisterLegacyAlgorithms() +{ +#if NEED_OPENSSL_3_0 + if (API_EXISTS(OSSL_PROVIDER_try_load)) + { + OSSL_PROVIDER_try_load(NULL, "legacy", 1); + } +#endif +} + #ifdef NEED_OPENSSL_1_0 // Lock used to make sure EnsureopenSslInitialized itself is thread safe static pthread_mutex_t g_initLock = PTHREAD_MUTEX_INITIALIZER; diff --git a/src/Native/Unix/System.Security.Cryptography.Native/openssl.h b/src/Native/Unix/System.Security.Cryptography.Native/openssl.h index 1b4604024e..7bf0da2426 100644 --- a/src/Native/Unix/System.Security.Cryptography.Native/openssl.h +++ b/src/Native/Unix/System.Security.Cryptography.Native/openssl.h @@ -73,3 +73,5 @@ DLLEXPORT int32_t CryptoNative_LookupFriendlyNameByOid(const char* oidValue, con DLLEXPORT int32_t CryptoNative_EnsureOpenSslInitialized(void); DLLEXPORT int64_t CryptoNative_OpenSslVersionNumber(void); + +DLLEXPORT void CryptoNative_RegisterLegacyAlgorithms(void); diff --git a/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.h b/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.h index 1dc9a8c35c..957860cae4 100644 --- a/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.h +++ b/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.h @@ -41,6 +41,10 @@ #define OPENSSL_VERSION_1_1_0_RTM 0x10100000L #define OPENSSL_VERSION_1_0_2_RTM 0x10002000L +#if OPENSSL_VERSION_NUMBER >= OPENSSL_VERSION_3_0_RTM +#include +#endif + #if OPENSSL_VERSION_NUMBER >= OPENSSL_VERSION_1_1_1_RTM #define HAVE_OPENSSL_SET_CIPHERSUITES 1 #else @@ -374,6 +378,7 @@ void SSL_get0_alpn_selected(const SSL* ssl, const unsigned char** protocol, unsi RENAMED_FUNCTION(OPENSSL_sk_push, sk_push) \ RENAMED_FUNCTION(OPENSSL_sk_value, sk_value) \ FALLBACK_FUNCTION(OpenSSL_version_num) \ + LIGHTUP_FUNCTION(OSSL_PROVIDER_try_load) \ REQUIRED_FUNCTION(PEM_read_bio_PKCS7) \ REQUIRED_FUNCTION(PEM_read_bio_X509) \ REQUIRED_FUNCTION(PEM_read_bio_X509_AUX) \ @@ -778,6 +783,7 @@ FOR_ALL_OPENSSL_FUNCTIONS #define OPENSSL_sk_push OPENSSL_sk_push_ptr #define OPENSSL_sk_value OPENSSL_sk_value_ptr #define OpenSSL_version_num OpenSSL_version_num_ptr +#define OSSL_PROVIDER_try_load OSSL_PROVIDER_try_load_ptr #define PEM_read_bio_PKCS7 PEM_read_bio_PKCS7_ptr #define PEM_read_bio_X509 PEM_read_bio_X509_ptr #define PEM_read_bio_X509_AUX PEM_read_bio_X509_AUX_ptr diff --git a/src/Native/Unix/System.Security.Cryptography.Native/osslcompat_30.h b/src/Native/Unix/System.Security.Cryptography.Native/osslcompat_30.h index 0fe57c9132..b87b4e7250 100644 --- a/src/Native/Unix/System.Security.Cryptography.Native/osslcompat_30.h +++ b/src/Native/Unix/System.Security.Cryptography.Native/osslcompat_30.h @@ -12,6 +12,9 @@ #undef EVP_PKEY_CTX_set_rsa_pss_saltlen #undef EVP_PKEY_CTX_set_signature_md +typedef struct ossl_provider_st OSSL_PROVIDER; +typedef struct ossl_lib_ctx_st OSSL_LIB_CTX; + void ERR_new(void); void ERR_set_debug(const char *file, int line, const char *func); void ERR_set_error(int lib, int reason, const char *fmt, ...); @@ -20,4 +23,5 @@ int EVP_PKEY_CTX_set_rsa_oaep_md(EVP_PKEY_CTX* ctx, const EVP_MD* md); int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX* ctx, int pad_mode); int EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX* ctx, int saltlen); int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX* ctx, const EVP_MD* md); +OSSL_PROVIDER* OSSL_PROVIDER_try_load(OSSL_LIB_CTX* , const char* name, int retain_fallbacks); X509* SSL_get1_peer_certificate(const SSL* ssl); diff --git a/src/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/DesImplementation.Unix.cs b/src/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/DesImplementation.Unix.cs index 721efeec6c..0416a86577 100644 --- a/src/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/DesImplementation.Unix.cs +++ b/src/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/DesImplementation.Unix.cs @@ -31,6 +31,8 @@ partial class DesImplementation throw new NotSupportedException(); } + Interop.Crypto.EnsureLegacyAlgorithmsRegistered(); + BasicSymmetricCipher cipher = new OpenSslCipher(algorithm, cipherMode, blockSize, key, 0, iv, encrypting); return UniversalCryptoTransform.Create(paddingMode, cipher, encrypting); } diff --git a/src/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/RC2Implementation.Unix.cs b/src/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/RC2Implementation.Unix.cs index 0c06cdbcf7..93e5e9a713 100644 --- a/src/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/RC2Implementation.Unix.cs +++ b/src/System.Security.Cryptography.Algorithms/src/Internal/Cryptography/RC2Implementation.Unix.cs @@ -33,6 +33,8 @@ partial class RC2Implementation throw new NotSupportedException(); } + Interop.Crypto.EnsureLegacyAlgorithmsRegistered(); + BasicSymmetricCipher cipher = new OpenSslCipher(algorithm, cipherMode, blockSize, key, effectiveKeyLength, iv, encrypting); return UniversalCryptoTransform.Create(paddingMode, cipher, encrypting); } diff --git a/src/System.Security.Cryptography.Algorithms/src/System.Security.Cryptography.Algorithms.csproj b/src/System.Security.Cryptography.Algorithms/src/System.Security.Cryptography.Algorithms.csproj index c6e8b5b69a..cf5c6731c2 100644 --- a/src/System.Security.Cryptography.Algorithms/src/System.Security.Cryptography.Algorithms.csproj +++ b/src/System.Security.Cryptography.Algorithms/src/System.Security.Cryptography.Algorithms.csproj @@ -519,6 +519,9 @@ Common\Interop\Unix\System.Security.Cryptography.Native\Interop.Hmac.cs + + Common\Interop\Unix\System.Security.Cryptography.Native\Interop.LegacyAlgorithms.cs + Common\Interop\Unix\System.Security.Cryptography.Native\Interop.RAND.cs -- 2.31.1