From 7f171bb20e0816cd2d5af57437553f1a31a886af Mon Sep 17 00:00:00 2001
From: Jeremy Barton <jbarton@microsoft.com>
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 <openssl/provider.h>
+#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 @@
<Compile Include="$(CommonPath)\Interop\Unix\System.Security.Cryptography.Native\Interop.Hmac.cs">
<Link>Common\Interop\Unix\System.Security.Cryptography.Native\Interop.Hmac.cs</Link>
</Compile>
+ <Compile Include="$(CommonPath)\Interop\Unix\System.Security.Cryptography.Native\Interop.LegacyAlgorithms.cs">
+ <Link>Common\Interop\Unix\System.Security.Cryptography.Native\Interop.LegacyAlgorithms.cs</Link>
+ </Compile>
<Compile Include="$(CommonPath)\Interop\Unix\System.Security.Cryptography.Native\Interop.RAND.cs">
<Link>Common\Interop\Unix\System.Security.Cryptography.Native\Interop.RAND.cs</Link>
</Compile>
--
2.31.1