Blob Blame History Raw
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