Compare commits

...

10 Commits

Author SHA1 Message Date
Troy Dawson cd39cf0709 dotnet3.1 package is retired on c9s for CS-1038 2022-04-14 12:22:48 -07:00
Omair Majid a19e43c2cf Update to .NET SDK 3.1.118 and Runtime 3.1.18
Resolves: RHBZ#1961848
2021-08-27 09:21:15 -04:00
Omair Majid 983d1e4bc6 Fix building and running against OpenSSL 3 beta 2
Resolves: RHBZ#1991050
2021-08-24 11:54:01 -04:00
Omair Majid 9a758096ea Update to .NET SDK 3.1.117 and Runtime 3.1.17
Resolves: RHBZ#1961848
2021-08-12 15:43:07 -04:00
Mohan Boddu cba30c5ced Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
Related: rhbz#1991688
Signed-off-by: Mohan Boddu <mboddu@redhat.com>
2021-08-09 19:51:24 +00:00
Mohan Boddu 23429142dc Rebuilt for RHEL 9 BETA for openssl 3.0
Related: rhbz#1971065
Signed-off-by: Mohan Boddu <mboddu@redhat.com>
2021-06-16 03:24:01 +00:00
Omair Majid ba6164a282 Update to .NET SDK 3.1.116 and Runtime 3.1.16
Resolves: RHBZ#1961848
2021-06-12 18:54:27 -04:00
Omair Majid b9eb75e9ea Support building against OpenSSL 3.0
Resolves: RHBZ#1965045
2021-06-08 10:58:25 -04:00
Omair Majid c0725fa2c5 Update to .NET SDK 3.1.115 and Runtime 3.1.15
Resolves: RHBZ#1961848
2021-05-20 17:45:40 -04:00
Omair Majid 9d0e0a2877 lttng tools are not available for CI
Also add an rpmsinspect file for gating

Resolves: RHBZ#1951312
2021-04-23 16:50:00 -04:00
27 changed files with 4148 additions and 476 deletions

4
.gitignore vendored
View File

@ -13,3 +13,7 @@
/dotnet-v3.1.111-SDK.tar.gz
/dotnet-v3.1.112-SDK.tar.gz
/dotnet-v3.1.113-SDK.tar.gz
/dotnet-v3.1.115-SDK.tar.gz
/dotnet-v3.1.116-SDK.tar.gz
/dotnet-v3.1.117-SDK.tar.gz
/dotnet-v3.1.118-SDK.tar.gz

View File

@ -1,57 +0,0 @@
diff --git a/previously-built-dotnet/sdk/3.1.112/RuntimeIdentifierGraph.json b/previously-built-dotnet/sdk/3.1.112/RuntimeIdentifierGraph.json
--- a/previously-built-dotnet/sdk/3.1.112/RuntimeIdentifierGraph.json
+++ b/previously-built-dotnet/sdk/3.1.112/RuntimeIdentifierGraph.json
@@ -151,6 +151,12 @@
"rhel"
]
},
+ "centos-arm64": {
+ "#import": [
+ "centos",
+ "rhel-arm64"
+ ]
+ },
"centos-x64": {
"#import": [
"centos",
@@ -176,6 +182,13 @@
"rhel.8"
]
},
+ "centos.8-arm64": {
+ "#import": [
+ "centos.8",
+ "centos-arm64",
+ "rhel.8-arm64"
+ ]
+ },
"centos.8-x64": {
"#import": [
"centos.8",
@@ -183,6 +196,26 @@
"rhel.8-x64"
]
},
+ "centos.9": {
+ "#import": [
+ "centos",
+ "rhel.9"
+ ]
+ },
+ "centos.9-arm64": {
+ "#import": [
+ "centos.9",
+ "centos-arm64",
+ "rhel.9-arm64"
+ ]
+ },
+ "centos.9-x64": {
+ "#import": [
+ "centos.9",
+ "centos-x64",
+ "rhel.9-x64"
+ ]
+ },
"debian": {
"#import": [
"linux"

View File

@ -91,12 +91,14 @@ if [ ! -f "${unmodified_tarball_name}.tar.gz" ]; then
git checkout "${tag}"
git submodule update --init --recursive
clean_dotnet_cache
sed -i -e 's|cmakeargs -DCLR_CMAKE_USE_SYSTEM_LIBUNWIND=TRUE||' repos/coreclr.proj
sed -i -e 's|cmakeargs -DCLR_CMAKE_USE_SYSTEM_LIBUNWIND=TRUE||' repos/coreclr.common.props
mkdir -p patches/coreclr/
cp ../../build-coreclr-clang10.patch patches/coreclr/
cp ../../coreclr-libunwind-fno-common.patch patches/coreclr/
mkdir -p patches/corefx/
cp ../../corefx-42900-clang-10.patch patches/corefx/
mkdir -p patches/core-setup/
cp ../../core-setup-gcc11.patch patches/core-setup/
mkdir -p patches/aspnetcore/
cp ../../disable-aspnetcore-targetingpackoverride.patch patches/aspnetcore/
./build.sh /p:ArchiveDownloadedPackages=true /p:DownloadSourceBuildReferencePackagesTimeoutSeconds=100000 /p:DownloadSourceBuildReferencePackagesTimeoutSeconds=100000

View File

@ -1,11 +0,0 @@
diff --git a/src/settings.cmake b/src/settings.cmake
--- a/src/settings.cmake
+++ b/src/settings.cmake
@@ -218,6 +218,7 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Xlinker -Bsymbolic -Bsymbolic-functions")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--build-id=sha1")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--build-id=sha1")
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pie")
add_compile_options(-fstack-protector-strong)
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
add_compile_options(-fstack-protector)

View File

@ -1,11 +0,0 @@
diff --git a/src/debug/createdump/CMakeLists.txt b/src/debug/createdump/CMakeLists.txt
--- a/src/debug/createdump/CMakeLists.txt
+++ b/src/debug/createdump/CMakeLists.txt
@@ -21,6 +21,7 @@ include_directories(BEFORE ${VM_DIR})
add_definitions(-DPAL_STDCPP_COMPAT)
add_compile_options(-fPIE)
+add_link_options(-pie)
set(CREATEDUMP_SOURCES
createdump.cpp

View File

@ -1,124 +0,0 @@
From 66d0116c74a33e43b171f3ef5323e8a3883ceb18 Mon Sep 17 00:00:00 2001
From: Omair Majid <omajid@redhat.com>
Date: Fri, 12 Feb 2021 11:01:36 -0500
Subject: [PATCH] Add Fedora 35 RID
Fedora rawhide now uses the fedora.35-x64 RID:
$ podman run -it registry.fedoraproject.org/fedora:rawhide /bin/bash -c 'cat /etc/os-release'
NAME=Fedora
VERSION="35 (Container Image Prerelease)"
ID=fedora
VERSION_ID=35
VERSION_CODENAME=""
PLATFORM_ID="platform:f35"
PRETTY_NAME="Fedora 35 (Container Image Prerelease)"
ANSI_COLOR="0;38;2;60;110;180"
LOGO=fedora-logo-icon
CPE_NAME="cpe:/o:fedoraproject:fedora:35"
HOME_URL="https://fedoraproject.org/"
DOCUMENTATION_URL="https://docs.fedoraproject.org/en-US/fedora/rawhide/system-administrators-guide/"
SUPPORT_URL="https://fedoraproject.org/wiki/Communicating_and_getting_help"
BUG_REPORT_URL="https://bugzilla.redhat.com/"
REDHAT_BUGZILLA_PRODUCT="Fedora"
REDHAT_BUGZILLA_PRODUCT_VERSION=rawhide
REDHAT_SUPPORT_PRODUCT="Fedora"
REDHAT_SUPPORT_PRODUCT_VERSION=rawhide
PRIVACY_POLICY_URL="https://fedoraproject.org/wiki/Legal:PrivacyPolicy"
VARIANT="Container Image"
VARIANT_ID=container
This is a backport of https://github.com/dotnet/runtime/pull/48200.
---
eng/Packaging.props | 2 +-
.../runtime.compatibility.json | 32 +++++++++++++++++++
pkg/Microsoft.NETCore.Platforms/runtime.json | 17 ++++++++++
.../runtimeGroups.props | 2 +-
.../packageIndex.json | 5 +--
src/packages.builds | 3 ++
6 files changed, 57 insertions(+), 4 deletions(-)
diff --git a/pkg/Microsoft.NETCore.Platforms/runtime.compatibility.json b/pkg/Microsoft.NETCore.Platforms/runtime.compatibility.json
index 382ee4552177..bb045b0856f1 100644
--- a/pkg/Microsoft.NETCore.Platforms/runtime.compatibility.json
+++ b/pkg/Microsoft.NETCore.Platforms/runtime.compatibility.json
@@ -1102,6 +1102,38 @@
"any",
"base"
],
+ "fedora.35": [
+ "fedora.35",
+ "fedora",
+ "linux",
+ "unix",
+ "any",
+ "base"
+ ],
+ "fedora.35-arm64": [
+ "fedora.35-arm64",
+ "fedora.35",
+ "fedora-arm64",
+ "fedora",
+ "linux-arm64",
+ "linux",
+ "unix-arm64",
+ "unix",
+ "any",
+ "base"
+ ],
+ "fedora.35-x64": [
+ "fedora.35-x64",
+ "fedora.35",
+ "fedora-x64",
+ "fedora",
+ "linux-x64",
+ "linux",
+ "unix-x64",
+ "unix",
+ "any",
+ "base"
+ ],
"freebsd": [
"freebsd",
"unix",
diff --git a/pkg/Microsoft.NETCore.Platforms/runtime.json b/pkg/Microsoft.NETCore.Platforms/runtime.json
index a50be8567ce0..10b204def550 100644
--- a/pkg/Microsoft.NETCore.Platforms/runtime.json
+++ b/pkg/Microsoft.NETCore.Platforms/runtime.json
@@ -544,6 +544,23 @@
"fedora-x64"
]
},
+ "fedora.35": {
+ "#import": [
+ "fedora"
+ ]
+ },
+ "fedora.35-arm64": {
+ "#import": [
+ "fedora.35",
+ "fedora-arm64"
+ ]
+ },
+ "fedora.35-x64": {
+ "#import": [
+ "fedora.35",
+ "fedora-x64"
+ ]
+ },
"freebsd": {
"#import": [
"unix"
diff --git a/pkg/Microsoft.NETCore.Platforms/runtimeGroups.props b/pkg/Microsoft.NETCore.Platforms/runtimeGroups.props
index faa697f34e20..8b9c2e47ba2d 100644
--- a/pkg/Microsoft.NETCore.Platforms/runtimeGroups.props
+++ b/pkg/Microsoft.NETCore.Platforms/runtimeGroups.props
@@ -43,7 +43,7 @@
<RuntimeGroup Include="fedora">
<Parent>linux</Parent>
<Architectures>x64;arm64</Architectures>
- <Versions>23;24;25;26;27;28;29;30;31;32;33;34</Versions>
+ <Versions>23;24;25;26;27;28;29;30;31;32;33;34;35</Versions>
<TreatVersionsAsCompatible>false</TreatVersionsAsCompatible>
</RuntimeGroup>

View File

@ -1,220 +0,0 @@
From 99ce8c8010296b48745edcfab9ea9cb3abf50ed1 Mon Sep 17 00:00:00 2001
From: Omair Majid <omajid@redhat.com>
Date: Tue, 20 Apr 2021 11:52:13 -0400
Subject: [PATCH] Add CentOS 9 RID and make CentOS 8 arm64 as well
This is the only part of https://github.com/dotnet/runtime/pull/34088
that wasn't already backported to release/3.1.
https://www.redhat.com/en/blog/faq-centos-stream-updates says:
> There will not be a CentOS Linux 9.
>
> CentOS Stream 9 will launch in Q2 2021 as part of the RHEL 9
> development process.
The last part also means that the current parent-child relationship that
we use for RHEL->CentOS in our RID graph will flip starting in 9. I dont
see any immediate impact, so I think we can leave it alone for now.
I got a (currently internal) build of CentOS Stream 9 and
/etc/os-release looks like this:
$ cat /etc/os-release
NAME="CentOS Stream"
VERSION="9"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="9"
PLATFORM_ID="platform:el9"
PRETTY_NAME="CentOS Stream 9"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:9"
HOME_URL="https://centos.org/"
BUG_REPORT_URL="https://bugzilla.redhat.com/"
REDHAT_SUPPORT_PRODUCT="Red Hat Enterprise Linux 9"
REDHAT_SUPPORT_PRODUCT_VERSION="CentOS Stream"
---
.../runtime.compatibility.json | 72 ++++++++++++++++++-
pkg/Microsoft.NETCore.Platforms/runtime.json | 35 ++++++++-
.../runtimeGroups.props | 9 ++-
.../packageIndex.json | 3 +-
src/packages.builds | 3 +
6 files changed, 119 insertions(+), 5 deletions(-)
diff --git a/pkg/Microsoft.NETCore.Platforms/runtime.compatibility.json b/pkg/Microsoft.NETCore.Platforms/runtime.compatibility.json
index 29bd92af0b..da7345623e 100644
--- a/pkg/Microsoft.NETCore.Platforms/runtime.compatibility.json
+++ b/pkg/Microsoft.NETCore.Platforms/runtime.compatibility.json
@@ -366,6 +366,18 @@
"any",
"base"
],
+ "centos-arm64": [
+ "centos-arm64",
+ "centos",
+ "rhel-arm64",
+ "rhel",
+ "linux-arm64",
+ "linux",
+ "unix-arm64",
+ "unix",
+ "any",
+ "base"
+ ],
"centos-x64": [
"centos-x64",
"centos",
@@ -414,6 +426,22 @@
"any",
"base"
],
+ "centos.8-arm64": [
+ "centos.8-arm64",
+ "centos.8",
+ "centos-arm64",
+ "rhel.8-arm64",
+ "centos",
+ "rhel.8",
+ "rhel-arm64",
+ "rhel",
+ "linux-arm64",
+ "linux",
+ "unix-arm64",
+ "unix",
+ "any",
+ "base"
+ ],
"centos.8-x64": [
"centos.8-x64",
"centos.8",
@@ -430,6 +458,48 @@
"any",
"base"
],
+ "centos.9": [
+ "centos.9",
+ "centos",
+ "rhel.9",
+ "rhel",
+ "linux",
+ "unix",
+ "any",
+ "base"
+ ],
+ "centos.9-arm64": [
+ "centos.9-arm64",
+ "centos.9",
+ "centos-arm64",
+ "rhel.9-arm64",
+ "centos",
+ "rhel.9",
+ "rhel-arm64",
+ "rhel",
+ "linux-arm64",
+ "linux",
+ "unix-arm64",
+ "unix",
+ "any",
+ "base"
+ ],
+ "centos.9-x64": [
+ "centos.9-x64",
+ "centos.9",
+ "centos-x64",
+ "rhel.9-x64",
+ "centos",
+ "rhel.9",
+ "rhel-x64",
+ "rhel",
+ "linux-x64",
+ "linux",
+ "unix-x64",
+ "unix",
+ "any",
+ "base"
+ ],
"debian": [
"debian",
"linux",
diff --git a/pkg/Microsoft.NETCore.Platforms/runtime.json b/pkg/Microsoft.NETCore.Platforms/runtime.json
index 0bcd543a3b..608a034808 100644
--- a/pkg/Microsoft.NETCore.Platforms/runtime.json
+++ b/pkg/Microsoft.NETCore.Platforms/runtime.json
@@ -151,6 +151,12 @@
"rhel"
]
},
+ "centos-arm64": {
+ "#import": [
+ "centos",
+ "rhel-arm64"
+ ]
+ },
"centos-x64": {
"#import": [
"centos",
@@ -176,6 +182,13 @@
"rhel.8"
]
},
+ "centos.8-arm64": {
+ "#import": [
+ "centos.8",
+ "centos-arm64",
+ "rhel.8-arm64"
+ ]
+ },
"centos.8-x64": {
"#import": [
"centos.8",
@@ -183,6 +196,26 @@
"rhel.8-x64"
]
},
+ "centos.9": {
+ "#import": [
+ "centos",
+ "rhel.9"
+ ]
+ },
+ "centos.9-arm64": {
+ "#import": [
+ "centos.9",
+ "centos-arm64",
+ "rhel.9-arm64"
+ ]
+ },
+ "centos.9-x64": {
+ "#import": [
+ "centos.9",
+ "centos-x64",
+ "rhel.9-x64"
+ ]
+ },
"debian": {
"#import": [
"linux"
diff --git a/pkg/Microsoft.NETCore.Platforms/runtimeGroups.props b/pkg/Microsoft.NETCore.Platforms/runtimeGroups.props
index 52b3659651..0e8d06dddd 100644
--- a/pkg/Microsoft.NETCore.Platforms/runtimeGroups.props
+++ b/pkg/Microsoft.NETCore.Platforms/runtimeGroups.props
@@ -28,7 +28,14 @@
<RuntimeGroup Include="centos">
<Parent>rhel</Parent>
<Architectures>x64</Architectures>
- <Versions>7;8</Versions>
+ <Versions>7</Versions>
+ <ApplyVersionsToParent>true</ApplyVersionsToParent>
+ <TreatVersionsAsCompatible>false</TreatVersionsAsCompatible>
+ </RuntimeGroup>
+ <RuntimeGroup Include="centos">
+ <Parent>rhel</Parent>
+ <Architectures>x64;arm64</Architectures>
+ <Versions>8;9</Versions>
<ApplyVersionsToParent>true</ApplyVersionsToParent>
<TreatVersionsAsCompatible>false</TreatVersionsAsCompatible>
</RuntimeGroup>
--
2.30.2

View File

@ -0,0 +1,349 @@
From 2b6b45878b1be4d77eec34ab5bc80b626995a8c5 Mon Sep 17 00:00:00 2001
From: Jeremy Barton <jbarton@microsoft.com>
Date: Fri, 19 Mar 2021 15:05:41 -0700
Subject: [PATCH 01/11] Use EVP_PKEY for RSA key generation
---
.../Interop.EvpPkey.Rsa.cs | 16 ++++++++
.../Interop.Rsa.cs | 3 --
.../Security/Cryptography/RSAOpenSsl.cs | 37 ++++---------------
.../apibridge.c | 8 ++++
.../apibridge.h | 1 +
.../opensslshim.h | 23 ++++++++++++
.../pal_evp_pkey_rsa.c | 29 +++++++++++++++
.../pal_evp_pkey_rsa.h | 5 +++
.../pal_rsa.c | 5 ---
.../pal_rsa.h | 7 ----
...em.Security.Cryptography.Algorithms.csproj | 3 ++
11 files changed, 93 insertions(+), 44 deletions(-)
diff --git a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EvpPkey.Rsa.cs b/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EvpPkey.Rsa.cs
index 1f61a826a9..c28522784b 100644
--- a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EvpPkey.Rsa.cs
+++ b/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EvpPkey.Rsa.cs
@@ -10,6 +10,22 @@ internal static partial class Interop
{
internal static partial class Crypto
{
+ [DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_RsaGenerateKey")]
+ private static extern SafeEvpPKeyHandle CryptoNative_RsaGenerateKey(int keySize);
+
+ internal static SafeEvpPKeyHandle RsaGenerateKey(int keySize)
+ {
+ SafeEvpPKeyHandle pkey = CryptoNative_RsaGenerateKey(keySize);
+
+ if (pkey.IsInvalid)
+ {
+ pkey.Dispose();
+ throw CreateOpenSslCryptographicException();
+ }
+
+ return pkey;
+ }
+
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpPkeyGetRsa")]
internal static extern SafeRsaHandle EvpPkeyGetRsa(SafeEvpPKeyHandle pkey);
diff --git a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Rsa.cs b/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Rsa.cs
index a7b85ae011..a05f020ada 100644
--- a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Rsa.cs
+++ b/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Rsa.cs
@@ -89,9 +89,6 @@ internal static partial class Crypto
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_RsaSize")]
internal static extern int RsaSize(SafeRsaHandle rsa);
- [DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_RsaGenerateKeyEx")]
- internal static extern int RsaGenerateKeyEx(SafeRsaHandle rsa, int bits, SafeBignumHandle e);
-
internal static bool RsaSign(int type, ReadOnlySpan<byte> m, int m_len, Span<byte> sigret, out int siglen, SafeRsaHandle rsa) =>
RsaSign(type, ref MemoryMarshal.GetReference(m), m_len, ref MemoryMarshal.GetReference(sigret), out siglen, rsa);
diff --git a/src/Common/src/System/Security/Cryptography/RSAOpenSsl.cs b/src/Common/src/System/Security/Cryptography/RSAOpenSsl.cs
index 6741d28bba..4d4a8414b3 100644
--- a/src/Common/src/System/Security/Cryptography/RSAOpenSsl.cs
+++ b/src/Common/src/System/Security/Cryptography/RSAOpenSsl.cs
@@ -25,9 +25,6 @@ public sealed partial class RSAOpenSsl : RSA
{
private const int BitsPerByte = 8;
- // 65537 (0x10001) in big-endian form
- private static readonly byte[] s_defaultExponent = { 0x01, 0x00, 0x01 };
-
private Lazy<SafeRsaHandle> _key;
public RSAOpenSsl()
@@ -585,36 +582,18 @@ private static void CheckBoolReturn(int returnValue)
private SafeRsaHandle GenerateKey()
{
- SafeRsaHandle key = Interop.Crypto.RsaCreate();
- bool generated = false;
-
- Interop.Crypto.CheckValidOpenSslHandle(key);
-
- try
+ using (SafeEvpPKeyHandle pkey = Interop.Crypto.RsaGenerateKey(KeySize))
{
- using (SafeBignumHandle exponent = Interop.Crypto.CreateBignum(s_defaultExponent))
- {
- // The documentation for RSA_generate_key_ex does not say that it returns only
- // 0 or 1, so the call marshals it back as a full Int32 and checks for a value
- // of 1 explicitly.
- int response = Interop.Crypto.RsaGenerateKeyEx(
- key,
- KeySize,
- exponent);
-
- CheckBoolReturn(response);
- generated = true;
- }
- }
- finally
- {
- if (!generated)
+ SafeRsaHandle rsa = Interop.Crypto.EvpPkeyGetRsa(pkey);
+
+ if (rsa.IsInvalid)
{
- key.Dispose();
+ rsa.Dispose();
+ throw Interop.Crypto.CreateOpenSslCryptographicException();
}
- }
- return key;
+ return rsa;
+ }
}
protected override byte[] HashData(byte[] data, int offset, int count, HashAlgorithmName hashAlgorithm) =>
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/apibridge.c b/src/Native/Unix/System.Security.Cryptography.Native/apibridge.c
index 167de7fd8e..def7198deb 100644
--- a/src/Native/Unix/System.Security.Cryptography.Native/apibridge.c
+++ b/src/Native/Unix/System.Security.Cryptography.Native/apibridge.c
@@ -728,4 +728,12 @@ void local_SSL_CTX_set_security_level(SSL_CTX* ctx, int32_t level)
(void)ctx;
(void)level;
}
+
+int32_t local_RSA_pkey_ctx_ctrl(EVP_PKEY_CTX* ctx, int32_t optype, int32_t cmd, int32_t p1, void* p2)
+{
+ // On OpenSSL 1.0.2 there aren't two different identifiers for RSA,
+ // so just pass the request on th EVP_PKEY_CTX_ctrl with the only identifier defined.
+ return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, optype, cmd, p1, p2);
+}
+
#endif
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/apibridge.h b/src/Native/Unix/System.Security.Cryptography.Native/apibridge.h
index 5f62864b24..b58611ae73 100644
--- a/src/Native/Unix/System.Security.Cryptography.Native/apibridge.h
+++ b/src/Native/Unix/System.Security.Cryptography.Native/apibridge.h
@@ -26,6 +26,7 @@ int32_t local_RSA_meth_get_flags(const RSA_METHOD* meth);
int32_t local_RSA_set0_crt_params(RSA* rsa, BIGNUM* dmp1, BIGNUM* dmq1, BIGNUM* iqmp);
int32_t local_RSA_set0_factors(RSA* rsa, BIGNUM* p, BIGNUM* q);
int32_t local_RSA_set0_key(RSA* rsa, BIGNUM* n, BIGNUM* e, BIGNUM* d);
+int32_t local_RSA_pkey_ctx_ctrl(EVP_PKEY_CTX* ctx, int32_t optype, int32_t cmd, int32_t p1, void* p2);
int32_t local_SSL_is_init_finished(const SSL* ssl);
unsigned long local_SSL_CTX_set_options(SSL_CTX* ctx, unsigned long options);
void local_SSL_CTX_set_security_level(SSL_CTX* ctx, int32_t level);
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.h b/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.h
index ed3994926d..dff6091e9e 100644
--- a/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.h
+++ b/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.h
@@ -145,6 +145,7 @@ void RSA_get0_factors(const RSA* rsa, const BIGNUM** p, const BIGNUM** q);
void RSA_get0_key(const RSA* rsa, const BIGNUM** n, const BIGNUM** e, const BIGNUM** d);
int32_t RSA_meth_get_flags(const RSA_METHOD* meth);
const RSA_METHOD* RSA_PKCS1_OpenSSL(void);
+int32_t RSA_pkey_ctx_ctrl(EVP_PKEY_CTX* ctx, int32_t optype, int32_t cmd, int32_t p1, void* p2);
int32_t RSA_set0_crt_params(RSA* rsa, BIGNUM* dmp1, BIGNUM* dmq1, BIGNUM* iqmp);
int32_t RSA_set0_factors(RSA* rsa, BIGNUM* p, BIGNUM* q);
int32_t RSA_set0_key(RSA* rsa, BIGNUM* n, BIGNUM* e, BIGNUM* d);
@@ -170,6 +171,13 @@ const X509_ALGOR* X509_get0_tbs_sigalg(const X509* x509);
X509_PUBKEY* X509_get_X509_PUBKEY(const X509* x509);
int32_t X509_get_version(const X509* x509);
int32_t X509_up_ref(X509* x509);
+
+// Redefine EVP_PKEY_CTX_set_rsa operations to use (local_)RSA_pkey_ctx_ctrl so the path is the same
+// for 1.0-built on 1.1 as on 1.1-built on 1.1.
+#undef EVP_PKEY_CTX_set_rsa_keygen_bits
+#define EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) \
+ RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_KEYGEN, EVP_PKEY_CTRL_RSA_KEYGEN_BITS, bits, NULL)
+
#endif
#if OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_1_0_2_RTM
@@ -341,8 +349,12 @@ void SSL_get0_alpn_selected(const SSL* ssl, const unsigned char** protocol, unsi
RENAMED_FUNCTION(EVP_MD_CTX_free, EVP_MD_CTX_destroy) \
RENAMED_FUNCTION(EVP_MD_CTX_new, EVP_MD_CTX_create) \
REQUIRED_FUNCTION(EVP_MD_size) \
+ REQUIRED_FUNCTION(EVP_PKEY_CTX_ctrl) \
REQUIRED_FUNCTION(EVP_PKEY_CTX_free) \
+ REQUIRED_FUNCTION(EVP_PKEY_CTX_get0_pkey) \
REQUIRED_FUNCTION(EVP_PKEY_CTX_new) \
+ REQUIRED_FUNCTION(EVP_PKEY_CTX_new_id) \
+ REQUIRED_FUNCTION(EVP_PKEY_base_id) \
REQUIRED_FUNCTION(EVP_PKEY_derive_set_peer) \
REQUIRED_FUNCTION(EVP_PKEY_derive_init) \
REQUIRED_FUNCTION(EVP_PKEY_derive) \
@@ -350,6 +362,8 @@ void SSL_get0_alpn_selected(const SSL* ssl, const unsigned char** protocol, unsi
REQUIRED_FUNCTION(EVP_PKEY_get1_DSA) \
REQUIRED_FUNCTION(EVP_PKEY_get1_EC_KEY) \
REQUIRED_FUNCTION(EVP_PKEY_get1_RSA) \
+ REQUIRED_FUNCTION(EVP_PKEY_keygen) \
+ REQUIRED_FUNCTION(EVP_PKEY_keygen_init) \
REQUIRED_FUNCTION(EVP_PKEY_new) \
REQUIRED_FUNCTION(EVP_PKEY_set1_DSA) \
REQUIRED_FUNCTION(EVP_PKEY_set1_EC_KEY) \
@@ -432,6 +446,7 @@ void SSL_get0_alpn_selected(const SSL* ssl, const unsigned char** protocol, unsi
FALLBACK_FUNCTION(RSA_get0_key) \
FALLBACK_FUNCTION(RSA_meth_get_flags) \
REQUIRED_FUNCTION(RSA_new) \
+ FALLBACK_FUNCTION(RSA_pkey_ctx_ctrl) \
RENAMED_FUNCTION(RSA_PKCS1_OpenSSL, RSA_PKCS1_SSLeay) \
REQUIRED_FUNCTION(RSA_private_decrypt) \
REQUIRED_FUNCTION(RSA_private_encrypt) \
@@ -727,8 +742,12 @@ FOR_ALL_OPENSSL_FUNCTIONS
#define EVP_MD_CTX_free EVP_MD_CTX_free_ptr
#define EVP_MD_CTX_new EVP_MD_CTX_new_ptr
#define EVP_MD_size EVP_MD_size_ptr
+#define EVP_PKEY_CTX_ctrl EVP_PKEY_CTX_ctrl_ptr
#define EVP_PKEY_CTX_free EVP_PKEY_CTX_free_ptr
+#define EVP_PKEY_CTX_get0_pkey EVP_PKEY_CTX_get0_pkey_ptr
#define EVP_PKEY_CTX_new EVP_PKEY_CTX_new_ptr
+#define EVP_PKEY_CTX_new_id EVP_PKEY_CTX_new_id_ptr
+#define EVP_PKEY_base_id EVP_PKEY_base_id_ptr
#define EVP_PKEY_derive_set_peer EVP_PKEY_derive_set_peer_ptr
#define EVP_PKEY_derive_init EVP_PKEY_derive_init_ptr
#define EVP_PKEY_derive EVP_PKEY_derive_ptr
@@ -736,6 +755,8 @@ FOR_ALL_OPENSSL_FUNCTIONS
#define EVP_PKEY_get1_DSA EVP_PKEY_get1_DSA_ptr
#define EVP_PKEY_get1_EC_KEY EVP_PKEY_get1_EC_KEY_ptr
#define EVP_PKEY_get1_RSA EVP_PKEY_get1_RSA_ptr
+#define EVP_PKEY_keygen EVP_PKEY_keygen_ptr
+#define EVP_PKEY_keygen_init EVP_PKEY_keygen_init_ptr
#define EVP_PKEY_new EVP_PKEY_new_ptr
#define EVP_PKEY_set1_DSA EVP_PKEY_set1_DSA_ptr
#define EVP_PKEY_set1_EC_KEY EVP_PKEY_set1_EC_KEY_ptr
@@ -818,6 +839,7 @@ FOR_ALL_OPENSSL_FUNCTIONS
#define RSA_get_method RSA_get_method_ptr
#define RSA_meth_get_flags RSA_meth_get_flags_ptr
#define RSA_new RSA_new_ptr
+#define RSA_pkey_ctx_ctrl RSA_pkey_ctx_ctrl_ptr
#define RSA_PKCS1_OpenSSL RSA_PKCS1_OpenSSL_ptr
#define RSA_private_decrypt RSA_private_decrypt_ptr
#define RSA_private_encrypt RSA_private_encrypt_ptr
@@ -1026,6 +1048,7 @@ FOR_ALL_OPENSSL_FUNCTIONS
#define RSA_set0_crt_params local_RSA_set0_crt_params
#define RSA_set0_factors local_RSA_set0_factors
#define RSA_set0_key local_RSA_set0_key
+#define RSA_pkey_ctx_ctrl local_RSA_pkey_ctx_ctrl
#define SSL_CTX_set_security_level local_SSL_CTX_set_security_level
#define SSL_is_init_finished local_SSL_is_init_finished
#define X509_CRL_get0_nextUpdate local_X509_CRL_get0_nextUpdate
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey_rsa.c b/src/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey_rsa.c
index e8d961dbd2..29f9238ce9 100644
--- a/src/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey_rsa.c
+++ b/src/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey_rsa.c
@@ -4,6 +4,35 @@
#include "pal_evp_pkey_rsa.h"
+EVP_PKEY* CryptoNative_RsaGenerateKey(int keySize)
+{
+ EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
+
+ if (ctx == NULL)
+ {
+ return NULL;
+ }
+
+ EVP_PKEY* pkey = NULL;
+ EVP_PKEY* ret = NULL;
+
+ if (EVP_PKEY_keygen_init(ctx) == 1 &&
+ EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, keySize) == 1 &&
+ EVP_PKEY_keygen(ctx, &pkey) == 1)
+ {
+ ret = pkey;
+ pkey = NULL;
+ }
+
+ if (pkey != NULL)
+ {
+ EVP_PKEY_free(pkey);
+ }
+
+ EVP_PKEY_CTX_free(ctx);
+ return ret;
+}
+
RSA* CryptoNative_EvpPkeyGetRsa(EVP_PKEY* pkey)
{
return EVP_PKEY_get1_RSA(pkey);
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey_rsa.h b/src/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey_rsa.h
index d8ff369670..1fda149414 100644
--- a/src/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey_rsa.h
+++ b/src/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey_rsa.h
@@ -6,6 +6,11 @@
#include "pal_compiler.h"
#include "opensslshim.h"
+/*
+Creates an RSA key of the requested size.
+*/
+DLLEXPORT EVP_PKEY* CryptoNative_RsaGenerateKey(int32_t keySize);
+
/*
Shims the EVP_PKEY_get1_RSA method.
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/pal_rsa.c b/src/Native/Unix/System.Security.Cryptography.Native/pal_rsa.c
index f764815a04..080027de0e 100644
--- a/src/Native/Unix/System.Security.Cryptography.Native/pal_rsa.c
+++ b/src/Native/Unix/System.Security.Cryptography.Native/pal_rsa.c
@@ -143,11 +143,6 @@ int32_t CryptoNative_RsaSize(RSA* rsa)
return RSA_size(rsa);
}
-int32_t CryptoNative_RsaGenerateKeyEx(RSA* rsa, int32_t bits, BIGNUM* e)
-{
- return RSA_generate_key_ex(rsa, bits, e, NULL);
-}
-
int32_t
CryptoNative_RsaSign(int32_t type, const uint8_t* m, int32_t mlen, uint8_t* sigret, int32_t* siglen, RSA* rsa)
{
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/pal_rsa.h b/src/Native/Unix/System.Security.Cryptography.Native/pal_rsa.h
index b85fed627f..1c0bc2df47 100644
--- a/src/Native/Unix/System.Security.Cryptography.Native/pal_rsa.h
+++ b/src/Native/Unix/System.Security.Cryptography.Native/pal_rsa.h
@@ -86,13 +86,6 @@ Returns the RSA modulus size in bytes.
*/
DLLEXPORT int32_t CryptoNative_RsaSize(RSA* rsa);
-/*
-Shims the RSA_generate_key_ex method.
-
-Returns 1 upon success, otherwise 0.
-*/
-DLLEXPORT int32_t CryptoNative_RsaGenerateKeyEx(RSA* rsa, int32_t bits, BIGNUM* e);
-
/*
Shims the RSA_sign method.
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 fa63b6e2fe..6ad2b78e01 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
@@ -507,6 +507,9 @@
<Compile Include="$(CommonPath)\Interop\Unix\System.Security.Cryptography.Native\Interop.EvpPkey.Ecdh.cs">
<Link>Common\Interop\Unix\System.Security.Cryptography.Native\Interop.EvpPkey.Ecdh.cs</Link>
</Compile>
+ <Compile Include="$(CommonPath)\Interop\Unix\System.Security.Cryptography.Native\Interop.EvpPkey.Rsa.cs">
+ <Link>Common\Interop\Unix\System.Security.Cryptography.Native\Interop.EvpPkey.Rsa.cs</Link>
+ </Compile>
<Compile Include="$(CommonPath)\Interop\Unix\System.Security.Cryptography.Native\Interop.EVP.cs">
<Link>Common\Interop\Unix\System.Security.Cryptography.Native\Interop.EVP.cs</Link>
</Compile>
--
2.31.1

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,538 @@
From 7111a92546253d6fc857f7cad8b0bff425df0798 Mon Sep 17 00:00:00 2001
From: Jeremy Barton <jbarton@microsoft.com>
Date: Fri, 2 Apr 2021 09:10:08 -0700
Subject: [PATCH 03/11] Use EVP_PKEY for RSA signing operations
With this change all RSA private key operations (excluding import/export) use the EVP_PKEY APIs.
* RSAPaddingProcessor is no longer used in conjunction with the private keys, on Linux.
* The pal_rsa.c copy of HasPrivateKey has been removed.
---
.../Interop.EvpPkey.Rsa.cs | 35 ++++++
.../Interop.Rsa.cs | 20 ----
.../Security/Cryptography/RSAOpenSsl.cs | 87 ++++-----------
.../opensslshim.h | 19 +++-
.../pal_evp_pkey_rsa.c | 76 ++++++++++++-
.../pal_evp_pkey_rsa.h | 14 +++
.../pal_rsa.c | 100 ------------------
7 files changed, 156 insertions(+), 195 deletions(-)
diff --git a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EvpPkey.Rsa.cs b/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EvpPkey.Rsa.cs
index f023ced7f9..6aab764cff 100644
--- a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EvpPkey.Rsa.cs
+++ b/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EvpPkey.Rsa.cs
@@ -63,6 +63,41 @@ internal static SafeEvpPKeyHandle RsaGenerateKey(int keySize)
return written;
}
+ [DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_RsaSignHash")]
+ private static extern int CryptoNative_RsaSignHash(
+ SafeEvpPKeyHandle pkey,
+ RSASignaturePaddingMode paddingMode,
+ IntPtr digestAlgorithm,
+ ref byte hash,
+ int hashLength,
+ ref byte destination,
+ int destinationLength);
+
+ internal static int RsaSignHash(
+ SafeEvpPKeyHandle pkey,
+ RSASignaturePaddingMode paddingMode,
+ IntPtr digestAlgorithm,
+ ReadOnlySpan<byte> hash,
+ Span<byte> destination)
+ {
+ int written = CryptoNative_RsaSignHash(
+ pkey,
+ paddingMode,
+ digestAlgorithm,
+ ref MemoryMarshal.GetReference(hash),
+ hash.Length,
+ ref MemoryMarshal.GetReference(destination),
+ destination.Length);
+
+ if (written < 0)
+ {
+ Debug.Assert(written == -1);
+ throw CreateOpenSslCryptographicException();
+ }
+
+ return written;
+ }
+
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EvpPkeyGetRsa")]
internal static extern SafeRsaHandle EvpPkeyGetRsa(SafeEvpPKeyHandle pkey);
diff --git a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Rsa.cs b/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Rsa.cs
index 5ad534a8f2..b2f250ffe9 100644
--- a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Rsa.cs
+++ b/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Rsa.cs
@@ -44,19 +44,6 @@ internal static partial class Crypto
SafeRsaHandle rsa,
RsaPadding padding);
- internal static int RsaSignPrimitive(
- ReadOnlySpan<byte> from,
- Span<byte> to,
- SafeRsaHandle rsa) =>
- RsaSignPrimitive(from.Length, ref MemoryMarshal.GetReference(from), ref MemoryMarshal.GetReference(to), rsa);
-
- [DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_RsaSignPrimitive")]
- private static extern int RsaSignPrimitive(
- int flen,
- ref byte from,
- ref byte to,
- SafeRsaHandle rsa);
-
internal static int RsaVerificationPrimitive(
ReadOnlySpan<byte> from,
Span<byte> to,
@@ -73,13 +60,6 @@ internal static partial class Crypto
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_RsaSize")]
internal static extern int RsaSize(SafeRsaHandle rsa);
- internal static bool RsaSign(int type, ReadOnlySpan<byte> m, int m_len, Span<byte> sigret, out int siglen, SafeRsaHandle rsa) =>
- RsaSign(type, ref MemoryMarshal.GetReference(m), m_len, ref MemoryMarshal.GetReference(sigret), out siglen, rsa);
-
- [DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_RsaSign")]
- [return: MarshalAs(UnmanagedType.Bool)]
- private static extern bool RsaSign(int type, ref byte m, int m_len, ref byte sigret, out int siglen, SafeRsaHandle rsa);
-
internal static bool RsaVerify(int type, ReadOnlySpan<byte> m, ReadOnlySpan<byte> sigbuf, SafeRsaHandle rsa)
{
bool ret = RsaVerify(
diff --git a/src/Common/src/System/Security/Cryptography/RSAOpenSsl.cs b/src/Common/src/System/Security/Cryptography/RSAOpenSsl.cs
index 87e31b9dde..225968fc50 100644
--- a/src/Common/src/System/Security/Cryptography/RSAOpenSsl.cs
+++ b/src/Common/src/System/Security/Cryptography/RSAOpenSsl.cs
@@ -655,84 +655,33 @@ public override byte[] SignHash(byte[] hash, HashAlgorithmName hashAlgorithm, RS
{
Debug.Assert(!string.IsNullOrEmpty(hashAlgorithm.Name));
Debug.Assert(padding != null);
+ ValidatePadding(padding);
signature = null;
- // Do not factor out getting _key.Value, since the key creation should not happen on
- // invalid padding modes.
+ IntPtr digestAlgorithm = Interop.Crypto.HashAlgorithmToEvp(hashAlgorithm.Name);
+ SafeEvpPKeyHandle key = GetPKey();
+ int bytesRequired = Interop.Crypto.EvpPKeySize(key);
- if (padding.Mode == RSASignaturePaddingMode.Pkcs1)
+ if (allocateSignature)
{
- int algorithmNid = GetAlgorithmNid(hashAlgorithm);
- SafeRsaHandle rsa = GetKey();
-
- int bytesRequired = Interop.Crypto.RsaSize(rsa);
-
- if (allocateSignature)
- {
- Debug.Assert(destination.Length == 0);
- signature = new byte[bytesRequired];
- destination = signature;
- }
-
- if (destination.Length < bytesRequired)
- {
- bytesWritten = 0;
- return false;
- }
-
- if (!Interop.Crypto.RsaSign(algorithmNid, hash, hash.Length, destination, out int signatureSize, rsa))
- {
- throw Interop.Crypto.CreateOpenSslCryptographicException();
- }
-
- Debug.Assert(
- signatureSize == bytesRequired,
- $"RSA_sign reported signatureSize was {signatureSize}, when {bytesRequired} was expected");
-
- bytesWritten = signatureSize;
- return true;
+ Debug.Assert(destination.Length == 0);
+ signature = new byte[bytesRequired];
+ destination = signature;
}
- else if (padding.Mode == RSASignaturePaddingMode.Pss)
+ else if (destination.Length < bytesRequired)
{
- RsaPaddingProcessor processor = RsaPaddingProcessor.OpenProcessor(hashAlgorithm);
- SafeRsaHandle rsa = GetKey();
-
- int bytesRequired = Interop.Crypto.RsaSize(rsa);
-
- if (allocateSignature)
- {
- Debug.Assert(destination.Length == 0);
- signature = new byte[bytesRequired];
- destination = signature;
- }
-
- if (destination.Length < bytesRequired)
- {
- bytesWritten = 0;
- return false;
- }
-
- byte[] pssRented = CryptoPool.Rent(bytesRequired);
- Span<byte> pssBytes = new Span<byte>(pssRented, 0, bytesRequired);
-
- processor.EncodePss(hash, pssBytes, KeySize);
-
- int ret = Interop.Crypto.RsaSignPrimitive(pssBytes, destination, rsa);
-
- CryptoPool.Return(pssRented, bytesRequired);
-
- CheckReturn(ret);
-
- Debug.Assert(
- ret == bytesRequired,
- $"RSA_private_encrypt returned {ret} when {bytesRequired} was expected");
-
- bytesWritten = ret;
- return true;
+ bytesWritten = 0;
+ return false;
}
- throw PaddingModeNotSupported();
+ int written = Interop.Crypto.RsaSignHash(key, padding.Mode, digestAlgorithm, hash, destination);
+ Debug.Assert(written == bytesRequired);
+ bytesWritten = written;
+
+ // Until EVP_PKEY is what gets stored, free the temporary key handle.
+ key.Dispose();
+ return true;
}
public override bool VerifyHash(
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.h b/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.h
index 47cb142d25..4c15914d25 100644
--- a/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.h
+++ b/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.h
@@ -179,11 +179,15 @@ int32_t X509_up_ref(X509* x509);
#define EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) \
RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_KEYGEN, EVP_PKEY_CTRL_RSA_KEYGEN_BITS, bits, NULL)
+// EVP_PKEY_CTX_set_rsa_oaep_md doesn't call RSA_pkey_ctx_ctrl in 1.1, so don't redefine it here.
+
#undef EVP_PKEY_CTX_set_rsa_padding
#define EVP_PKEY_CTX_set_rsa_padding(ctx, pad) \
RSA_pkey_ctx_ctrl(ctx, -1, EVP_PKEY_CTRL_RSA_PADDING, pad, NULL)
-// EVP_PKEY_CTX_set_rsa_oaep_md doesn't call RSA_pkey_ctx_ctrl in 1.1, so don't redefine it here.
+#undef EVP_PKEY_CTX_set_rsa_pss_saltlen
+#define EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, len) \
+ RSA_pkey_ctx_ctrl(ctx, (EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY), EVP_PKEY_CTRL_RSA_PSS_SALTLEN, len, NULL)
#endif
@@ -209,6 +213,11 @@ void SSL_CTX_set_alpn_select_cb(SSL_CTX* ctx,
void SSL_get0_alpn_selected(const SSL* ssl, const unsigned char** protocol, unsigned int* len);
#endif
+// The value -1 has the correct meaning on 1.0.x, but the constant wasn't named.
+#ifndef RSA_PSS_SALTLEN_DIGEST
+#define RSA_PSS_SALTLEN_DIGEST -1
+#endif
+
#define API_EXISTS(fn) (fn != NULL)
// List of all functions from the libssl that are used in the System.Security.Cryptography.Native.
@@ -378,6 +387,8 @@ void SSL_get0_alpn_selected(const SSL* ssl, const unsigned char** protocol, unsi
REQUIRED_FUNCTION(EVP_PKEY_set1_DSA) \
REQUIRED_FUNCTION(EVP_PKEY_set1_EC_KEY) \
REQUIRED_FUNCTION(EVP_PKEY_set1_RSA) \
+ REQUIRED_FUNCTION(EVP_PKEY_sign) \
+ REQUIRED_FUNCTION(EVP_PKEY_sign_init) \
REQUIRED_FUNCTION(EVP_PKEY_size) \
FALLBACK_FUNCTION(EVP_PKEY_up_ref) \
REQUIRED_FUNCTION(EVP_rc2_cbc) \
@@ -459,14 +470,12 @@ void SSL_get0_alpn_selected(const SSL* ssl, const unsigned char** protocol, unsi
REQUIRED_FUNCTION(RSA_new) \
FALLBACK_FUNCTION(RSA_pkey_ctx_ctrl) \
RENAMED_FUNCTION(RSA_PKCS1_OpenSSL, RSA_PKCS1_SSLeay) \
- REQUIRED_FUNCTION(RSA_private_encrypt) \
REQUIRED_FUNCTION(RSA_public_decrypt) \
REQUIRED_FUNCTION(RSA_public_encrypt) \
FALLBACK_FUNCTION(RSA_set0_crt_params) \
FALLBACK_FUNCTION(RSA_set0_factors) \
FALLBACK_FUNCTION(RSA_set0_key) \
REQUIRED_FUNCTION(RSA_set_method) \
- REQUIRED_FUNCTION(RSA_sign) \
REQUIRED_FUNCTION(RSA_size) \
REQUIRED_FUNCTION(RSA_up_ref) \
REQUIRED_FUNCTION(RSA_verify) \
@@ -774,6 +783,8 @@ FOR_ALL_OPENSSL_FUNCTIONS
#define EVP_PKEY_set1_DSA EVP_PKEY_set1_DSA_ptr
#define EVP_PKEY_set1_EC_KEY EVP_PKEY_set1_EC_KEY_ptr
#define EVP_PKEY_set1_RSA EVP_PKEY_set1_RSA_ptr
+#define EVP_PKEY_sign_init EVP_PKEY_sign_init_ptr
+#define EVP_PKEY_sign EVP_PKEY_sign_ptr
#define EVP_PKEY_size EVP_PKEY_size_ptr
#define EVP_PKEY_up_ref EVP_PKEY_up_ref_ptr
#define EVP_rc2_cbc EVP_rc2_cbc_ptr
@@ -855,14 +866,12 @@ FOR_ALL_OPENSSL_FUNCTIONS
#define RSA_new RSA_new_ptr
#define RSA_pkey_ctx_ctrl RSA_pkey_ctx_ctrl_ptr
#define RSA_PKCS1_OpenSSL RSA_PKCS1_OpenSSL_ptr
-#define RSA_private_encrypt RSA_private_encrypt_ptr
#define RSA_public_decrypt RSA_public_decrypt_ptr
#define RSA_public_encrypt RSA_public_encrypt_ptr
#define RSA_set0_crt_params RSA_set0_crt_params_ptr
#define RSA_set0_factors RSA_set0_factors_ptr
#define RSA_set0_key RSA_set0_key_ptr
#define RSA_set_method RSA_set_method_ptr
-#define RSA_sign RSA_sign_ptr
#define RSA_size RSA_size_ptr
#define RSA_up_ref RSA_up_ref_ptr
#define RSA_verify RSA_verify_ptr
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey_rsa.c b/src/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey_rsa.c
index 6235c905db..68b6a34a5d 100644
--- a/src/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey_rsa.c
+++ b/src/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey_rsa.c
@@ -91,7 +91,6 @@ int32_t CryptoNative_RsaDecrypt(EVP_PKEY* pkey,
if (rsa == NULL || HasNoPrivateKey(rsa))
{
ERR_PUT_error(ERR_LIB_RSA, RSA_F_RSA_NULL_PRIVATE_DECRYPT, RSA_R_VALUE_MISSING, __FILE__, __LINE__);
- ret = -1;
goto done;
}
}
@@ -112,6 +111,81 @@ done:
return ret;
}
+int32_t CryptoNative_RsaSignHash(EVP_PKEY* pkey,
+ RsaPaddingMode padding,
+ const EVP_MD* digest,
+ const uint8_t* hash,
+ int32_t hashLen,
+ uint8_t* destination,
+ int32_t destinationLen)
+{
+ assert(pkey != NULL);
+ assert(destination != NULL);
+ assert(padding >= RsaPaddingPkcs1 && padding <= RsaPaddingOaepOrPss);
+ assert(digest != NULL || padding == RsaPaddingPkcs1);
+
+ EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new(pkey, NULL);
+
+ int ret = -1;
+
+ if (ctx == NULL || EVP_PKEY_sign_init(ctx) <= 0)
+ {
+ goto done;
+ }
+
+ if (padding == RsaPaddingPkcs1)
+ {
+ if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0)
+ {
+ goto done;
+ }
+ }
+ else
+ {
+ assert(padding == RsaPaddingOaepOrPss);
+
+ if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING) <= 0 ||
+ EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, RSA_PSS_SALTLEN_DIGEST) <= 0)
+ {
+ goto done;
+ }
+ }
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wcast-qual"
+ if (EVP_PKEY_CTX_set_signature_md(ctx, digest) <= 0)
+#pragma clang diagnostic pop
+ {
+ goto done;
+ }
+
+ // This check may no longer be needed on OpenSSL 3.0
+ {
+ RSA* rsa = EVP_PKEY_get0_RSA(pkey);
+
+ if (rsa == NULL || HasNoPrivateKey(rsa))
+ {
+ ERR_PUT_error(ERR_LIB_RSA, RSA_F_RSA_NULL_PRIVATE_DECRYPT, RSA_R_VALUE_MISSING, __FILE__, __LINE__);
+ goto done;
+ }
+ }
+
+ size_t written = Int32ToSizeT(destinationLen);
+
+ if (EVP_PKEY_sign(ctx, destination, &written, hash, Int32ToSizeT(hashLen)) > 0)
+ {
+ ret = SizeTToInt32(written);
+ }
+
+done:
+ if (ctx != NULL)
+ {
+ EVP_PKEY_CTX_free(ctx);
+ }
+
+ return ret;
+}
+
RSA* CryptoNative_EvpPkeyGetRsa(EVP_PKEY* pkey)
{
return EVP_PKEY_get1_RSA(pkey);
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey_rsa.h b/src/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey_rsa.h
index d220065adf..f811523f78 100644
--- a/src/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey_rsa.h
+++ b/src/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey_rsa.h
@@ -34,6 +34,20 @@ DLLEXPORT int32_t CryptoNative_RsaDecrypt(EVP_PKEY* pkey,
uint8_t* destination,
int32_t destinationLen);
+/*
+Complete the RSA signature generation for the specified hash using the provided RSA key
+(wrapped in an EVP_PKEY) and padding/digest options.
+
+Returns the number of bytes written to destination, -1 on error.
+*/
+DLLEXPORT int32_t CryptoNative_RsaSignHash(EVP_PKEY* pkey,
+ RsaPaddingMode padding,
+ const EVP_MD* digest,
+ const uint8_t* hash,
+ int32_t hashLen,
+ uint8_t* destination,
+ int32_t destinationLen);
+
/*
Shims the EVP_PKEY_get1_RSA method.
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/pal_rsa.c b/src/Native/Unix/System.Security.Cryptography.Native/pal_rsa.c
index 0c635dfca7..43268e88e1 100644
--- a/src/Native/Unix/System.Security.Cryptography.Native/pal_rsa.c
+++ b/src/Native/Unix/System.Security.Cryptography.Native/pal_rsa.c
@@ -48,60 +48,6 @@ static int GetOpenSslPadding(RsaPadding padding)
}
}
-static int HasNoPrivateKey(RSA* rsa)
-{
- if (rsa == NULL)
- return 1;
-
- // Shared pointer, don't free.
- const RSA_METHOD* meth = RSA_get_method(rsa);
-
- // The method has descibed itself as having the private key external to the structure.
- // That doesn't mean it's actually present, but we can't tell.
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wcast-qual"
- if (RSA_meth_get_flags((RSA_METHOD*)meth) & RSA_FLAG_EXT_PKEY)
-#pragma clang diagnostic pop
- {
- return 0;
- }
-
- // In the event that there's a middle-ground where we report failure when success is expected,
- // one could do something like check if the RSA_METHOD intercepts all private key operations:
- //
- // * meth->rsa_priv_enc
- // * meth->rsa_priv_dec
- // * meth->rsa_sign (in 1.0.x this is only respected if the RSA_FLAG_SIGN_VER flag is asserted)
- //
- // But, for now, leave it at the EXT_PKEY flag test.
-
- // The module is documented as accepting either d or the full set of CRT parameters (p, q, dp, dq, qInv)
- // So if we see d, we're good. Otherwise, if any of the rest are missing, we're public-only.
- const BIGNUM* d;
- RSA_get0_key(rsa, NULL, NULL, &d);
-
- if (d != NULL)
- {
- return 0;
- }
-
- const BIGNUM* p;
- const BIGNUM* q;
- const BIGNUM* dmp1;
- const BIGNUM* dmq1;
- const BIGNUM* iqmp;
-
- RSA_get0_factors(rsa, &p, &q);
- RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp);
-
- if (p == NULL || q == NULL || dmp1 == NULL || dmq1 == NULL || iqmp == NULL)
- {
- return 1;
- }
-
- return 0;
-}
-
int32_t
CryptoNative_RsaPublicEncrypt(int32_t flen, const uint8_t* from, uint8_t* to, RSA* rsa, RsaPadding padding)
{
@@ -109,17 +55,6 @@ CryptoNative_RsaPublicEncrypt(int32_t flen, const uint8_t* from, uint8_t* to, RS
return RSA_public_encrypt(flen, from, to, rsa, openSslPadding);
}
-int32_t CryptoNative_RsaSignPrimitive(int32_t flen, const uint8_t* from, uint8_t* to, RSA* rsa)
-{
- if (HasNoPrivateKey(rsa))
- {
- ERR_PUT_error(ERR_LIB_RSA, RSA_F_RSA_NULL_PRIVATE_ENCRYPT, RSA_R_VALUE_MISSING, __FILE__, __LINE__);
- return -1;
- }
-
- return RSA_private_encrypt(flen, from, to, rsa, RSA_NO_PADDING);
-}
-
int32_t CryptoNative_RsaVerificationPrimitive(int32_t flen, const uint8_t* from, uint8_t* to, RSA* rsa)
{
return RSA_public_decrypt(flen, from, to, rsa, RSA_NO_PADDING);
@@ -130,41 +65,6 @@ int32_t CryptoNative_RsaSize(RSA* rsa)
return RSA_size(rsa);
}
-int32_t
-CryptoNative_RsaSign(int32_t type, const uint8_t* m, int32_t mlen, uint8_t* sigret, int32_t* siglen, RSA* rsa)
-{
- if (siglen == NULL)
- {
- assert(false);
- return 0;
- }
-
- *siglen = 0;
-
- if (HasNoPrivateKey(rsa))
- {
- ERR_PUT_error(ERR_LIB_RSA, RSA_F_RSA_SIGN, RSA_R_VALUE_MISSING, __FILE__, __LINE__);
- return 0;
- }
-
- // Shared pointer to the metadata about the message digest algorithm
- const EVP_MD* digest = EVP_get_digestbynid(type);
-
- // If the digest itself isn't known then RSA_R_UNKNOWN_ALGORITHM_TYPE will get reported, but
- // we have to check that the digest size matches what we expect.
- if (digest != NULL && mlen != EVP_MD_size(digest))
- {
- ERR_PUT_error(ERR_LIB_RSA, RSA_F_RSA_SIGN, RSA_R_INVALID_MESSAGE_LENGTH, __FILE__, __LINE__);
- return 0;
- }
-
- unsigned int unsignedSigLen = 0;
- int32_t ret = RSA_sign(type, m, Int32ToUint32(mlen), sigret, &unsignedSigLen, rsa);
- assert(unsignedSigLen <= INT32_MAX);
- *siglen = (int32_t)unsignedSigLen;
- return ret;
-}
-
int32_t
CryptoNative_RsaVerify(int32_t type, const uint8_t* m, int32_t mlen, uint8_t* sigbuf, int32_t siglen, RSA* rsa)
{
--
2.31.1

View File

@ -0,0 +1,648 @@
From 49dc6e515d9ec0db1841e5d2d86f52916d35f667 Mon Sep 17 00:00:00 2001
From: Jeremy Barton <jbarton@microsoft.com>
Date: Mon, 5 Apr 2021 11:07:29 -0700
Subject: [PATCH 04/11] Support compiling against OpenSSL 3 headers
Building against OpenSSL 3's headers fails to compile, as X509_V_ERR_INVALID_CA has changed from 24 to 79, tripping a static assert.
* Rename the managed X509VerifyStatusCode enum to X509VerifyStatusCodeUniversal, to represent the name/values that are present in all current versions of OpenSSL (1.0.2, 1.1.1, 3.0 alpha)
* Add new enums for the name/value pairs that are unique to a given version
* Add an X509VerifyStatusCode struct that just wraps the int and is a faux-union of the various enums
* Use the OpenSSL runtime version to determine which mapping table to use (after the Universal table fails)
In addition to that, there are a few const-related changes in the 3.0 headers that are addressed.
`corefx/src/Native$ ./build_native.sh -portablebuild=false` on systems where find_package(OpenSSL) maps to 3.0 succeeds with these changes. Portable builds still fail.
Not all tests pass with OpenSSL 3.0 (alpha 13) with these changes, but it does reduce to three categories of error:
* ICryptoTransform reset/reuse tests fail (OpenSSL regression is open)
* DSA small key generation fails (OpenSSL has fixed the regression for the next alpha/beta release)
* Some OuterLoop X.509 tests are failing as positively revoked when they expect ambiguous revocation states (investigation pending)
---
.../Interop.OCSP.cs | 4 +-
.../Interop.X509.cs | 109 +++++++++++-
.../pal_evp_pkey_rsa.c | 8 +-
.../pal_x509.c | 24 ++-
.../pal_x509.h | 29 +++-
.../Pal.Unix/OpenSslX509ChainProcessor.cs | 155 ++++++++++++------
6 files changed, 266 insertions(+), 63 deletions(-)
diff --git a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OCSP.cs b/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OCSP.cs
index bcf9e2af48..8be162e284 100644
--- a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OCSP.cs
+++ b/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OCSP.cs
@@ -43,7 +43,7 @@ internal static X509VerifyStatusCode X509ChainGetCachedOcspStatus(SafeX509StoreC
{
X509VerifyStatusCode response = CryptoNative_X509ChainGetCachedOcspStatus(ctx, cachePath);
- if (response < 0)
+ if (response.Code < 0)
{
Debug.Fail($"Unexpected response from X509ChainGetCachedOcspSuccess: {response}");
throw new CryptographicException();
@@ -67,7 +67,7 @@ internal static X509VerifyStatusCode X509ChainGetCachedOcspStatus(SafeX509StoreC
{
X509VerifyStatusCode response = CryptoNative_X509ChainVerifyOcsp(ctx, req, resp, cachePath);
- if (response < 0)
+ if (response.Code < 0)
{
Debug.Fail($"Unexpected response from X509ChainGetCachedOcspSuccess: {response}");
throw new CryptographicException();
diff --git a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.X509.cs b/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.X509.cs
index 8ffc70af6a..99747c276b 100644
--- a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.X509.cs
+++ b/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.X509.cs
@@ -216,13 +216,13 @@ internal static bool X509StoreCtxRebuildChain(SafeX509StoreCtxHandle ctx)
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_X509StoreCtxSetVerifyCallback")]
internal static extern void X509StoreCtxSetVerifyCallback(SafeX509StoreCtxHandle ctx, X509StoreVerifyCallback callback);
- internal static string GetX509VerifyCertErrorString(X509VerifyStatusCode n)
+ internal static string GetX509VerifyCertErrorString(int n)
{
return Marshal.PtrToStringAnsi(X509VerifyCertErrorString(n));
}
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_X509VerifyCertErrorString")]
- private static extern IntPtr X509VerifyCertErrorString(X509VerifyStatusCode n);
+ private static extern IntPtr X509VerifyCertErrorString(int n);
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_X509CrlDestroy")]
internal static extern void X509CrlDestroy(IntPtr a);
@@ -239,11 +239,13 @@ internal static string GetX509VerifyCertErrorString(X509VerifyStatusCode n)
[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EncodeX509SubjectPublicKeyInfo")]
internal static extern int EncodeX509SubjectPublicKeyInfo(SafeX509Handle x509, byte[] buf);
- internal enum X509VerifyStatusCode : int
+ internal enum X509VerifyStatusCodeUniversal
{
X509_V_OK = 0,
+ X509_V_ERR_UNSPECIFIED = 1,
X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT = 2,
X509_V_ERR_UNABLE_TO_GET_CRL = 3,
+ X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE = 4,
X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE = 5,
X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY = 6,
X509_V_ERR_CERT_SIGNATURE_FAILURE = 7,
@@ -263,18 +265,25 @@ internal enum X509VerifyStatusCode : int
X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE = 21,
X509_V_ERR_CERT_CHAIN_TOO_LONG = 22,
X509_V_ERR_CERT_REVOKED = 23,
- X509_V_ERR_INVALID_CA = 24,
+
+ // Code 24 varies.
+
X509_V_ERR_PATH_LENGTH_EXCEEDED = 25,
X509_V_ERR_INVALID_PURPOSE = 26,
X509_V_ERR_CERT_UNTRUSTED = 27,
X509_V_ERR_CERT_REJECTED = 28,
+ X509_V_ERR_SUBJECT_ISSUER_MISMATCH = 29,
+ X509_V_ERR_AKID_SKID_MISMATCH = 30,
+ X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH = 31,
X509_V_ERR_KEYUSAGE_NO_CERTSIGN = 32,
X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER = 33,
X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION = 34,
X509_V_ERR_KEYUSAGE_NO_CRL_SIGN = 35,
X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION = 36,
X509_V_ERR_INVALID_NON_CA = 37,
+ X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED = 38,
X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE = 39,
+ X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED = 40,
X509_V_ERR_INVALID_EXTENSION = 41,
X509_V_ERR_INVALID_POLICY_EXTENSION = 42,
X509_V_ERR_NO_EXPLICIT_POLICY = 43,
@@ -289,7 +298,6 @@ internal enum X509VerifyStatusCode : int
X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX = 52,
X509_V_ERR_UNSUPPORTED_NAME_SYNTAX = 53,
X509_V_ERR_CRL_PATH_VALIDATION_ERROR = 54,
- X509_V_ERR_PATH_LOOP = 55,
X509_V_ERR_SUITE_B_INVALID_VERSION = 56,
X509_V_ERR_SUITE_B_INVALID_ALGORITHM = 57,
X509_V_ERR_SUITE_B_INVALID_CURVE = 58,
@@ -299,6 +307,41 @@ internal enum X509VerifyStatusCode : int
X509_V_ERR_HOSTNAME_MISMATCH = 62,
X509_V_ERR_EMAIL_MISMATCH = 63,
X509_V_ERR_IP_ADDRESS_MISMATCH = 64,
+ }
+ internal enum X509VerifyStatusCode102
+ {
+ X509_V_ERR_INVALID_CA = 24,
+
+ X509_V_ERR_INVALID_CALL = 65,
+ X509_V_ERR_STORE_LOOKUP = 66,
+ X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION = 67,
+ }
+
+ internal enum X509VerifyStatusCode111
+ {
+ X509_V_ERR_INVALID_CA = 24,
+
+ X509_V_ERR_DANE_NO_MATCH = 65,
+ X509_V_ERR_EE_KEY_TOO_SMALL = 66,
+ X509_V_ERR_CA_KEY_TOO_SMALL = 67,
+ X509_V_ERR_CA_MD_TOO_WEAK = 68,
+ X509_V_ERR_INVALID_CALL = 69,
+ X509_V_ERR_STORE_LOOKUP = 70,
+ X509_V_ERR_NO_VALID_SCTS = 71,
+ X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION = 72,
+ X509_V_ERR_OCSP_VERIFY_NEEDED = 73,
+ X509_V_ERR_OCSP_VERIFY_FAILED = 74,
+ X509_V_ERR_OCSP_CERT_UNKNOWN = 75,
+ X509_V_ERR_SIGNATURE_ALGORITHM_MISMATCH = 76,
+ X509_V_ERR_NO_ISSUER_PUBLIC_KEY = 77,
+ X509_V_ERR_UNSUPPORTED_SIGNATURE_ALGORITHM = 78,
+ X509_V_ERR_EC_KEY_EXPLICIT_PARAMS = 79,
+ }
+
+ internal enum X509VerifyStatusCode30
+ {
+ X509_V_ERR_NO_ISSUER_PUBLIC_KEY = 24,
+
X509_V_ERR_DANE_NO_MATCH = 65,
X509_V_ERR_EE_KEY_TOO_SMALL = 66,
X509_V_ERR_CA_KEY_TOO_SMALL = 67,
@@ -310,6 +353,62 @@ internal enum X509VerifyStatusCode : int
X509_V_ERR_OCSP_VERIFY_NEEDED = 73,
X509_V_ERR_OCSP_VERIFY_FAILED = 74,
X509_V_ERR_OCSP_CERT_UNKNOWN = 75,
+ X509_V_ERR_UNSUPPORTED_SIGNATURE_ALGORITHM = 76,
+ X509_V_ERR_SIGNATURE_ALGORITHM_MISMATCH = 77,
+ X509_V_ERR_SIGNATURE_ALGORITHM_INCONSISTENCY = 78,
+ X509_V_ERR_INVALID_CA = 79,
+ X509_V_ERR_PATHLEN_INVALID_FOR_NON_CA = 80,
+ X509_V_ERR_PATHLEN_WITHOUT_KU_KEY_CERT_SIGN = 81,
+ X509_V_ERR_KU_KEY_CERT_SIGN_INVALID_FOR_NON_CA = 82,
+ X509_V_ERR_ISSUER_NAME_EMPTY = 83,
+ X509_V_ERR_SUBJECT_NAME_EMPTY = 84,
+ X509_V_ERR_MISSING_AUTHORITY_KEY_IDENTIFIER = 85,
+ X509_V_ERR_MISSING_SUBJECT_KEY_IDENTIFIER = 86,
+ X509_V_ERR_EMPTY_SUBJECT_ALT_NAME = 87,
+ X509_V_ERR_EMPTY_SUBJECT_SAN_NOT_CRITICAL = 88,
+ X509_V_ERR_CA_BCONS_NOT_CRITICAL = 89,
+ X509_V_ERR_AUTHORITY_KEY_IDENTIFIER_CRITICAL = 90,
+ X509_V_ERR_SUBJECT_KEY_IDENTIFIER_CRITICAL = 91,
+ X509_V_ERR_CA_CERT_MISSING_KEY_USAGE = 92,
+ X509_V_ERR_EXTENSIONS_REQUIRE_VERSION_3 = 93,
+ X509_V_ERR_EC_KEY_EXPLICIT_PARAMS = 94,
+ }
+
+ internal readonly struct X509VerifyStatusCode : IEquatable<X509VerifyStatusCode>
+ {
+ internal static readonly X509VerifyStatusCode X509_V_OK = X509VerifyStatusCodeUniversal.X509_V_OK;
+
+ public int Code { get; }
+
+ internal X509VerifyStatusCode(int code)
+ {
+ Code = code;
+ }
+
+ public X509VerifyStatusCodeUniversal UniversalCode => (X509VerifyStatusCodeUniversal)Code;
+ public X509VerifyStatusCode102 Code102 => (X509VerifyStatusCode102)Code;
+ public X509VerifyStatusCode111 Code111 => (X509VerifyStatusCode111)Code;
+ public X509VerifyStatusCode30 Code30 => (X509VerifyStatusCode30)Code;
+
+ public bool Equals(X509VerifyStatusCode other) => Code == other.Code;
+
+ public override bool Equals(object obj) => obj is X509VerifyStatusCode other && Equals(other);
+
+ public override int GetHashCode() => Code.GetHashCode();
+
+ public static bool operator ==(X509VerifyStatusCode left, X509VerifyStatusCode right) => left.Equals(right);
+
+ public static bool operator !=(X509VerifyStatusCode left, X509VerifyStatusCode right) => !left.Equals(right);
+
+ public static explicit operator X509VerifyStatusCode(int code)
+ {
+ return new X509VerifyStatusCode(code);
+ }
+
+ public static implicit operator X509VerifyStatusCode(X509VerifyStatusCodeUniversal code)
+ {
+ return new X509VerifyStatusCode((int)code);
+ }
}
}
}
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey_rsa.c b/src/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey_rsa.c
index 68b6a34a5d..02b31b4737 100644
--- a/src/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey_rsa.c
+++ b/src/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey_rsa.c
@@ -6,7 +6,7 @@
#include "pal_utilities.h"
#include <assert.h>
-static int HasNoPrivateKey(RSA* rsa);
+static int HasNoPrivateKey(const RSA* rsa);
EVP_PKEY* CryptoNative_RsaGenerateKey(int keySize)
{
@@ -86,7 +86,7 @@ int32_t CryptoNative_RsaDecrypt(EVP_PKEY* pkey,
// This check may no longer be needed on OpenSSL 3.0
{
- RSA* rsa = EVP_PKEY_get0_RSA(pkey);
+ const RSA* rsa = EVP_PKEY_get0_RSA(pkey);
if (rsa == NULL || HasNoPrivateKey(rsa))
{
@@ -161,7 +161,7 @@ int32_t CryptoNative_RsaSignHash(EVP_PKEY* pkey,
// This check may no longer be needed on OpenSSL 3.0
{
- RSA* rsa = EVP_PKEY_get0_RSA(pkey);
+ const RSA* rsa = EVP_PKEY_get0_RSA(pkey);
if (rsa == NULL || HasNoPrivateKey(rsa))
{
@@ -196,7 +196,7 @@ int32_t CryptoNative_EvpPkeySetRsa(EVP_PKEY* pkey, RSA* rsa)
return EVP_PKEY_set1_RSA(pkey, rsa);
}
-static int HasNoPrivateKey(RSA* rsa)
+static int HasNoPrivateKey(const RSA* rsa)
{
if (rsa == NULL)
return 1;
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/pal_x509.c b/src/Native/Unix/System.Security.Cryptography.Native/pal_x509.c
index 5dd31d0e62..0554c8d3e8 100644
--- a/src/Native/Unix/System.Security.Cryptography.Native/pal_x509.c
+++ b/src/Native/Unix/System.Security.Cryptography.Native/pal_x509.c
@@ -33,7 +33,6 @@ c_static_assert(PAL_X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY == X509_V_ERR_U
c_static_assert(PAL_X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE == X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE);
c_static_assert(PAL_X509_V_ERR_CERT_CHAIN_TOO_LONG == X509_V_ERR_CERT_CHAIN_TOO_LONG);
c_static_assert(PAL_X509_V_ERR_CERT_REVOKED == X509_V_ERR_CERT_REVOKED);
-c_static_assert(PAL_X509_V_ERR_INVALID_CA == X509_V_ERR_INVALID_CA);
c_static_assert(PAL_X509_V_ERR_PATH_LENGTH_EXCEEDED == X509_V_ERR_PATH_LENGTH_EXCEEDED);
c_static_assert(PAL_X509_V_ERR_INVALID_PURPOSE == X509_V_ERR_INVALID_PURPOSE);
c_static_assert(PAL_X509_V_ERR_CERT_UNTRUSTED == X509_V_ERR_CERT_UNTRUSTED);
@@ -48,6 +47,26 @@ c_static_assert(PAL_X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE == X509_V_ERR_KEYUS
c_static_assert(PAL_X509_V_ERR_INVALID_EXTENSION == X509_V_ERR_INVALID_EXTENSION);
c_static_assert(PAL_X509_V_ERR_INVALID_POLICY_EXTENSION == X509_V_ERR_INVALID_POLICY_EXTENSION);
c_static_assert(PAL_X509_V_ERR_NO_EXPLICIT_POLICY == X509_V_ERR_NO_EXPLICIT_POLICY);
+c_static_assert(PAL_X509_V_ERR_DIFFERENT_CRL_SCOPE == X509_V_ERR_DIFFERENT_CRL_SCOPE);
+c_static_assert(PAL_X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE == X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE);
+c_static_assert(PAL_X509_V_ERR_UNNESTED_RESOURCE == X509_V_ERR_UNNESTED_RESOURCE);
+c_static_assert(PAL_X509_V_ERR_PERMITTED_VIOLATION == X509_V_ERR_PERMITTED_VIOLATION);
+c_static_assert(PAL_X509_V_ERR_EXCLUDED_VIOLATION == X509_V_ERR_EXCLUDED_VIOLATION);
+c_static_assert(PAL_X509_V_ERR_SUBTREE_MINMAX == X509_V_ERR_SUBTREE_MINMAX);
+c_static_assert(PAL_X509_V_ERR_APPLICATION_VERIFICATION == X509_V_ERR_APPLICATION_VERIFICATION);
+c_static_assert(PAL_X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE == X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE);
+c_static_assert(PAL_X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX == X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX);
+c_static_assert(PAL_X509_V_ERR_UNSUPPORTED_NAME_SYNTAX == X509_V_ERR_UNSUPPORTED_NAME_SYNTAX);
+c_static_assert(PAL_X509_V_ERR_CRL_PATH_VALIDATION_ERROR == X509_V_ERR_CRL_PATH_VALIDATION_ERROR);
+c_static_assert(PAL_X509_V_ERR_SUITE_B_INVALID_VERSION == X509_V_ERR_SUITE_B_INVALID_VERSION);
+c_static_assert(PAL_X509_V_ERR_SUITE_B_INVALID_ALGORITHM == X509_V_ERR_SUITE_B_INVALID_ALGORITHM);
+c_static_assert(PAL_X509_V_ERR_SUITE_B_INVALID_CURVE == X509_V_ERR_SUITE_B_INVALID_CURVE);
+c_static_assert(PAL_X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM == X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM);
+c_static_assert(PAL_X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED == X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED);
+c_static_assert(PAL_X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256 == X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256);
+c_static_assert(PAL_X509_V_ERR_HOSTNAME_MISMATCH == X509_V_ERR_HOSTNAME_MISMATCH);
+c_static_assert(PAL_X509_V_ERR_EMAIL_MISMATCH == X509_V_ERR_EMAIL_MISMATCH);
+c_static_assert(PAL_X509_V_ERR_IP_ADDRESS_MISMATCH == X509_V_ERR_IP_ADDRESS_MISMATCH);
EVP_PKEY* CryptoNative_GetX509EvpPublicKey(X509* x509)
{
@@ -1109,7 +1128,10 @@ CryptoNative_X509ChainVerifyOcsp(X509_STORE_CTX* storeCtx, OCSP_REQUEST* req, OC
if (bio != NULL)
{
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wcast-qual"
if (i2d_OCSP_RESPONSE_bio(bio, resp))
+#pragma clang diagnostic pop
{
clearErr = 0;
}
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/pal_x509.h b/src/Native/Unix/System.Security.Cryptography.Native/pal_x509.h
index 7f242b4c2e..f7114e9642 100644
--- a/src/Native/Unix/System.Security.Cryptography.Native/pal_x509.h
+++ b/src/Native/Unix/System.Security.Cryptography.Native/pal_x509.h
@@ -18,7 +18,10 @@ typedef enum {
/*
The error codes used when verifying X509 certificate chains.
-These values should be kept in sync with Interop.Crypto.X509VerifyStatusCode.
+These values should be kept in sync with Interop.Crypto.X509VerifyStatusCodeUniversal.
+
+Codes specific to specific versions of OpenSSL can also be returned,
+but are not represented in this enum due to their non-constant nature.
*/
typedef enum {
PAL_X509_V_OK = 0,
@@ -43,7 +46,9 @@ typedef enum {
PAL_X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE = 21,
PAL_X509_V_ERR_CERT_CHAIN_TOO_LONG = 22,
PAL_X509_V_ERR_CERT_REVOKED = 23,
- PAL_X509_V_ERR_INVALID_CA = 24,
+
+ // Code 24 varies
+
PAL_X509_V_ERR_PATH_LENGTH_EXCEEDED = 25,
PAL_X509_V_ERR_INVALID_PURPOSE = 26,
PAL_X509_V_ERR_CERT_UNTRUSTED = 27,
@@ -58,6 +63,26 @@ typedef enum {
PAL_X509_V_ERR_INVALID_EXTENSION = 41,
PAL_X509_V_ERR_INVALID_POLICY_EXTENSION = 42,
PAL_X509_V_ERR_NO_EXPLICIT_POLICY = 43,
+ PAL_X509_V_ERR_DIFFERENT_CRL_SCOPE = 44,
+ PAL_X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE = 45,
+ PAL_X509_V_ERR_UNNESTED_RESOURCE = 46,
+ PAL_X509_V_ERR_PERMITTED_VIOLATION = 47,
+ PAL_X509_V_ERR_EXCLUDED_VIOLATION = 48,
+ PAL_X509_V_ERR_SUBTREE_MINMAX = 49,
+ PAL_X509_V_ERR_APPLICATION_VERIFICATION = 50,
+ PAL_X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE = 51,
+ PAL_X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX = 52,
+ PAL_X509_V_ERR_UNSUPPORTED_NAME_SYNTAX = 53,
+ PAL_X509_V_ERR_CRL_PATH_VALIDATION_ERROR = 54,
+ PAL_X509_V_ERR_SUITE_B_INVALID_VERSION = 56,
+ PAL_X509_V_ERR_SUITE_B_INVALID_ALGORITHM = 57,
+ PAL_X509_V_ERR_SUITE_B_INVALID_CURVE = 58,
+ PAL_X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM = 59,
+ PAL_X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED = 60,
+ PAL_X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256 = 61,
+ PAL_X509_V_ERR_HOSTNAME_MISMATCH = 62,
+ PAL_X509_V_ERR_EMAIL_MISMATCH = 63,
+ PAL_X509_V_ERR_IP_ADDRESS_MISMATCH = 64,
} X509VerifyStatusCode;
typedef int32_t (*X509StoreVerifyCallback)(int32_t, X509_STORE_CTX*);
diff --git a/src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/OpenSslX509ChainProcessor.cs b/src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/OpenSslX509ChainProcessor.cs
index d28286f016..a7f777261e 100644
--- a/src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/OpenSslX509ChainProcessor.cs
+++ b/src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/OpenSslX509ChainProcessor.cs
@@ -13,10 +13,14 @@
using System.Security.Cryptography.X509Certificates.Asn1;
using Microsoft.Win32.SafeHandles;
+using X509VerifyStatusCodeUniversal = Interop.Crypto.X509VerifyStatusCodeUniversal;
+
namespace Internal.Cryptography.Pal
{
internal sealed class OpenSslX509ChainProcessor : IChainPal
{
+ private delegate X509ChainStatusFlags MapVersionSpecificCode(Interop.Crypto.X509VerifyStatusCode code);
+
// The average chain is 3 (End-Entity, Intermediate, Root)
// 10 is plenty big.
private const int DefaultChainCapacity = 10;
@@ -30,6 +34,8 @@ internal sealed class OpenSslX509ChainProcessor : IChainPal
private static readonly CachedDirectoryStoreProvider s_userPersonalStore =
new CachedDirectoryStoreProvider(X509Store.MyStoreName);
+ private static readonly MapVersionSpecificCode s_mapVersionSpecificCode = GetVersionLookup();
+
private SafeX509Handle _leafHandle;
private SafeX509StoreHandle _store;
private readonly SafeX509StackHandle _untrustedLookup;
@@ -156,10 +162,10 @@ internal Interop.Crypto.X509VerifyStatusCode FindFirstChain(X509Certificate2Coll
internal static bool IsCompleteChain(Interop.Crypto.X509VerifyStatusCode statusCode)
{
- switch (statusCode)
+ switch (statusCode.UniversalCode)
{
- case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
- case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
+ case X509VerifyStatusCodeUniversal.X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
+ case X509VerifyStatusCodeUniversal.X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
return false;
default:
return true;
@@ -173,7 +179,7 @@ internal static bool IsCompleteChain(Interop.Crypto.X509VerifyStatusCode statusC
SafeX509StoreCtxHandle storeCtx = _storeCtx;
Interop.Crypto.X509VerifyStatusCode statusCode =
- Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT;
+ X509VerifyStatusCodeUniversal.X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT;
while (!IsCompleteChain(statusCode))
{
@@ -426,7 +432,7 @@ private Interop.Crypto.X509VerifyStatusCode CheckOcsp()
Interop.Crypto.X509VerifyStatusCode status =
Interop.Crypto.X509ChainGetCachedOcspStatus(_storeCtx, ocspCache);
- if (status != Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_UNABLE_TO_GET_CRL)
+ if (status != X509VerifyStatusCodeUniversal.X509_V_ERR_UNABLE_TO_GET_CRL)
{
return status;
}
@@ -468,7 +474,7 @@ private Interop.Crypto.X509VerifyStatusCode CheckOcsp()
{
if (resp == null || resp.IsInvalid)
{
- return Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_UNABLE_TO_GET_CRL;
+ return X509VerifyStatusCodeUniversal.X509_V_ERR_UNABLE_TO_GET_CRL;
}
try
@@ -744,77 +750,111 @@ private static void AddUniqueStatus(IList<X509ChainStatus> list, ref X509ChainSt
private static X509ChainStatusFlags MapVerifyErrorToChainStatus(Interop.Crypto.X509VerifyStatusCode code)
{
- switch (code)
+ switch (code.UniversalCode)
{
- case Interop.Crypto.X509VerifyStatusCode.X509_V_OK:
+ case X509VerifyStatusCodeUniversal.X509_V_OK:
return X509ChainStatusFlags.NoError;
- case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_CERT_NOT_YET_VALID:
- case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_CERT_HAS_EXPIRED:
- case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
- case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
+ case X509VerifyStatusCodeUniversal.X509_V_ERR_CERT_NOT_YET_VALID:
+ case X509VerifyStatusCodeUniversal.X509_V_ERR_CERT_HAS_EXPIRED:
+ case X509VerifyStatusCodeUniversal.X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
+ case X509VerifyStatusCodeUniversal.X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
return X509ChainStatusFlags.NotTimeValid;
- case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_CERT_REVOKED:
+ case X509VerifyStatusCodeUniversal.X509_V_ERR_CERT_REVOKED:
return X509ChainStatusFlags.Revoked;
- case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
- case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_CERT_SIGNATURE_FAILURE:
+ case X509VerifyStatusCodeUniversal.X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
+ case X509VerifyStatusCodeUniversal.X509_V_ERR_CERT_SIGNATURE_FAILURE:
return X509ChainStatusFlags.NotSignatureValid;
- case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_CERT_UNTRUSTED:
- case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
- case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
+ case X509VerifyStatusCodeUniversal.X509_V_ERR_CERT_UNTRUSTED:
+ case X509VerifyStatusCodeUniversal.X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
+ case X509VerifyStatusCodeUniversal.X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
return X509ChainStatusFlags.UntrustedRoot;
- case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_CRL_HAS_EXPIRED:
+ case X509VerifyStatusCodeUniversal.X509_V_ERR_CRL_HAS_EXPIRED:
return X509ChainStatusFlags.OfflineRevocation;
- case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_CRL_NOT_YET_VALID:
- case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_CRL_SIGNATURE_FAILURE:
- case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
- case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
- case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_KEYUSAGE_NO_CRL_SIGN:
- case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
- case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_UNABLE_TO_GET_CRL:
- case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
- case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION:
+ case X509VerifyStatusCodeUniversal.X509_V_ERR_CRL_NOT_YET_VALID:
+ case X509VerifyStatusCodeUniversal.X509_V_ERR_CRL_SIGNATURE_FAILURE:
+ case X509VerifyStatusCodeUniversal.X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
+ case X509VerifyStatusCodeUniversal.X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
+ case X509VerifyStatusCodeUniversal.X509_V_ERR_KEYUSAGE_NO_CRL_SIGN:
+ case X509VerifyStatusCodeUniversal.X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
+ case X509VerifyStatusCodeUniversal.X509_V_ERR_UNABLE_TO_GET_CRL:
+ case X509VerifyStatusCodeUniversal.X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
+ case X509VerifyStatusCodeUniversal.X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION:
return X509ChainStatusFlags.RevocationStatusUnknown;
- case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_INVALID_EXTENSION:
+ case X509VerifyStatusCodeUniversal.X509_V_ERR_INVALID_EXTENSION:
return X509ChainStatusFlags.InvalidExtension;
- case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
- case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
- case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
+ case X509VerifyStatusCodeUniversal.X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
+ case X509VerifyStatusCodeUniversal.X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
+ case X509VerifyStatusCodeUniversal.X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
return X509ChainStatusFlags.PartialChain;
- case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_INVALID_PURPOSE:
+ case X509VerifyStatusCodeUniversal.X509_V_ERR_INVALID_PURPOSE:
return X509ChainStatusFlags.NotValidForUsage;
- case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_INVALID_CA:
- case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_INVALID_NON_CA:
- case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_PATH_LENGTH_EXCEEDED:
- case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_KEYUSAGE_NO_CERTSIGN:
- case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE:
+ case X509VerifyStatusCodeUniversal.X509_V_ERR_INVALID_NON_CA:
+ case X509VerifyStatusCodeUniversal.X509_V_ERR_PATH_LENGTH_EXCEEDED:
+ case X509VerifyStatusCodeUniversal.X509_V_ERR_KEYUSAGE_NO_CERTSIGN:
+ case X509VerifyStatusCodeUniversal.X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE:
return X509ChainStatusFlags.InvalidBasicConstraints;
- case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_INVALID_POLICY_EXTENSION:
- case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_NO_EXPLICIT_POLICY:
+ case X509VerifyStatusCodeUniversal.X509_V_ERR_INVALID_POLICY_EXTENSION:
+ case X509VerifyStatusCodeUniversal.X509_V_ERR_NO_EXPLICIT_POLICY:
return X509ChainStatusFlags.InvalidPolicyConstraints;
- case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_CERT_REJECTED:
+ case X509VerifyStatusCodeUniversal.X509_V_ERR_CERT_REJECTED:
return X509ChainStatusFlags.ExplicitDistrust;
- case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION:
+ case X509VerifyStatusCodeUniversal.X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION:
return X509ChainStatusFlags.HasNotSupportedCriticalExtension;
- case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_CERT_CHAIN_TOO_LONG:
+ case X509VerifyStatusCodeUniversal.X509_V_ERR_CERT_CHAIN_TOO_LONG:
throw new CryptographicException();
- case Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_OUT_OF_MEM:
+ case X509VerifyStatusCodeUniversal.X509_V_ERR_OUT_OF_MEM:
throw new OutOfMemoryException();
+ default:
+ return s_mapVersionSpecificCode(code);
+ }
+ }
+
+ private static X509ChainStatusFlags MapOpenSsl30Code(Interop.Crypto.X509VerifyStatusCode code)
+ {
+ switch (code.Code30)
+ {
+ case Interop.Crypto.X509VerifyStatusCode30.X509_V_ERR_INVALID_CA:
+ return X509ChainStatusFlags.InvalidBasicConstraints;
+ default:
+ Debug.Fail("Unrecognized X509VerifyStatusCode:" + code);
+ throw new CryptographicException();
+ }
+ }
+
+ private static X509ChainStatusFlags MapOpenSsl102Code(Interop.Crypto.X509VerifyStatusCode code)
+ {
+ switch (code.Code102)
+ {
+ case Interop.Crypto.X509VerifyStatusCode102.X509_V_ERR_INVALID_CA:
+ return X509ChainStatusFlags.InvalidBasicConstraints;
+ default:
+ Debug.Fail("Unrecognized X509VerifyStatusCode:" + code);
+ throw new CryptographicException();
+ }
+ }
+
+ private static X509ChainStatusFlags MapOpenSsl111Code(Interop.Crypto.X509VerifyStatusCode code)
+ {
+ switch (code.Code111)
+ {
+ case Interop.Crypto.X509VerifyStatusCode111.X509_V_ERR_INVALID_CA:
+ return X509ChainStatusFlags.InvalidBasicConstraints;
default:
Debug.Fail("Unrecognized X509VerifyStatusCode:" + code);
throw new CryptographicException();
@@ -969,7 +1009,7 @@ internal int VerifyCallback(int ok, IntPtr ctx)
int errorDepth = Interop.Crypto.X509StoreCtxGetErrorDepth(storeCtx);
if (AbortOnSignatureError &&
- errorCode == Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_CERT_SIGNATURE_FAILURE)
+ errorCode == X509VerifyStatusCodeUniversal.X509_V_ERR_CERT_SIGNATURE_FAILURE)
{
AbortedForSignatureError = true;
return 0;
@@ -979,9 +1019,9 @@ internal int VerifyCallback(int ok, IntPtr ctx)
// * For compatibility with Windows / .NET Framework, do not report X509_V_CRL_NOT_YET_VALID.
// * X509_V_ERR_DIFFERENT_CRL_SCOPE will result in X509_V_ERR_UNABLE_TO_GET_CRL
// which will trigger OCSP, so is ignorable.
- if (errorCode != Interop.Crypto.X509VerifyStatusCode.X509_V_OK &&
- errorCode != Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_CRL_NOT_YET_VALID &&
- errorCode != Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_DIFFERENT_CRL_SCOPE)
+ if (errorCode != X509VerifyStatusCodeUniversal.X509_V_OK &&
+ errorCode != X509VerifyStatusCodeUniversal.X509_V_ERR_CRL_NOT_YET_VALID &&
+ errorCode != X509VerifyStatusCodeUniversal.X509_V_ERR_DIFFERENT_CRL_SCOPE)
{
if (_errors == null)
{
@@ -1016,6 +1056,23 @@ internal int VerifyCallback(int ok, IntPtr ctx)
}
}
+ private static MapVersionSpecificCode GetVersionLookup()
+ {
+ // 3.0+ are M_NN_00_PP_p (Major, Minor, 0, Patch, Preview)
+ // 1.x.y are 1_XX_YY_PP_p
+ if (SafeEvpPKeyHandle.OpenSslVersion >= 0x3_00_00_00_0)
+ {
+ return MapOpenSsl30Code;
+ }
+
+ if (SafeEvpPKeyHandle.OpenSslVersion >= 0x1_01_01_00_0)
+ {
+ return MapOpenSsl111Code;
+ }
+
+ return MapOpenSsl102Code;
+ }
+
private unsafe struct ErrorCollection
{
// As of OpenSSL 1.1.1 there are 75 defined X509_V_ERR values,
@@ -1059,7 +1116,7 @@ public Enumerator GetEnumerator()
private static int FindBucket(Interop.Crypto.X509VerifyStatusCode statusCode, out int bitValue)
{
- int val = (int)statusCode;
+ int val = statusCode.Code;
int bucket;
--
2.31.1

View File

@ -0,0 +1,829 @@
From 07c2b5773e994e8922a24757605a5eff05073167 Mon Sep 17 00:00:00 2001
From: Jeremy Barton <jbarton@microsoft.com>
Date: Wed, 14 Apr 2021 16:38:19 -0700
Subject: [PATCH 05/11] Make portable builds work across OpenSSL
1.0.2/1.1.1/3.0
Overall structure of changes
* Pull compatibility headers out into separate include files, because opensslshim.h is too big.
* Use forward definition of EVP_PKEY_CTX_set_rsa_keygen_bits and friends.
* These are in a new apibridge file because they're for bridging up to 3.0, and the existing one was for 1.1(.1)
* Some constants needed for this file changed between 1.1 and 3.0, so there are a lot of asserts and redefines.
* On OpenSSL 3.0, build a legacy version of ERR_put_error since it has the easier signature to work with.
* FALLBACK_FUNCTION doesn't care which version it bound to, if it doesn't find it use a local_ function.
* Renamed NEW_REQUIRED_FUNCTION to REQUIRED_FUNCTION_110 because "new" is now "sort of old".
* There's a manual sanity test that either ERR_put_error or the three new functions that together replace it are found, so we don't end up in a state where we can't report shim-injected errors.
Portable build checker:
* Built with OpenSSL 1.0.2 headers (Ubuntu 16.04 default libssl-dev)
* Ran with 1.0.2 (Ubuntu 16.04 default libssl)
* Ran with 1.1.1 (Ubuntu 18.04 default libssl)
* Ran with 3.0 (Ubuntu 16.04 with local build of OpenSSL 3.0 alpha 13)
* Built with OpenSSL 1.1.1 headers (Ubuntu 18.04 default libssl-dev)
* Ran with 1.0.2 (Ubuntu 16.04 default libssl)
* Ran with 1.1.1 (Ubuntu 18.04 default libssl)
* Ran with 3.0 (Ubuntu 16.04 with local build of OpenSSL 3.0 alpha 13)
* Built with OpenSSL 3.0 headers (Ubuntu 16.04 with local build of OpenSSL 3.0 alpha 13 and some surgery to the extra_libs.cmake)
* Ran with 1.0.2 (Ubuntu 16.04 default libssl)
* Ran with 1.1.1 (Ubuntu 18.04 default libssl)
* Ran with 3.0 (Ubuntu 16.04 with local build of OpenSSL 3.0 alpha 13)
3.0 doesn't run error-free, but it runs with the same error rate from portable and direct builds. All verification was limited to the System.Security.Cryptography.Algorithms.Tests run, but that's generally representative of the bindings.
---
.../CMakeLists.txt | 1 +
.../apibridge_30.c | 104 +++++++++
.../apibridge_30.h | 13 ++
.../apibridge_30_rev.h | 10 +
.../openssl.c | 2 +-
.../opensslshim.c | 29 ++-
.../opensslshim.h | 204 +++++++-----------
.../osslcompat_102.h | 34 +++
.../osslcompat_111.h | 80 +++++++
.../osslcompat_30.h | 23 ++
.../pal_ssl.c | 2 +-
11 files changed, 367 insertions(+), 135 deletions(-)
create mode 100644 src/Native/Unix/System.Security.Cryptography.Native/apibridge_30.c
create mode 100644 src/Native/Unix/System.Security.Cryptography.Native/apibridge_30.h
create mode 100644 src/Native/Unix/System.Security.Cryptography.Native/apibridge_30_rev.h
create mode 100644 src/Native/Unix/System.Security.Cryptography.Native/osslcompat_102.h
create mode 100644 src/Native/Unix/System.Security.Cryptography.Native/osslcompat_111.h
create mode 100644 src/Native/Unix/System.Security.Cryptography.Native/osslcompat_30.h
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/CMakeLists.txt b/src/Native/Unix/System.Security.Cryptography.Native/CMakeLists.txt
index b2f4e33f0b..19dab3035d 100644
--- a/src/Native/Unix/System.Security.Cryptography.Native/CMakeLists.txt
+++ b/src/Native/Unix/System.Security.Cryptography.Native/CMakeLists.txt
@@ -23,6 +23,7 @@ include_directories(${OPENSSL_INCLUDE_DIR})
set(NATIVECRYPTO_SOURCES
apibridge.c
+ apibridge_30.c
openssl.c
pal_asn1.c
pal_bignum.c
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/apibridge_30.c b/src/Native/Unix/System.Security.Cryptography.Native/apibridge_30.c
new file mode 100644
index 0000000000..63b5531863
--- /dev/null
+++ b/src/Native/Unix/System.Security.Cryptography.Native/apibridge_30.c
@@ -0,0 +1,104 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+#include "opensslshim.h"
+#include "pal_crypto_types.h"
+#include "pal_types.h"
+
+#include "../Common/pal_safecrt.h"
+#include <assert.h>
+
+#if defined NEED_OPENSSL_1_0 || defined NEED_OPENSSL_1_1
+
+#include "apibridge_30.h"
+
+// 1.0 and 1.1 agree on the values of the EVP_PKEY_ values, but some of them changed in 3.0.
+// If we're running on 3.0 we already call the real methods, not these fallbacks, so we need to always use
+// the 1.0/1.1 values here.
+
+// These values are in common.
+c_static_assert(EVP_PKEY_CTRL_MD == 1);
+c_static_assert(EVP_PKEY_CTRL_RSA_KEYGEN_BITS == 0x1003);
+c_static_assert(EVP_PKEY_CTRL_RSA_OAEP_MD == 0x1009);
+c_static_assert(EVP_PKEY_CTRL_RSA_PADDING == 0x1001);
+c_static_assert(EVP_PKEY_CTRL_RSA_PSS_SALTLEN == 0x1002);
+c_static_assert(EVP_PKEY_OP_KEYGEN == (1 << 2));
+c_static_assert(EVP_PKEY_RSA == 6);
+
+#if OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_3_0_RTM
+
+c_static_assert(EVP_PKEY_OP_SIGN == (1 << 3));
+c_static_assert(EVP_PKEY_OP_VERIFY == (1 << 4));
+c_static_assert(EVP_PKEY_OP_TYPE_CRYPT == ((1 << 8) | (1 << 9)));
+c_static_assert(EVP_PKEY_OP_TYPE_SIG == 0xF8);
+
+#else
+
+#undef EVP_PKEY_OP_SIGN
+#define EVP_PKEY_OP_SIGN (1 << 3)
+#undef EVP_PKEY_OP_VERIFY
+#define EVP_PKEY_OP_VERIFY (1 << 4)
+#undef EVP_PKEY_OP_TYPE_CRYPT
+#define EVP_PKEY_OP_TYPE_CRYPT ((1 << 8) | (1 << 9))
+#undef EVP_PKEY_OP_TYPE_SIG
+#define EVP_PKEY_OP_TYPE_SIG 0xF8 // OP_SIGN | OP_VERIFY | OP_VERIFYRECOVER | OP_SIGNCTX | OP_VERIFYCTX
+
+#endif
+
+int local_EVP_PKEY_CTX_set_rsa_keygen_bits(EVP_PKEY_CTX* ctx, int bits)
+{
+ return RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_KEYGEN, EVP_PKEY_CTRL_RSA_KEYGEN_BITS, bits, NULL);
+}
+
+int local_EVP_PKEY_CTX_set_rsa_oaep_md(EVP_PKEY_CTX* ctx, const EVP_MD* md)
+{
+ // set_rsa_oaep_md doesn't route through RSA_pkey_ctx_ctrl n 1.1, unlike the other set_rsa operations.
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wcast-qual"
+ return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, EVP_PKEY_CTRL_RSA_OAEP_MD, 0, (void*)md);
+#pragma clang diagnostic pop
+}
+
+int local_EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX* ctx, int pad_mode)
+{
+ return RSA_pkey_ctx_ctrl(ctx, -1, EVP_PKEY_CTRL_RSA_PADDING, pad_mode, NULL);
+}
+
+int local_EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX* ctx, int saltlen)
+{
+ return RSA_pkey_ctx_ctrl(
+ ctx, (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY), EVP_PKEY_CTRL_RSA_PSS_SALTLEN, saltlen, NULL);
+}
+
+int local_EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX* ctx, const EVP_MD* md)
+{
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wcast-qual"
+ return EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, EVP_PKEY_CTRL_MD, 0, (void*)md);
+#pragma clang diagnostic pop
+}
+
+#endif // defined NEED_OPENSSL_1_0 || defined NEED_OPENSSL_1_1
+
+#ifdef NEED_OPENSSL_3_0
+
+#include "apibridge_30_rev.h"
+
+void local_ERR_put_error(int32_t lib, int32_t func, int32_t reason, const char* file, int32_t line)
+{
+ // In portable builds, ensure that we found the 3.0 error reporting functions.
+ // In non-portable builds, this is just assert(true), but then we call the functions,
+ // so the compiler ensures they're there anyways.
+ assert(API_EXISTS(ERR_new) && API_EXISTS(ERR_set_debug) && API_EXISTS(ERR_set_error));
+ ERR_new();
+
+ // ERR_set_debug saves only the pointer, not the value, as it expects constants.
+ // So just ignore the legacy numeric code, and use the 3.0 "Uh, I don't know"
+ // function name.
+ (void)func;
+ ERR_set_debug(file, line, "(unknown function)");
+
+ ERR_set_error(lib, reason, NULL);
+}
+
+#endif // defined NEED_OPENSSL_3_0
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/apibridge_30.h b/src/Native/Unix/System.Security.Cryptography.Native/apibridge_30.h
new file mode 100644
index 0000000000..0f28900cb7
--- /dev/null
+++ b/src/Native/Unix/System.Security.Cryptography.Native/apibridge_30.h
@@ -0,0 +1,13 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+// Functions based on OpenSSL 3.0 API, used when building against/running with older versions.
+
+#pragma once
+#include "pal_types.h"
+
+int local_EVP_PKEY_CTX_set_rsa_keygen_bits(EVP_PKEY_CTX* ctx, int bits);
+int local_EVP_PKEY_CTX_set_rsa_oaep_md(EVP_PKEY_CTX* ctx, const EVP_MD* md);
+int local_EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX* ctx, int pad_mode);
+int local_EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX* ctx, int saltlen);
+int local_EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX* ctx, const EVP_MD* md);
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/apibridge_30_rev.h b/src/Native/Unix/System.Security.Cryptography.Native/apibridge_30_rev.h
new file mode 100644
index 0000000000..657cc969d2
--- /dev/null
+++ b/src/Native/Unix/System.Security.Cryptography.Native/apibridge_30_rev.h
@@ -0,0 +1,10 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+// Functions based on OpenSSL 3.0 API, used when building against/running with older versions.
+
+#pragma once
+#include "pal_types.h"
+
+// For 3.0 to behave like previous versions.
+void local_ERR_put_error(int32_t lib, int32_t func, int32_t reason, const char* file, int32_t line);
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/openssl.c b/src/Native/Unix/System.Security.Cryptography.Native/openssl.c
index 1a9ea04839..456741360d 100644
--- a/src/Native/Unix/System.Security.Cryptography.Native/openssl.c
+++ b/src/Native/Unix/System.Security.Cryptography.Native/openssl.c
@@ -1256,7 +1256,7 @@ done:
}
#endif // NEED_OPENSSL_1_0 */
-#ifdef NEED_OPENSSL_1_1
+#if defined NEED_OPENSSL_1_1 || defined NEED_OPENSSL_3_0
// Only defined in OpenSSL 1.1.1+, has no effect on 1.1.0.
#ifndef OPENSSL_INIT_NO_ATEXIT
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.c b/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.c
index b085114a6b..edd7a6dd2d 100644
--- a/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.c
+++ b/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.c
@@ -13,7 +13,7 @@
// Define pointers to all the used OpenSSL functions
#define REQUIRED_FUNCTION(fn) __typeof(fn) fn##_ptr;
-#define NEW_REQUIRED_FUNCTION(fn) __typeof(fn) fn##_ptr;
+#define REQUIRED_FUNCTION_110(fn) __typeof(fn) fn##_ptr;
#define LIGHTUP_FUNCTION(fn) __typeof(fn) fn##_ptr;
#define FALLBACK_FUNCTION(fn) __typeof(fn) fn##_ptr;
#define RENAMED_FUNCTION(fn,oldfn) __typeof(fn) fn##_ptr;
@@ -23,7 +23,7 @@ FOR_ALL_OPENSSL_FUNCTIONS
#undef RENAMED_FUNCTION
#undef FALLBACK_FUNCTION
#undef LIGHTUP_FUNCTION
-#undef NEW_REQUIRED_FUNCTION
+#undef REQUIRED_FUNCTION_110
#undef REQUIRED_FUNCTION
// x.x.x, considering the max number of decimal digits for each component
@@ -73,7 +73,12 @@ static bool OpenLibrary()
if (libssl == NULL)
{
- // Prefer OpenSSL 1.1.x
+ // Prefer OpenSSL 3.x
+ DlOpen(MAKELIB("3"));
+ }
+
+ if (libssl == NULL)
+ {
DlOpen(MAKELIB("1.1"));
}
@@ -117,7 +122,7 @@ static void InitializeOpenSSLShim()
#define REQUIRED_FUNCTION(fn) \
if (!(fn##_ptr = (__typeof(fn))(dlsym(libssl, #fn)))) { fprintf(stderr, "Cannot get required symbol " #fn " from libssl\n"); abort(); }
-#define NEW_REQUIRED_FUNCTION(fn) \
+#define REQUIRED_FUNCTION_110(fn) \
if (!v1_0_sentinel && !(fn##_ptr = (__typeof(fn))(dlsym(libssl, #fn)))) { fprintf(stderr, "Cannot get required symbol " #fn " from libssl\n"); abort(); }
#define LIGHTUP_FUNCTION(fn) \
@@ -127,8 +132,8 @@ static void InitializeOpenSSLShim()
if (!(fn##_ptr = (__typeof(fn))(dlsym(libssl, #fn)))) { fn##_ptr = (__typeof(fn))local_##fn; }
#define RENAMED_FUNCTION(fn,oldfn) \
- if (!v1_0_sentinel && !(fn##_ptr = (__typeof(fn))(dlsym(libssl, #fn)))) { fprintf(stderr, "Cannot get required symbol " #fn " from libssl\n"); abort(); } \
- if (v1_0_sentinel && !(fn##_ptr = (__typeof(fn))(dlsym(libssl, #oldfn)))) { fprintf(stderr, "Cannot get required symbol " #oldfn " from libssl\n"); abort(); }
+ fn##_ptr = (__typeof(fn))(dlsym(libssl, #fn));\
+ if (!fn##_ptr && !(fn##_ptr = (__typeof(fn))(dlsym(libssl, #oldfn)))) { fprintf(stderr, "Cannot get required symbol " #oldfn " from libssl\n"); abort(); }
#define LEGACY_FUNCTION(fn) \
if (v1_0_sentinel && !(fn##_ptr = (__typeof(fn))(dlsym(libssl, #fn)))) { fprintf(stderr, "Cannot get required symbol " #fn " from libssl\n"); abort(); }
@@ -138,8 +143,18 @@ static void InitializeOpenSSLShim()
#undef RENAMED_FUNCTION
#undef FALLBACK_FUNCTION
#undef LIGHTUP_FUNCTION
-#undef NEW_REQUIRED_FUNCTION
+#undef REQUIRED_FUNCTION_110
#undef REQUIRED_FUNCTION
+
+ // Sanity check that we have at least one functioning way of reporting errors.
+ if (ERR_put_error_ptr == &local_ERR_put_error)
+ {
+ if (ERR_new_ptr == NULL || ERR_set_debug_ptr == NULL || ERR_set_error_ptr == NULL)
+ {
+ fprintf(stderr, "Cannot determine the error reporting routine from libssl\n");
+ abort();
+ }
+ }
}
__attribute__((destructor))
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.h b/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.h
index 4c15914d25..1dc9a8c35c 100644
--- a/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.h
+++ b/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.h
@@ -36,6 +36,7 @@
#include <openssl/x509v3.h>
#include "pal_crypto_config.h"
+#define OPENSSL_VERSION_3_0_RTM 0x30000000L
#define OPENSSL_VERSION_1_1_1_RTM 0x10101000L
#define OPENSSL_VERSION_1_1_0_RTM 0x10100000L
#define OPENSSL_VERSION_1_0_2_RTM 0x10002000L
@@ -64,6 +65,22 @@
#undef SSLv23_method
#endif
+#ifdef ERR_put_error
+#undef ERR_put_error
+void ERR_put_error(int32_t lib, int32_t func, int32_t reason, const char* file, int32_t line);
+#endif
+
+// The value -1 has the correct meaning on 1.0.x, but the constant wasn't named.
+#ifndef RSA_PSS_SALTLEN_DIGEST
+#define RSA_PSS_SALTLEN_DIGEST -1
+#endif
+
+#if defined FEATURE_DISTRO_AGNOSTIC_SSL || OPENSSL_VERSION_NUMBER >= OPENSSL_VERSION_3_0_RTM
+#include "apibridge_30_rev.h"
+#endif
+#if defined FEATURE_DISTRO_AGNOSTIC_SSL || OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_3_0_RTM
+#include "apibridge_30.h"
+#endif
#if defined FEATURE_DISTRO_AGNOSTIC_SSL || OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_1_1_0_RTM
#include "apibridge.h"
#endif
@@ -72,6 +89,7 @@
#define NEED_OPENSSL_1_0 true
#define NEED_OPENSSL_1_1 true
+#define NEED_OPENSSL_3_0 true
#if !HAVE_OPENSSL_EC2M
// In portable build, we need to support the following functions even if they were not present
@@ -93,110 +111,16 @@ int SSL_CTX_set_ciphersuites(SSL_CTX *ctx, const char *str);
const SSL_CIPHER* SSL_CIPHER_find(SSL *ssl, const unsigned char *ptr);
#endif
-#if OPENSSL_VERSION_NUMBER >= OPENSSL_VERSION_1_1_0_RTM
-typedef struct stack_st _STACK;
-int CRYPTO_add_lock(int* pointer, int amount, int type, const char* file, int line);
-int CRYPTO_num_locks(void);
-void CRYPTO_set_locking_callback(void (*func)(int mode, int type, const char* file, int line));
-void ERR_load_crypto_strings(void);
-int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX* a);
-int EVP_CIPHER_CTX_init(EVP_CIPHER_CTX* a);
-void HMAC_CTX_cleanup(HMAC_CTX* ctx);
-void HMAC_CTX_init(HMAC_CTX* ctx);
-void OPENSSL_add_all_algorithms_conf(void);
-int SSL_library_init(void);
-void SSL_load_error_strings(void);
-int SSL_state(const SSL* ssl);
-unsigned long SSLeay(void);
+#if OPENSSL_VERSION_NUMBER >= OPENSSL_VERSION_3_0_RTM
+#include "osslcompat_102.h"
+#elif OPENSSL_VERSION_NUMBER >= OPENSSL_VERSION_1_1_0_RTM
+#include "osslcompat_30.h"
+#include "osslcompat_102.h"
#else
-typedef struct ossl_init_settings_st OPENSSL_INIT_SETTINGS;
-typedef struct stack_st OPENSSL_STACK;
-
-#define OPENSSL_INIT_LOAD_CRYPTO_STRINGS 0x00000002L
-#define OPENSSL_INIT_ADD_ALL_CIPHERS 0x00000004L
-#define OPENSSL_INIT_ADD_ALL_DIGESTS 0x00000008L
-#define OPENSSL_INIT_LOAD_CONFIG 0x00000040L
-#define OPENSSL_INIT_LOAD_SSL_STRINGS 0x00200000L
-
-const BIGNUM* DSA_get0_key(const DSA* dsa, const BIGNUM** pubKey, const BIGNUM** privKey);
-void DSA_get0_pqg(const DSA* dsa, const BIGNUM** p, const BIGNUM** q, const BIGNUM** g);
-const DSA_METHOD* DSA_get_method(const DSA* dsa);
-int32_t DSA_set0_key(DSA* dsa, BIGNUM* bnY, BIGNUM* bnX);
-int32_t DSA_set0_pqg(DSA* dsa, BIGNUM* bnP, BIGNUM* bnQ, BIGNUM* bnG);
-void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX* ctx);
-EVP_CIPHER_CTX* EVP_CIPHER_CTX_new(void);
-int32_t EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX* ctx);
-void EVP_MD_CTX_free(EVP_MD_CTX* ctx);
-EVP_MD_CTX* EVP_MD_CTX_new(void);
-RSA* EVP_PKEY_get0_RSA(EVP_PKEY* pkey);
-int32_t EVP_PKEY_up_ref(EVP_PKEY* pkey);
-void HMAC_CTX_free(HMAC_CTX* ctx);
-HMAC_CTX* HMAC_CTX_new(void);
-int OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS* settings);
-void OPENSSL_sk_free(OPENSSL_STACK*);
-OPENSSL_STACK* OPENSSL_sk_new_null(void);
-int OPENSSL_sk_num(const OPENSSL_STACK*);
-void* OPENSSL_sk_pop(OPENSSL_STACK* st);
-void OPENSSL_sk_pop_free(OPENSSL_STACK* st, void (*func)(void*));
-int OPENSSL_sk_push(OPENSSL_STACK* st, const void* data);
-void* OPENSSL_sk_value(const OPENSSL_STACK*, int);
-long OpenSSL_version_num(void);
-void RSA_get0_crt_params(const RSA* rsa, const BIGNUM** dmp1, const BIGNUM** dmq1, const BIGNUM** iqmp);
-void RSA_get0_factors(const RSA* rsa, const BIGNUM** p, const BIGNUM** q);
-void RSA_get0_key(const RSA* rsa, const BIGNUM** n, const BIGNUM** e, const BIGNUM** d);
-int32_t RSA_meth_get_flags(const RSA_METHOD* meth);
-const RSA_METHOD* RSA_PKCS1_OpenSSL(void);
-int32_t RSA_pkey_ctx_ctrl(EVP_PKEY_CTX* ctx, int32_t optype, int32_t cmd, int32_t p1, void* p2);
-int32_t RSA_set0_crt_params(RSA* rsa, BIGNUM* dmp1, BIGNUM* dmq1, BIGNUM* iqmp);
-int32_t RSA_set0_factors(RSA* rsa, BIGNUM* p, BIGNUM* q);
-int32_t RSA_set0_key(RSA* rsa, BIGNUM* n, BIGNUM* e, BIGNUM* d);
-int32_t SSL_is_init_finished(SSL* ssl);
-#undef SSL_CTX_set_options
-unsigned long SSL_CTX_set_options(SSL_CTX* ctx, unsigned long options);
-void SSL_CTX_set_security_level(SSL_CTX* ctx, int32_t level);
-#undef SSL_session_reused
-int SSL_session_reused(SSL* ssl);
-const SSL_METHOD* TLS_method(void);
-const ASN1_TIME* X509_CRL_get0_nextUpdate(const X509_CRL* crl);
-int32_t X509_NAME_get0_der(X509_NAME* x509Name, const uint8_t** pder, size_t* pderlen);
-int32_t X509_PUBKEY_get0_param(
- ASN1_OBJECT** palgOid, const uint8_t** pkeyBytes, int* pkeyBytesLen, X509_ALGOR** palg, X509_PUBKEY* pubkey);
-X509* X509_STORE_CTX_get0_cert(X509_STORE_CTX* ctx);
-STACK_OF(X509)* X509_STORE_CTX_get0_chain(X509_STORE_CTX* ctx);
-STACK_OF(X509)* X509_STORE_CTX_get0_untrusted(X509_STORE_CTX* ctx);
-X509_VERIFY_PARAM* X509_STORE_get0_param(X509_STORE* ctx);
-const ASN1_TIME* X509_get0_notAfter(const X509* x509);
-const ASN1_TIME* X509_get0_notBefore(const X509* x509);
-ASN1_BIT_STRING* X509_get0_pubkey_bitstr(const X509* x509);
-const X509_ALGOR* X509_get0_tbs_sigalg(const X509* x509);
-X509_PUBKEY* X509_get_X509_PUBKEY(const X509* x509);
-int32_t X509_get_version(const X509* x509);
-int32_t X509_up_ref(X509* x509);
-
-// Redefine EVP_PKEY_CTX_set_rsa operations to use (local_)RSA_pkey_ctx_ctrl so the path is the same
-// for 1.0-built on 1.1 as on 1.1-built on 1.1.
-#undef EVP_PKEY_CTX_set_rsa_keygen_bits
-#define EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) \
- RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_KEYGEN, EVP_PKEY_CTRL_RSA_KEYGEN_BITS, bits, NULL)
-
-// EVP_PKEY_CTX_set_rsa_oaep_md doesn't call RSA_pkey_ctx_ctrl in 1.1, so don't redefine it here.
-
-#undef EVP_PKEY_CTX_set_rsa_padding
-#define EVP_PKEY_CTX_set_rsa_padding(ctx, pad) \
- RSA_pkey_ctx_ctrl(ctx, -1, EVP_PKEY_CTRL_RSA_PADDING, pad, NULL)
-
-#undef EVP_PKEY_CTX_set_rsa_pss_saltlen
-#define EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, len) \
- RSA_pkey_ctx_ctrl(ctx, (EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY), EVP_PKEY_CTRL_RSA_PSS_SALTLEN, len, NULL)
-
+#include "osslcompat_30.h"
+#include "osslcompat_111.h"
#endif
-#if OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_1_0_2_RTM
-X509_STORE* X509_STORE_CTX_get0_store(X509_STORE_CTX* ctx);
-int32_t X509_check_host(X509* x509, const char* name, size_t namelen, unsigned int flags, char** peername);
-#define X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS 4
-
-#endif
#if !HAVE_OPENSSL_ALPN
#undef HAVE_OPENSSL_ALPN
@@ -213,11 +137,6 @@ void SSL_CTX_set_alpn_select_cb(SSL_CTX* ctx,
void SSL_get0_alpn_selected(const SSL* ssl, const unsigned char** protocol, unsigned int* len);
#endif
-// The value -1 has the correct meaning on 1.0.x, but the constant wasn't named.
-#ifndef RSA_PSS_SALTLEN_DIGEST
-#define RSA_PSS_SALTLEN_DIGEST -1
-#endif
-
#define API_EXISTS(fn) (fn != NULL)
// List of all functions from the libssl that are used in the System.Security.Cryptography.Native.
@@ -326,10 +245,13 @@ void SSL_get0_alpn_selected(const SSL* ssl, const unsigned char** protocol, unsi
REQUIRED_FUNCTION(ERR_error_string_n) \
REQUIRED_FUNCTION(ERR_get_error) \
LEGACY_FUNCTION(ERR_load_crypto_strings) \
- REQUIRED_FUNCTION(ERR_put_error) \
+ LIGHTUP_FUNCTION(ERR_new) \
REQUIRED_FUNCTION(ERR_peek_error) \
REQUIRED_FUNCTION(ERR_peek_last_error) \
+ FALLBACK_FUNCTION(ERR_put_error) \
REQUIRED_FUNCTION(ERR_reason_error_string) \
+ LIGHTUP_FUNCTION(ERR_set_debug) \
+ LIGHTUP_FUNCTION(ERR_set_error) \
REQUIRED_FUNCTION(EVP_aes_128_cbc) \
REQUIRED_FUNCTION(EVP_aes_128_ccm) \
REQUIRED_FUNCTION(EVP_aes_128_ecb) \
@@ -370,6 +292,11 @@ void SSL_get0_alpn_selected(const SSL* ssl, const unsigned char** protocol, unsi
REQUIRED_FUNCTION(EVP_PKEY_CTX_get0_pkey) \
REQUIRED_FUNCTION(EVP_PKEY_CTX_new) \
REQUIRED_FUNCTION(EVP_PKEY_CTX_new_id) \
+ FALLBACK_FUNCTION(EVP_PKEY_CTX_set_rsa_keygen_bits) \
+ FALLBACK_FUNCTION(EVP_PKEY_CTX_set_rsa_oaep_md) \
+ FALLBACK_FUNCTION(EVP_PKEY_CTX_set_rsa_padding) \
+ FALLBACK_FUNCTION(EVP_PKEY_CTX_set_rsa_pss_saltlen) \
+ FALLBACK_FUNCTION(EVP_PKEY_CTX_set_signature_md) \
REQUIRED_FUNCTION(EVP_PKEY_base_id) \
REQUIRED_FUNCTION(EVP_PKEY_decrypt) \
REQUIRED_FUNCTION(EVP_PKEY_decrypt_init) \
@@ -438,7 +365,7 @@ void SSL_get0_alpn_selected(const SSL* ssl, const unsigned char** protocol, unsi
REQUIRED_FUNCTION(OCSP_RESPONSE_new) \
LEGACY_FUNCTION(OPENSSL_add_all_algorithms_conf) \
REQUIRED_FUNCTION(OPENSSL_cleanse) \
- NEW_REQUIRED_FUNCTION(OPENSSL_init_ssl) \
+ REQUIRED_FUNCTION_110(OPENSSL_init_ssl) \
RENAMED_FUNCTION(OPENSSL_sk_free, sk_free) \
RENAMED_FUNCTION(OPENSSL_sk_new_null, sk_new_null) \
RENAMED_FUNCTION(OPENSSL_sk_num, sk_num) \
@@ -510,11 +437,11 @@ void SSL_get0_alpn_selected(const SSL* ssl, const unsigned char** protocol, unsi
REQUIRED_FUNCTION(SSL_get_error) \
REQUIRED_FUNCTION(SSL_get_finished) \
REQUIRED_FUNCTION(SSL_get_peer_cert_chain) \
- REQUIRED_FUNCTION(SSL_get_peer_certificate) \
REQUIRED_FUNCTION(SSL_get_peer_finished) \
REQUIRED_FUNCTION(SSL_get_SSL_CTX) \
REQUIRED_FUNCTION(SSL_get_version) \
LIGHTUP_FUNCTION(SSL_get0_alpn_selected) \
+ RENAMED_FUNCTION(SSL_get1_peer_certificate, SSL_get_peer_certificate) \
LEGACY_FUNCTION(SSL_library_init) \
LEGACY_FUNCTION(SSL_load_error_strings) \
REQUIRED_FUNCTION(SSL_new) \
@@ -606,7 +533,7 @@ void SSL_get0_alpn_selected(const SSL* ssl, const unsigned char** protocol, unsi
// Declare pointers to all the used OpenSSL functions
#define REQUIRED_FUNCTION(fn) extern __typeof(fn)* fn##_ptr;
-#define NEW_REQUIRED_FUNCTION(fn) extern __typeof(fn)* fn##_ptr;
+#define REQUIRED_FUNCTION_110(fn) extern __typeof(fn)* fn##_ptr;
#define LIGHTUP_FUNCTION(fn) extern __typeof(fn)* fn##_ptr;
#define FALLBACK_FUNCTION(fn) extern __typeof(fn)* fn##_ptr;
#define RENAMED_FUNCTION(fn,oldfn) extern __typeof(fn)* fn##_ptr;
@@ -616,7 +543,7 @@ FOR_ALL_OPENSSL_FUNCTIONS
#undef RENAMED_FUNCTION
#undef FALLBACK_FUNCTION
#undef LIGHTUP_FUNCTION
-#undef NEW_REQUIRED_FUNCTION
+#undef REQUIRED_FUNCTION_110
#undef REQUIRED_FUNCTION
// Redefine all calls to OpenSSL functions as calls through pointers that are set
@@ -722,10 +649,13 @@ FOR_ALL_OPENSSL_FUNCTIONS
#define ERR_error_string_n ERR_error_string_n_ptr
#define ERR_get_error ERR_get_error_ptr
#define ERR_load_crypto_strings ERR_load_crypto_strings_ptr
+#define ERR_new ERR_new_ptr
#define ERR_peek_error ERR_peek_error_ptr
#define ERR_peek_last_error ERR_peek_last_error_ptr
#define ERR_put_error ERR_put_error_ptr
#define ERR_reason_error_string ERR_reason_error_string_ptr
+#define ERR_set_debug ERR_set_debug_ptr
+#define ERR_set_error ERR_set_error_ptr
#define EVP_aes_128_cbc EVP_aes_128_cbc_ptr
#define EVP_aes_128_ecb EVP_aes_128_ecb_ptr
#define EVP_aes_128_gcm EVP_aes_128_gcm_ptr
@@ -766,6 +696,11 @@ FOR_ALL_OPENSSL_FUNCTIONS
#define EVP_PKEY_CTX_get0_pkey EVP_PKEY_CTX_get0_pkey_ptr
#define EVP_PKEY_CTX_new EVP_PKEY_CTX_new_ptr
#define EVP_PKEY_CTX_new_id EVP_PKEY_CTX_new_id_ptr
+#define EVP_PKEY_CTX_set_rsa_keygen_bits EVP_PKEY_CTX_set_rsa_keygen_bits_ptr
+#define EVP_PKEY_CTX_set_rsa_oaep_md EVP_PKEY_CTX_set_rsa_oaep_md_ptr
+#define EVP_PKEY_CTX_set_rsa_padding EVP_PKEY_CTX_set_rsa_padding_ptr
+#define EVP_PKEY_CTX_set_rsa_pss_saltlen EVP_PKEY_CTX_set_rsa_pss_saltlen_ptr
+#define EVP_PKEY_CTX_set_signature_md EVP_PKEY_CTX_set_signature_md_ptr
#define EVP_PKEY_base_id EVP_PKEY_base_id_ptr
#define EVP_PKEY_decrypt_init EVP_PKEY_decrypt_init_ptr
#define EVP_PKEY_decrypt EVP_PKEY_decrypt_ptr
@@ -875,13 +810,6 @@ FOR_ALL_OPENSSL_FUNCTIONS
#define RSA_size RSA_size_ptr
#define RSA_up_ref RSA_up_ref_ptr
#define RSA_verify RSA_verify_ptr
-#define sk_free OPENSSL_sk_free_ptr
-#define sk_new_null OPENSSL_sk_new_null_ptr
-#define sk_num OPENSSL_sk_num_ptr
-#define sk_pop OPENSSL_sk_pop_ptr
-#define sk_pop_free OPENSSL_sk_pop_free_ptr
-#define sk_push OPENSSL_sk_push_ptr
-#define sk_value OPENSSL_sk_value_ptr
#define SSL_CIPHER_get_bits SSL_CIPHER_get_bits_ptr
#define SSL_CIPHER_find SSL_CIPHER_find_ptr
#define SSL_CIPHER_get_id SSL_CIPHER_get_id_ptr
@@ -912,11 +840,11 @@ FOR_ALL_OPENSSL_FUNCTIONS
#define SSL_get_error SSL_get_error_ptr
#define SSL_get_finished SSL_get_finished_ptr
#define SSL_get_peer_cert_chain SSL_get_peer_cert_chain_ptr
-#define SSL_get_peer_certificate SSL_get_peer_certificate_ptr
#define SSL_get_peer_finished SSL_get_peer_finished_ptr
#define SSL_get_SSL_CTX SSL_get_SSL_CTX_ptr
#define SSL_get_version SSL_get_version_ptr
#define SSL_get0_alpn_selected SSL_get0_alpn_selected_ptr
+#define SSL_get1_peer_certificate SSL_get1_peer_certificate_ptr
#define SSL_is_init_finished SSL_is_init_finished_ptr
#define SSL_library_init SSL_library_init_ptr
#define SSL_load_error_strings SSL_load_error_strings_ptr
@@ -1011,7 +939,7 @@ FOR_ALL_OPENSSL_FUNCTIONS
// STACK_OF types will have been declared with inline functions to handle the pointer casting.
// Since these inline functions are strongly bound to the OPENSSL_sk_* functions in 1.1 we need to
// rebind things here.
-#if OPENSSL_VERSION_NUMBER >= OPENSSL_VERSION_1_1_0_RTM
+#if OPENSSL_VERSION_NUMBER >= OPENSSL_VERSION_1_1_0_RTM && OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_3_0_RTM
// type-safe OPENSSL_sk_free
#define sk_GENERAL_NAME_free(stack) OPENSSL_sk_free((OPENSSL_STACK*)(1 ? stack : (STACK_OF(GENERAL_NAME)*)0))
#define sk_X509_free(stack) OPENSSL_sk_free((OPENSSL_STACK*)(1 ? stack : (STACK_OF(X509)*)0))
@@ -1039,6 +967,17 @@ FOR_ALL_OPENSSL_FUNCTIONS
#define sk_GENERAL_NAME_value(stack, idx) (GENERAL_NAME*)OPENSSL_sk_value((const OPENSSL_STACK*)(1 ? stack : (const STACK_OF(GENERAL_NAME)*)0), idx)
#define sk_X509_NAME_value(stack, idx) (X509_NAME*)OPENSSL_sk_value((const OPENSSL_STACK*)(1 ? stack : (const STACK_OF(X509_NAME)*)0), idx)
#define sk_X509_value(stack, idx) (X509*)OPENSSL_sk_value((const OPENSSL_STACK*)(1 ? stack : (const STACK_OF(X509)*)0), idx)
+
+#elif OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_1_1_0_RTM
+
+#define sk_free OPENSSL_sk_free_ptr
+#define sk_new_null OPENSSL_sk_new_null_ptr
+#define sk_num OPENSSL_sk_num_ptr
+#define sk_pop OPENSSL_sk_pop_ptr
+#define sk_pop_free OPENSSL_sk_pop_free_ptr
+#define sk_push OPENSSL_sk_push_ptr
+#define sk_value OPENSSL_sk_value_ptr
+
#endif
@@ -1046,9 +985,26 @@ FOR_ALL_OPENSSL_FUNCTIONS
#define API_EXISTS(fn) true
-#if OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_1_1_0_RTM
-
+#if OPENSSL_VERSION_NUMBER >= OPENSSL_VERSION_3_0_RTM
+#define NEED_OPENSSL_3_0 true
+#elif OPENSSL_VERSION_NUMBER >= OPENSSL_VERSION_1_1_0_RTM
+#define NEED_OPENSSL_1_1 true
+#else
#define NEED_OPENSSL_1_0 true
+#endif
+
+#if OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_3_0_RTM
+
+// Undo renames for renamed-in-3.0
+#define SSL_get1_peer_certificate SSL_get_peer_certificate
+
+#endif
+
+#if OPENSSL_VERSION_NUMBER >= OPENSSL_VERSION_3_0_RTM
+
+#define ERR_put_error local_ERR_put_error
+
+#elif OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_1_1_0_RTM
// Alias "future" API to the local_ version.
#define DSA_get0_key local_DSA_get0_key
@@ -1110,10 +1066,6 @@ FOR_ALL_OPENSSL_FUNCTIONS
#define OPENSSL_sk_value sk_value
#define TLS_method SSLv23_method
-#else // if OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_1_1_0_RTM
-
-#define NEED_OPENSSL_1_1 true
-
#endif
#endif // FEATURE_DISTRO_AGNOSTIC_SSL
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/osslcompat_102.h b/src/Native/Unix/System.Security.Cryptography.Native/osslcompat_102.h
new file mode 100644
index 0000000000..2ee440c320
--- /dev/null
+++ b/src/Native/Unix/System.Security.Cryptography.Native/osslcompat_102.h
@@ -0,0 +1,34 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+//
+
+#pragma once
+
+// Function prototypes unique to OpenSSL 1.0.2
+
+typedef struct stack_st _STACK;
+
+#undef CRYPTO_num_locks
+#undef CRYPTO_set_locking_callback
+#undef ERR_load_crypto_strings
+#undef EVP_CIPHER_CTX_cleanup
+#undef EVP_CIPHER_CTX_init
+#undef OPENSSL_add_all_algorithms_conf
+#undef SSL_library_init
+#undef SSL_load_error_strings
+#undef SSL_state
+#undef SSLeay
+
+int CRYPTO_add_lock(int* pointer, int amount, int type, const char* file, int line);
+int CRYPTO_num_locks(void);
+void CRYPTO_set_locking_callback(void (*func)(int mode, int type, const char* file, int line));
+void ERR_load_crypto_strings(void);
+int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX* a);
+int EVP_CIPHER_CTX_init(EVP_CIPHER_CTX* a);
+void HMAC_CTX_cleanup(HMAC_CTX* ctx);
+void HMAC_CTX_init(HMAC_CTX* ctx);
+void OPENSSL_add_all_algorithms_conf(void);
+int SSL_library_init(void);
+void SSL_load_error_strings(void);
+int SSL_state(const SSL* ssl);
+unsigned long SSLeay(void);
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/osslcompat_111.h b/src/Native/Unix/System.Security.Cryptography.Native/osslcompat_111.h
new file mode 100644
index 0000000000..0a730cef89
--- /dev/null
+++ b/src/Native/Unix/System.Security.Cryptography.Native/osslcompat_111.h
@@ -0,0 +1,80 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+// Function prototypes unique to OpenSSL 1.1.x
+
+#pragma once
+#include "pal_types.h"
+
+#undef SSL_CTX_set_options
+#undef SSL_session_reused
+
+typedef struct ossl_init_settings_st OPENSSL_INIT_SETTINGS;
+typedef struct stack_st OPENSSL_STACK;
+
+#define OPENSSL_INIT_LOAD_CRYPTO_STRINGS 0x00000002L
+#define OPENSSL_INIT_ADD_ALL_CIPHERS 0x00000004L
+#define OPENSSL_INIT_ADD_ALL_DIGESTS 0x00000008L
+#define OPENSSL_INIT_LOAD_CONFIG 0x00000040L
+#define OPENSSL_INIT_LOAD_SSL_STRINGS 0x00200000L
+
+const BIGNUM* DSA_get0_key(const DSA* dsa, const BIGNUM** pubKey, const BIGNUM** privKey);
+void DSA_get0_pqg(const DSA* dsa, const BIGNUM** p, const BIGNUM** q, const BIGNUM** g);
+const DSA_METHOD* DSA_get_method(const DSA* dsa);
+int32_t DSA_set0_key(DSA* dsa, BIGNUM* bnY, BIGNUM* bnX);
+int32_t DSA_set0_pqg(DSA* dsa, BIGNUM* bnP, BIGNUM* bnQ, BIGNUM* bnG);
+void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX* ctx);
+EVP_CIPHER_CTX* EVP_CIPHER_CTX_new(void);
+int32_t EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX* ctx);
+void EVP_MD_CTX_free(EVP_MD_CTX* ctx);
+EVP_MD_CTX* EVP_MD_CTX_new(void);
+RSA* EVP_PKEY_get0_RSA(EVP_PKEY* pkey);
+int32_t EVP_PKEY_up_ref(EVP_PKEY* pkey);
+void HMAC_CTX_free(HMAC_CTX* ctx);
+HMAC_CTX* HMAC_CTX_new(void);
+int OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS* settings);
+void OPENSSL_sk_free(OPENSSL_STACK*);
+OPENSSL_STACK* OPENSSL_sk_new_null(void);
+int OPENSSL_sk_num(const OPENSSL_STACK*);
+void* OPENSSL_sk_pop(OPENSSL_STACK* st);
+void OPENSSL_sk_pop_free(OPENSSL_STACK* st, void (*func)(void*));
+int OPENSSL_sk_push(OPENSSL_STACK* st, const void* data);
+void* OPENSSL_sk_value(const OPENSSL_STACK*, int);
+long OpenSSL_version_num(void);
+const RSA_METHOD* RSA_PKCS1_OpenSSL(void);
+void RSA_get0_crt_params(const RSA* rsa, const BIGNUM** dmp1, const BIGNUM** dmq1, const BIGNUM** iqmp);
+void RSA_get0_factors(const RSA* rsa, const BIGNUM** p, const BIGNUM** q);
+void RSA_get0_key(const RSA* rsa, const BIGNUM** n, const BIGNUM** e, const BIGNUM** d);
+int32_t RSA_meth_get_flags(const RSA_METHOD* meth);
+int32_t RSA_pkey_ctx_ctrl(EVP_PKEY_CTX* ctx, int32_t optype, int32_t cmd, int32_t p1, void* p2);
+int32_t RSA_set0_crt_params(RSA* rsa, BIGNUM* dmp1, BIGNUM* dmq1, BIGNUM* iqmp);
+int32_t RSA_set0_factors(RSA* rsa, BIGNUM* p, BIGNUM* q);
+int32_t RSA_set0_key(RSA* rsa, BIGNUM* n, BIGNUM* e, BIGNUM* d);
+int SSL_CTX_config(SSL_CTX* ctx, const char* name);
+unsigned long SSL_CTX_set_options(SSL_CTX* ctx, unsigned long options);
+void SSL_CTX_set_security_level(SSL_CTX* ctx, int32_t level);
+int32_t SSL_is_init_finished(SSL* ssl);
+int SSL_session_reused(SSL* ssl);
+const SSL_METHOD* TLS_method(void);
+const ASN1_TIME* X509_CRL_get0_nextUpdate(const X509_CRL* crl);
+int32_t X509_NAME_get0_der(X509_NAME* x509Name, const uint8_t** pder, size_t* pderlen);
+int32_t X509_PUBKEY_get0_param(
+ ASN1_OBJECT** palgOid, const uint8_t** pkeyBytes, int* pkeyBytesLen, X509_ALGOR** palg, X509_PUBKEY* pubkey);
+X509* X509_STORE_CTX_get0_cert(X509_STORE_CTX* ctx);
+STACK_OF(X509) * X509_STORE_CTX_get0_chain(X509_STORE_CTX* ctx);
+STACK_OF(X509) * X509_STORE_CTX_get0_untrusted(X509_STORE_CTX* ctx);
+X509_VERIFY_PARAM* X509_STORE_get0_param(X509_STORE* ctx);
+const ASN1_TIME* X509_get0_notAfter(const X509* x509);
+const ASN1_TIME* X509_get0_notBefore(const X509* x509);
+ASN1_BIT_STRING* X509_get0_pubkey_bitstr(const X509* x509);
+const X509_ALGOR* X509_get0_tbs_sigalg(const X509* x509);
+X509_PUBKEY* X509_get_X509_PUBKEY(const X509* x509);
+int32_t X509_get_version(const X509* x509);
+int32_t X509_up_ref(X509* x509);
+
+#if OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_1_0_2_RTM
+int32_t X509_check_host(X509* x509, const char* name, size_t namelen, unsigned int flags, char** peername);
+X509_STORE* X509_STORE_CTX_get0_store(X509_STORE_CTX* ctx);
+#define X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS 4
+
+#endif
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/osslcompat_30.h b/src/Native/Unix/System.Security.Cryptography.Native/osslcompat_30.h
new file mode 100644
index 0000000000..0fe57c9132
--- /dev/null
+++ b/src/Native/Unix/System.Security.Cryptography.Native/osslcompat_30.h
@@ -0,0 +1,23 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+// Function prototypes unique to OpenSSL 3.0
+
+#pragma once
+#include "pal_types.h"
+
+#undef EVP_PKEY_CTX_set_rsa_keygen_bits
+#undef EVP_PKEY_CTX_set_rsa_oaep_md
+#undef EVP_PKEY_CTX_set_rsa_padding
+#undef EVP_PKEY_CTX_set_rsa_pss_saltlen
+#undef EVP_PKEY_CTX_set_signature_md
+
+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, ...);
+int EVP_PKEY_CTX_set_rsa_keygen_bits(EVP_PKEY_CTX* ctx, int bits);
+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);
+X509* SSL_get1_peer_certificate(const SSL* ssl);
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/pal_ssl.c b/src/Native/Unix/System.Security.Cryptography.Native/pal_ssl.c
index 7764464bc8..c2e3fb2028 100644
--- a/src/Native/Unix/System.Security.Cryptography.Native/pal_ssl.c
+++ b/src/Native/Unix/System.Security.Cryptography.Native/pal_ssl.c
@@ -285,7 +285,7 @@ int32_t CryptoNative_IsSslStateOK(SSL* ssl)
X509* CryptoNative_SslGetPeerCertificate(SSL* ssl)
{
- return SSL_get_peer_certificate(ssl);
+ return SSL_get1_peer_certificate(ssl);
}
X509Stack* CryptoNative_SslGetPeerCertChain(SSL* ssl)
--
2.31.1

View File

@ -0,0 +1,36 @@
From 5848349f1e0df84949a01b41d41904036cc070f7 Mon Sep 17 00:00:00 2001
From: Omair Majid <omajid@redhat.com>
Date: Fri, 4 Jun 2021 17:21:28 -0400
Subject: [PATCH 06/11] Fix merge issues and make the build work
---
.../Cryptography/Pal.Unix/OpenSslX509ChainProcessor.cs | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/OpenSslX509ChainProcessor.cs b/src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/OpenSslX509ChainProcessor.cs
index a7f777261e..d5ec28b1ae 100644
--- a/src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/OpenSslX509ChainProcessor.cs
+++ b/src/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Unix/OpenSslX509ChainProcessor.cs
@@ -370,8 +370,8 @@ internal void Finish(OidCollection applicationPolicy, OidCollection certificateP
// chain is just fine (unless it returned a negative code for an exception)
Debug.Assert(verify, "verify should have returned true");
- const Interop.Crypto.X509VerifyStatusCode NoCrl =
- Interop.Crypto.X509VerifyStatusCode.X509_V_ERR_UNABLE_TO_GET_CRL;
+ Interop.Crypto.X509VerifyStatusCode NoCrl =
+ X509VerifyStatusCodeUniversal.X509_V_ERR_UNABLE_TO_GET_CRL;
ErrorCollection? errors =
workingChain.LastError > 0 ? (ErrorCollection?)workingChain[0] : null;
@@ -726,7 +726,7 @@ private static ArraySegment<char> Base64UrlEncode(ReadOnlySpan<byte> input)
X509ChainStatus chainStatus = new X509ChainStatus
{
Status = statusFlag,
- StatusInformation = Interop.Crypto.GetX509VerifyCertErrorString(errorCode),
+ StatusInformation = Interop.Crypto.GetX509VerifyCertErrorString(errorCode.Code),
};
elementStatus.Add(chainStatus);
--
2.31.1

View File

@ -0,0 +1,179 @@
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

View File

@ -0,0 +1,79 @@
From 30e2e4cbb11a4fbdb7102133b19bfc990a2ba939 Mon Sep 17 00:00:00 2001
From: Jeremy Barton <jbarton@microsoft.com>
Date: Fri, 16 Apr 2021 09:38:47 -0700
Subject: [PATCH 08/11] Work around OpenSSL 3.0 ciphers not restoring original
IV on reset.
---
.../opensslshim.h | 2 ++
.../osslcompat_30.h | 1 +
.../pal_evp_cipher.c | 20 ++++++++++++++++++-
3 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.h b/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.h
index 957860cae4..c5052c1ba5 100644
--- a/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.h
+++ b/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.h
@@ -271,6 +271,7 @@ void SSL_get0_alpn_selected(const SSL* ssl, const unsigned char** protocol, unsi
LEGACY_FUNCTION(EVP_CIPHER_CTX_cleanup) \
REQUIRED_FUNCTION(EVP_CIPHER_CTX_ctrl) \
FALLBACK_FUNCTION(EVP_CIPHER_CTX_free) \
+ LIGHTUP_FUNCTION(EVP_CIPHER_CTX_get_original_iv) \
LEGACY_FUNCTION(EVP_CIPHER_CTX_init) \
FALLBACK_FUNCTION(EVP_CIPHER_CTX_new) \
FALLBACK_FUNCTION(EVP_CIPHER_CTX_reset) \
@@ -676,6 +677,7 @@ FOR_ALL_OPENSSL_FUNCTIONS
#define EVP_CIPHER_CTX_cleanup EVP_CIPHER_CTX_cleanup_ptr
#define EVP_CIPHER_CTX_ctrl EVP_CIPHER_CTX_ctrl_ptr
#define EVP_CIPHER_CTX_free EVP_CIPHER_CTX_free_ptr
+#define EVP_CIPHER_CTX_get_original_iv EVP_CIPHER_CTX_get_original_iv_ptr
#define EVP_CIPHER_CTX_init EVP_CIPHER_CTX_init_ptr
#define EVP_CIPHER_CTX_new EVP_CIPHER_CTX_new_ptr
#define EVP_CIPHER_CTX_reset EVP_CIPHER_CTX_reset_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 b87b4e7250..bb529df51e 100644
--- a/src/Native/Unix/System.Security.Cryptography.Native/osslcompat_30.h
+++ b/src/Native/Unix/System.Security.Cryptography.Native/osslcompat_30.h
@@ -18,6 +18,7 @@ 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, ...);
+int EVP_CIPHER_CTX_get_original_iv(EVP_CIPHER_CTX *ctx, void *buf, size_t len);
int EVP_PKEY_CTX_set_rsa_keygen_bits(EVP_PKEY_CTX* ctx, int bits);
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);
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/pal_evp_cipher.c b/src/Native/Unix/System.Security.Cryptography.Native/pal_evp_cipher.c
index af2483fa0c..4d21294fa1 100644
--- a/src/Native/Unix/System.Security.Cryptography.Native/pal_evp_cipher.c
+++ b/src/Native/Unix/System.Security.Cryptography.Native/pal_evp_cipher.c
@@ -127,8 +127,26 @@ int32_t CryptoNative_EvpCipherReset(EVP_CIPHER_CTX* ctx)
//
// But since we have a different object returned for CreateEncryptor
// and CreateDecryptor we don't need to worry about that.
+ uint8_t* iv = NULL;
- return EVP_CipherInit_ex(ctx, NULL, NULL, NULL, NULL, KEEP_CURRENT_DIRECTION);
+#ifdef NEED_OPENSSL_3_0
+ // OpenSSL 3.0 alpha 13 does not properly reset the IV. Work around that by
+ // asking for the original IV, and giving it back.
+ uint8_t tmpIV[EVP_MAX_IV_LENGTH];
+
+ // If we're direct against 3.0, or we're portable and found 3.0
+ if (API_EXISTS(EVP_CIPHER_CTX_get_original_iv))
+ {
+ if (EVP_CIPHER_CTX_get_original_iv(ctx, tmpIV, sizeof(tmpIV)) != 1)
+ {
+ return 0;
+ }
+
+ iv = tmpIV;
+ }
+#endif
+
+ return EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, KEEP_CURRENT_DIRECTION);
}
int32_t CryptoNative_EvpCipherCtxSetPadding(EVP_CIPHER_CTX* x, int32_t padding)
--
2.31.1

View File

@ -0,0 +1,48 @@
From b7700862a9a85e5bab302c158d5aa6ac1af7c5c1 Mon Sep 17 00:00:00 2001
From: Omair Majid <omajid@redhat.com>
Date: Mon, 7 Jun 2021 11:37:48 -0400
Subject: [PATCH 09/11] Use `1` instead of `true` for more portable code
---
.../opensslshim.h | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.h b/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.h
index c5052c1ba5..b0d1a71671 100644
--- a/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.h
+++ b/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.h
@@ -91,9 +91,9 @@ void ERR_put_error(int32_t lib, int32_t func, int32_t reason, const char* file,
#ifdef FEATURE_DISTRO_AGNOSTIC_SSL
-#define NEED_OPENSSL_1_0 true
-#define NEED_OPENSSL_1_1 true
-#define NEED_OPENSSL_3_0 true
+#define NEED_OPENSSL_1_0 1
+#define NEED_OPENSSL_1_1 1
+#define NEED_OPENSSL_3_0 1
#if !HAVE_OPENSSL_EC2M
// In portable build, we need to support the following functions even if they were not present
@@ -991,14 +991,14 @@ FOR_ALL_OPENSSL_FUNCTIONS
#else // FEATURE_DISTRO_AGNOSTIC_SSL
-#define API_EXISTS(fn) true
+#define API_EXISTS(fn) 1
#if OPENSSL_VERSION_NUMBER >= OPENSSL_VERSION_3_0_RTM
-#define NEED_OPENSSL_3_0 true
+#define NEED_OPENSSL_3_0 1
#elif OPENSSL_VERSION_NUMBER >= OPENSSL_VERSION_1_1_0_RTM
-#define NEED_OPENSSL_1_1 true
+#define NEED_OPENSSL_1_1 1
#else
-#define NEED_OPENSSL_1_0 true
+#define NEED_OPENSSL_1_0 1
#endif
#if OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_3_0_RTM
--
2.31.1

View File

@ -0,0 +1,80 @@
From c746b2a3bd8ae3b76740e2b4f2cf12646eedbb51 Mon Sep 17 00:00:00 2001
From: Jeremy Barton <jbarton@microsoft.com>
Date: Sat, 21 Aug 2021 05:05:19 -0700
Subject: [PATCH 10/11] Stop using ERR_GET_FUNC, since it has been removed in
OSSL3 Beta2. (#57869)
---
.../openssl.c | 25 +++++++++++--------
.../opensslshim.h | 2 ++
2 files changed, 16 insertions(+), 11 deletions(-)
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/openssl.c b/src/Native/Unix/System.Security.Cryptography.Native/openssl.c
index 6792bdb1a1..e55486dc80 100644
--- a/src/Native/Unix/System.Security.Cryptography.Native/openssl.c
+++ b/src/Native/Unix/System.Security.Cryptography.Native/openssl.c
@@ -1064,27 +1064,30 @@ int32_t CryptoNative_LookupFriendlyNameByOid(const char* oidValue, const char**
return -2;
}
+ // First, check if oidValue parses as a dotted decimal OID. If not, we'll
+ // return not-found and let the system cache that.
+ int asnRet = a2d_ASN1_OBJECT(NULL, 0, oidValue, -1);
+
+ if (asnRet <= 0)
+ {
+ return 0;
+ }
+
// Do a lookup with no_name set. The purpose of this function is to map only the
// dotted decimal to the friendly name. "sha1" in should not result in "sha1" out.
oid = OBJ_txt2obj(oidValue, 1);
- if (!oid)
+ if (oid == NULL)
{
- unsigned long err = ERR_peek_last_error();
-
- // If the most recent error pushed onto the error queue is NOT from OID parsing
- // then signal for an exception to be thrown.
- if (err != 0 && ERR_GET_FUNC(err) != ASN1_F_A2D_ASN1_OBJECT)
- {
- return -1;
- }
-
- return 0;
+ // We know that the OID parsed (unless it underwent concurrent modification,
+ // which is unsupported), so any error in this stage should be an exception.
+ return -1;
}
// Look in the predefined, and late-registered, OIDs list to get the lookup table
// identifier for this OID. The OBJ_txt2obj object will not have ln set.
nid = OBJ_obj2nid(oid);
+ ASN1_OBJECT_free(oid);
if (nid == NID_undef)
{
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.h b/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.h
index b0d1a71671..c11285e7dd 100644
--- a/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.h
+++ b/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.h
@@ -148,6 +148,7 @@ void SSL_get0_alpn_selected(const SSL* ssl, const unsigned char** protocol, unsi
// that needs to be added.
#define FOR_ALL_OPENSSL_FUNCTIONS \
+ REQUIRED_FUNCTION(a2d_ASN1_OBJECT) \
REQUIRED_FUNCTION(ASN1_BIT_STRING_free) \
REQUIRED_FUNCTION(ASN1_d2i_bio) \
REQUIRED_FUNCTION(ASN1_i2d_bio) \
@@ -554,6 +555,7 @@ FOR_ALL_OPENSSL_FUNCTIONS
// Redefine all calls to OpenSSL functions as calls through pointers that are set
// to the functions from the libssl.so selected by the shim.
+#define a2d_ASN1_OBJECT a2d_ASN1_OBJECT_ptr
#define ASN1_BIT_STRING_free ASN1_BIT_STRING_free_ptr
#define ASN1_GENERALIZEDTIME_free ASN1_GENERALIZEDTIME_free_ptr
#define ASN1_d2i_bio ASN1_d2i_bio_ptr
--
2.31.1

View File

@ -0,0 +1,140 @@
From 05fb8ceb229d76ae32bd18e707b3682c8302490c Mon Sep 17 00:00:00 2001
From: Jeremy Barton <jbarton@microsoft.com>
Date: Tue, 13 Jul 2021 01:38:33 -0700
Subject: [PATCH 11/11] Adjust crypto shim for functions renamed for OSSL3
beta1
---
.../opensslshim.h | 15 +++++++++------
.../osslcompat_30.h | 3 +++
.../System.Security.Cryptography.Native/pal_evp.c | 2 +-
.../pal_evp_pkey.c | 2 +-
4 files changed, 14 insertions(+), 8 deletions(-)
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.h b/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.h
index c11285e7dd..b3386d381f 100644
--- a/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.h
+++ b/src/Native/Unix/System.Security.Cryptography.Native/opensslshim.h
@@ -292,7 +292,7 @@ void SSL_get0_alpn_selected(const SSL* ssl, const unsigned char** protocol, unsi
REQUIRED_FUNCTION(EVP_md5) \
RENAMED_FUNCTION(EVP_MD_CTX_free, EVP_MD_CTX_destroy) \
RENAMED_FUNCTION(EVP_MD_CTX_new, EVP_MD_CTX_create) \
- REQUIRED_FUNCTION(EVP_MD_size) \
+ RENAMED_FUNCTION(EVP_MD_get_size, EVP_MD_size) \
REQUIRED_FUNCTION(EVP_PKEY_CTX_ctrl) \
REQUIRED_FUNCTION(EVP_PKEY_CTX_free) \
REQUIRED_FUNCTION(EVP_PKEY_CTX_get0_pkey) \
@@ -303,13 +303,14 @@ void SSL_get0_alpn_selected(const SSL* ssl, const unsigned char** protocol, unsi
FALLBACK_FUNCTION(EVP_PKEY_CTX_set_rsa_padding) \
FALLBACK_FUNCTION(EVP_PKEY_CTX_set_rsa_pss_saltlen) \
FALLBACK_FUNCTION(EVP_PKEY_CTX_set_signature_md) \
- REQUIRED_FUNCTION(EVP_PKEY_base_id) \
REQUIRED_FUNCTION(EVP_PKEY_decrypt) \
REQUIRED_FUNCTION(EVP_PKEY_decrypt_init) \
REQUIRED_FUNCTION(EVP_PKEY_derive_set_peer) \
REQUIRED_FUNCTION(EVP_PKEY_derive_init) \
REQUIRED_FUNCTION(EVP_PKEY_derive) \
REQUIRED_FUNCTION(EVP_PKEY_free) \
+ RENAMED_FUNCTION(EVP_PKEY_get_base_id, EVP_PKEY_base_id) \
+ RENAMED_FUNCTION(EVP_PKEY_get_size, EVP_PKEY_size) \
FALLBACK_FUNCTION(EVP_PKEY_get0_RSA) \
REQUIRED_FUNCTION(EVP_PKEY_get1_DSA) \
REQUIRED_FUNCTION(EVP_PKEY_get1_EC_KEY) \
@@ -322,7 +323,6 @@ void SSL_get0_alpn_selected(const SSL* ssl, const unsigned char** protocol, unsi
REQUIRED_FUNCTION(EVP_PKEY_set1_RSA) \
REQUIRED_FUNCTION(EVP_PKEY_sign) \
REQUIRED_FUNCTION(EVP_PKEY_sign_init) \
- REQUIRED_FUNCTION(EVP_PKEY_size) \
FALLBACK_FUNCTION(EVP_PKEY_up_ref) \
REQUIRED_FUNCTION(EVP_rc2_cbc) \
REQUIRED_FUNCTION(EVP_rc2_ecb) \
@@ -699,7 +699,7 @@ FOR_ALL_OPENSSL_FUNCTIONS
#define EVP_md5 EVP_md5_ptr
#define EVP_MD_CTX_free EVP_MD_CTX_free_ptr
#define EVP_MD_CTX_new EVP_MD_CTX_new_ptr
-#define EVP_MD_size EVP_MD_size_ptr
+#define EVP_MD_get_size EVP_MD_get_size_ptr
#define EVP_PKEY_CTX_ctrl EVP_PKEY_CTX_ctrl_ptr
#define EVP_PKEY_CTX_free EVP_PKEY_CTX_free_ptr
#define EVP_PKEY_CTX_get0_pkey EVP_PKEY_CTX_get0_pkey_ptr
@@ -710,13 +710,14 @@ FOR_ALL_OPENSSL_FUNCTIONS
#define EVP_PKEY_CTX_set_rsa_padding EVP_PKEY_CTX_set_rsa_padding_ptr
#define EVP_PKEY_CTX_set_rsa_pss_saltlen EVP_PKEY_CTX_set_rsa_pss_saltlen_ptr
#define EVP_PKEY_CTX_set_signature_md EVP_PKEY_CTX_set_signature_md_ptr
-#define EVP_PKEY_base_id EVP_PKEY_base_id_ptr
#define EVP_PKEY_decrypt_init EVP_PKEY_decrypt_init_ptr
#define EVP_PKEY_decrypt EVP_PKEY_decrypt_ptr
#define EVP_PKEY_derive_set_peer EVP_PKEY_derive_set_peer_ptr
#define EVP_PKEY_derive_init EVP_PKEY_derive_init_ptr
#define EVP_PKEY_derive EVP_PKEY_derive_ptr
#define EVP_PKEY_free EVP_PKEY_free_ptr
+#define EVP_PKEY_get_base_id EVP_PKEY_get_base_id_ptr
+#define EVP_PKEY_get_size EVP_PKEY_get_size_ptr
#define EVP_PKEY_get0_RSA EVP_PKEY_get0_RSA_ptr
#define EVP_PKEY_get1_DSA EVP_PKEY_get1_DSA_ptr
#define EVP_PKEY_get1_EC_KEY EVP_PKEY_get1_EC_KEY_ptr
@@ -729,7 +730,6 @@ FOR_ALL_OPENSSL_FUNCTIONS
#define EVP_PKEY_set1_RSA EVP_PKEY_set1_RSA_ptr
#define EVP_PKEY_sign_init EVP_PKEY_sign_init_ptr
#define EVP_PKEY_sign EVP_PKEY_sign_ptr
-#define EVP_PKEY_size EVP_PKEY_size_ptr
#define EVP_PKEY_up_ref EVP_PKEY_up_ref_ptr
#define EVP_rc2_cbc EVP_rc2_cbc_ptr
#define EVP_rc2_ecb EVP_rc2_ecb_ptr
@@ -1006,6 +1006,9 @@ FOR_ALL_OPENSSL_FUNCTIONS
#if OPENSSL_VERSION_NUMBER < OPENSSL_VERSION_3_0_RTM
// Undo renames for renamed-in-3.0
+#define EVP_MD_get_size EVP_MD_size
+#define EVP_PKEY_get_base_id EVP_PKEY_base_id
+#define EVP_PKEY_get_size EVP_PKEY_size
#define SSL_get1_peer_certificate SSL_get_peer_certificate
#endif
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 bb529df51e..dba69f1382 100644
--- a/src/Native/Unix/System.Security.Cryptography.Native/osslcompat_30.h
+++ b/src/Native/Unix/System.Security.Cryptography.Native/osslcompat_30.h
@@ -19,10 +19,13 @@ 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, ...);
int EVP_CIPHER_CTX_get_original_iv(EVP_CIPHER_CTX *ctx, void *buf, size_t len);
+int EVP_MD_get_size(const EVP_MD* md);
int EVP_PKEY_CTX_set_rsa_keygen_bits(EVP_PKEY_CTX* ctx, int bits);
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);
+int EVP_PKEY_get_base_id(const EVP_PKEY* pkey);
+int EVP_PKEY_get_size(const EVP_PKEY* pkey);
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/Native/Unix/System.Security.Cryptography.Native/pal_evp.c b/src/Native/Unix/System.Security.Cryptography.Native/pal_evp.c
index 9665ffe3fa..5ec3c63122 100644
--- a/src/Native/Unix/System.Security.Cryptography.Native/pal_evp.c
+++ b/src/Native/Unix/System.Security.Cryptography.Native/pal_evp.c
@@ -59,7 +59,7 @@ int32_t CryptoNative_EvpDigestFinalEx(EVP_MD_CTX* ctx, uint8_t* md, uint32_t* s)
int32_t CryptoNative_EvpMdSize(const EVP_MD* md)
{
- return EVP_MD_size(md);
+ return EVP_MD_get_size(md);
}
const EVP_MD* CryptoNative_EvpMd5()
diff --git a/src/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey.c b/src/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey.c
index f232b382ea..67410bc4e8 100644
--- a/src/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey.c
+++ b/src/Native/Unix/System.Security.Cryptography.Native/pal_evp_pkey.c
@@ -21,7 +21,7 @@ void CryptoNative_EvpPkeyDestroy(EVP_PKEY* pkey)
int32_t CryptoNative_EvpPKeySize(EVP_PKEY* pkey)
{
assert(pkey != NULL);
- return EVP_PKEY_size(pkey);
+ return EVP_PKEY_get_size(pkey);
}
int32_t CryptoNative_UpRefEvpPkey(EVP_PKEY* pkey)
--
2.31.1

1
dead.package Normal file
View File

@ -0,0 +1 @@
dotnet3.1 package is retired on c9s for CS-1038

35
dotnet3.1.rpmlintrc Normal file
View File

@ -0,0 +1,35 @@
# Tarball is generated, no upstream URL
addFilter("W:.*invalid-url Source0: dotnet-.*tar.gz")
# macOS is the correct name
addFilter("W: spelling-error %description -l en_US macOS ->.*")
# The name of the nuget package includes NETCore
addFilter("W: spelling-error .* NETCore -> Net Core.*")
# Upstream really has no README or documentation files. They suggest using online resources.
addFilter("W: no-documentation")
# This is a script that we run; it's expected to have execute permissions
addFilter("W: strange-permission check-debug-symbols.py")
# libicu is a required dependency, but it's used via a dlopen()
addFilter("E: explicit-lib-dependency libicu")
# There's no devel package for us to place .h files
addFilter("W: devel-file-in-non-devel-package /usr/lib64/dotnet/.*\.h")
addFilter("W: devel-file-in-non-devel-package /usr/lib64/dotnet/.*\.a")
# These paths are non-standard, so we need $ORIGIN to find these libraries
addFilter("E: binary-or-shlib-defines-rpath /usr/lib64/dotnet/.*\['\$ORIGIN/netcoredeps'\]")
addFilter("E: binary-or-shlib-defines-rpath /usr/lib64/dotnet/.*\['\$ORIGIN'\]")
# We put dll files in /usr/lib/dotnet, but rpmlint somehow doesn't see it as a binary?
addFilter("W: only-non-binary-in-usr-lib")
# We use a number of zero-length files, including _._
addFilter("E: zero-length /usr/lib64/dotnet/.*/_\._")
# Upstream uses hidden files, even though we ask them not to, as much as possible
addFilter("W: hidden-file-or-dir /usr/lib64/dotnet/.*/\.version")
addFilter("W: hidden-file-or-dir /usr/lib64/dotnet/.*/\.toolsetversion")

View File

@ -21,10 +21,10 @@
%define _lto_cflags %{nil}
%global host_version 3.1.13
%global runtime_version 3.1.13
%global host_version 3.1.18
%global runtime_version 3.1.18
%global aspnetcore_runtime_version %{runtime_version}
%global sdk_version 3.1.113
%global sdk_version 3.1.118
# upstream can update releases without revving the SDK version so these don't always match
%global src_version %{sdk_version}
%global templates_version %(echo %{runtime_version} | awk 'BEGIN { FS="."; OFS="." } {print $1, $2, $3+1 }')
@ -55,7 +55,7 @@
Name: dotnet3.1
Version: %{sdk_rpm_version}
Release: 3%{?dist}
Release: 1%{?dist}
Summary: .NET Core Runtime and SDK
License: MIT and ASL 2.0 and BSD and LGPLv2+ and CC-BY and CC0 and MS-PL and EPL-1.0 and GPL+ and GPLv2 and ISC and OFL and zlib
URL: https://github.com/dotnet/
@ -65,9 +65,9 @@ URL: https://github.com/dotnet/
Source0: dotnet-v%{src_version}-SDK.tar.gz
Source1: check-debug-symbols.py
Source2: dotnet.sh.in
Source3: boot-sdk-centos-rid.patch
Patch1: source-build-warnings-are-not-errors.patch
Patch2: source-build-ilasm-ildasm-path-fix.patch
# Fix building with our additional CFLAGS/CXXFLAGS/LDFLAGS
Patch100: corefx-optflags-support.patch
@ -78,23 +78,25 @@ Patch101: corefx-39686-cgroupv2-01.patch
Patch102: corefx-39686-cgroupv2-02.patch
Patch103: corefx-39633-cgroupv2-mountpoints.patch
# https://github.com/dotnet/corefx/pull/43032
Patch104: corefx-43032-fedora-35-rid.patch
# https://github.com/dotnet/corefx/pull/43068
Patch105: corefx-43068-centos-9-rid.patch
# https://github.com/dotnet/corefx/pull/43078
Patch106: corefx-openssl-0001-Use-EVP_PKEY-for-RSA-key-generation.patch
Patch107: corefx-openssl-0002-Use-EVP_PKEY-for-RSA-Decrypt.patch
Patch108: corefx-openssl-0003-Use-EVP_PKEY-for-RSA-signing-operations.patch
Patch109: corefx-openssl-0004-Support-compiling-against-OpenSSL-3-headers.patch
Patch110: corefx-openssl-0005-Make-portable-builds-work-across-OpenSSL-1.0.2-1.1.1.patch
Patch111: corefx-openssl-0006-Fix-merge-issues-and-make-the-build-work.patch
Patch112: corefx-openssl-0007-OpenSSL3-Register-legacy-algorithms-when-needed.patch
Patch113: corefx-openssl-0008-Work-around-OpenSSL-3.0-ciphers-not-restoring-origin.patch
Patch114: corefx-openssl-0009-Use-1-instead-of-true-for-more-portable-code.patch
Patch115: corefx-openssl-0010-Stop-using-ERR_GET_FUNC-since-it-has-been-removed-in.patch
Patch116: corefx-openssl-0011-Adjust-crypto-shim-for-functions-renamed-for-OSSL3-b.patch
# Build with with hardening flags, including -pie
Patch200: coreclr-hardening-flags.patch
# Fix build with clang 10; Already applied at tarball-build time
# Patch201: coreclr-clang10.patch
# Patch200: coreclr-clang10.patch
# Fix build on recent versions of gcc/clang
# https://github.com/libunwind/libunwind/pull/166
# Already applied
#Patch202: coreclr-libunwind-fno-common.patch
# Build with with hardening flags, including -pie
Patch300: core-setup-hardening-flags.patch
Patch301: core-setup-gcc11.patch
#Patch201: coreclr-libunwind-fno-common.patch
# Disable telemetry by default; make it opt-in
Patch500: cli-telemetry-optout.patch
@ -131,6 +133,9 @@ BuildRequires: llvm
BuildRequires: lttng-ust-devel
BuildRequires: make
BuildRequires: openssl-devel
%if 0%{?rhel} > 8
BuildRequires: compat-openssl11
%endif
BuildRequires: python3
BuildRequires: systemtap-sdt-devel
BuildRequires: tar
@ -347,7 +352,6 @@ rm -rf packages/source-built
%endif
%if %{without bootstrap}
sed -i -e 's|3.1.100-preview1-014459|3.1.103|' global.json
mkdir -p packages/archive
ln -s %{_libdir}/dotnet/source-built-artifacts/*.tar.gz packages/archive/
ln -s %{_libdir}/dotnet/reference-packages/Private.SourceBuild.ReferencePackages*.tar.gz packages/archive
@ -360,25 +364,32 @@ sed -i 's|/usr/share/dotnet|%{_libdir}/dotnet|' src/core-setup.*/src/corehost/co
sed -i 's|skiptests|skiptests ignorewarnings|' repos/coreclr.proj
%patch1 -p1
%patch2 -p1
pushd src/corefx.*
%patch100 -p1
%patch101 -p1
%patch102 -p1
%patch103 -p1
%patch104 -p1
%patch105 -p1
%patch106 -p1
%patch107 -p1
%patch108 -p1
%patch109 -p1
%patch110 -p1
%patch111 -p1
%patch112 -p1
%patch113 -p1
%patch114 -p1
%patch115 -p1
%patch116 -p1
popd
pushd src/coreclr.*
%patch200 -p1
#%%patch200 -p1
#%%patch201 -p1
#%%patch202 -p1
popd
pushd src/core-setup.*
%patch300 -p1
%patch301 -p1
popd
pushd src/cli.*
@ -410,17 +421,6 @@ cat /etc/os-release
%if %{without bootstrap}
# We need to create a copy because we will mutate this
cp -a %{_libdir}/dotnet previously-built-dotnet
# .NET Core 3.1 doesn't (yet) know about CentOS 9, so lets hack the
# CentOS 9 RID into there, for now. This hack can be removed when an
# SDK that knows about CentOS 9 is available in the buildroot.
%if 0%{?rhel} == 9
cat /etc/os-release
find -iname RuntimeIdentifierGraph.json
patch -p1 -i %{SOURCE3}
cat $(find -iname RuntimeIdentifierGraph.json)
%endif
%endif
%if 0%{?fedora} > 32 || 0%{?rhel} > 8
@ -575,6 +575,38 @@ echo "Testing build results for debug symbols..."
%changelog
* Fri Aug 27 2021 Omair Majid <omajid@redhat.com> - 3.1.118-1
- Update to .NET SDK 3.1.118 and Runtime 3.1.18
- Resolves: RHBZ#1961848
* Tue Aug 24 2021 Omair Majid <omajid@redhat.com> - 3.1.117-2
- Fix building and running against OpenSSL 3.0
- Resolves: RHBZ#1991050
* Thu Aug 12 2021 Omair Majid <omajid@redhat.com> - 3.1.117-1
- Update to .NET SDK 3.1.117 and Runtime 3.1.17
- Resolves: RHBZ#1961848
* Mon Aug 09 2021 Mohan Boddu <mboddu@redhat.com> - 3.1.116-3
- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
Related: rhbz#1991688
* Wed Jun 16 2021 Mohan Boddu <mboddu@redhat.com> - 3.1.116-2
- Rebuilt for RHEL 9 BETA for openssl 3.0
Related: rhbz#1971065
* Fri Jun 11 2021 Omair Majid <omajid@redhat.com> - 3.1.116-1
- Update to .NET SDK 3.1.116 and Runtime 3.1.16
- Resolves: RHBZ#1961848
* Mon Jun 07 2021 Omair Majid <omajid@redhat.com> - 3.1.115-2
- Support building against OpenSSL 3.0
- Resolves: RHBZ#1965045
* Tue May 18 2021 Omair Majid <omajid@redhat.com> - 3.1.115-1
- Update to .NET SDK 3.1.115 and Runtime 3.1.15
- Resolves: RHBZ#1961848
* Wed Apr 21 2021 Omair Majid <omajid@redhat.com> - 3.1.113-3
- Fix build by adding CentOS 9 RIDs
- Resolves: RHBZ#1951312

View File

@ -21,12 +21,14 @@ while [[ "$#" -gt 0 ]]; do
esac
done
original_name=${positional_args[0]:-}
if [[ -z ${original_name} ]]; then
if [[ -z "${positional_args[0]:-}" ]]; then
echo "error: missing original tarball name"
exit 1
fi
original_path=$(readlink -f "${positional_args[0]:-}")
original_name=$(basename "$original_path")
new_name=${positional_args[1]:-}
if [[ -z ${new_name} ]]; then
echo "error: missing new tarball name"
@ -41,8 +43,8 @@ echo "New name: ${new_name}.tar.gz"
mkdir "temp-${new_name}"
pushd "temp-${new_name}"
tar xf "../${original_name}.tar.gz"
mv "${original_name}" "${new_name}"
tar xf "${original_path}"
mv -- * "${new_name}"
tar czf ../"${new_name}.tar.gz" "${new_name}"
rm -rf "${new_name}"
popd

12
rpminspect.yaml Normal file
View File

@ -0,0 +1,12 @@
---
inspections:
# We ship an empty dotnet package that installs the latest SDK, but
# also a newer SDK when we have that
emptyrpm: off
# We patch upstream a lot, no need to reject patches
patches: off
runpath:
# Upstream explicitly sets $ORIGIN/netcoredeps as an RPATH
# See https://github.com/dotnet/core/blob/main/Documentation/self-contained-linux-apps.md
allowed_origin_paths:
- /netcoredeps

View File

@ -0,0 +1,15 @@
diff --git a/Directory.Build.props b/Directory.Build.props
index f6a6f54a..8247c3ee 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -133,8 +133,8 @@
<AspNetRazorBuildServerLogDir>$(BaseOutputPath)aspnet-debug</AspNetRazorBuildServerLogDir>
<AspNetRazorBuildServerLogFile>$(AspNetRazorBuildServerLogDir)razor-build-server.log</AspNetRazorBuildServerLogFile>
<IlasmPath Condition="'$(OfflineBuild)' != 'true'">invalid: ILAsm is not expected to be needed in the online build</IlasmPath>
- <IlasmPath Condition="'$(OfflineBuild)' == 'true'">$(PrebuiltSourceBuiltPackagesPath)coreclr-tools/$(BuildArchitecture)/ilasm</IlasmPath>
- <IldasmPath Condition="'$(OfflineBuild)' != 'true'">$(ToolPackageExtractDir)coreclr-tools/$(BuildArchitecture)/ildasm</IldasmPath>
+ <IlasmPath Condition="'$(OfflineBuild)' == 'true'">$(PrebuiltSourceBuiltPackagesPath)coreclr-tools/ilasm</IlasmPath>
+ <IldasmPath Condition="'$(OfflineBuild)' != 'true'">$(ToolPackageExtractDir)coreclr-tools/ildasm</IldasmPath>
<IldasmPath Condition="'$(OfflineBuild)' == 'true'">invalid: ILDasm is not expected to be needed in the offline build</IldasmPath>
<!-- Dir where git info is generated during online builds. -->
<GitInfoOutputDir>$(BaseOutputPath)git-info/</GitInfoOutputDir>

View File

@ -1 +1 @@
SHA512 (dotnet-v3.1.113-SDK.tar.gz) = ed8dd57e9179d833084edc536340befc99065ef8f53aaddd2b3d2223787fe0b904d42ed46f506b00bc8a40e44610aff7474cecdfdf24ad232fad34ac847027cd
SHA512 (dotnet-v3.1.118-SDK.tar.gz) = 0c8fd6d9bedf262717e1d80bcd9f21c5647fd377a4e3abf29f47d4bfe017fece2cf82972a9fe7ff9284c5ff298c0c9ee7a325527b77d881fea57447e4148524e

View File

@ -21,13 +21,12 @@
dir: ./
run: ./turkey -l={{ remote_artifacts }} dotnet-regular-tests
required_packages:
- babeltrace
- bash-completion
- binutils
- compat-openssl11
- expect
- jq
- lldb
- lttng-tools
- npm
- python3
- strace

View File

@ -1,24 +1,37 @@
#!/bin/bash
# Usage:
# ./update-release sdk-version runtime-version
# ./update-release sdk-version runtime-version [--bug bug-id] [--tarball tarball-name]
set -euo pipefail
IFS=$'\n\t'
print_usage() {
echo " Usage:"
echo " ./update-release sdk-version runtime-version"
echo " ./update-release sdk-version runtime-version [--bug bug-id] [--tarball tarball-name]"
}
user_provided_tarball_name=""
positional_args=()
bug_ids=()
while [[ "$#" -gt 0 ]]; do
arg="${1}"
arg="$1"
case "${arg}" in
--bug)
bug_ids+=("$2")
shift;
shift;
;;
-h|--help)
print_usage
exit 0
;;
--tarball)
user_provided_tarball_name="$2"
shift;
shift;
;;
*)
positional_args+=("$1")
shift
@ -26,7 +39,8 @@ while [[ "$#" -gt 0 ]]; do
esac
done
spec_file=dotnet3.1.spec
spec_files=( ./*.spec )
spec_file="${spec_files[0]}"
sdk_version=${positional_args[0]:-}
if [[ -z ${sdk_version} ]]; then
@ -42,8 +56,22 @@ fi
host_version="$runtime_version"
if [[ ! -f "dotnet-v${sdk_version}-SDK.tar.gz" ]]; then
./build-dotnet-tarball "v${sdk_version}-SDK"
tag=v${sdk_version}-SDK
if [[ -f "dotnet-${tag}-original.tar.gz" ]]; then
echo "dotnet-${tag}-original.tar.gz alredy exists, not rebuilding tarball"
else
if [[ -n "${user_provided_tarball_name}" ]]; then
./rename-tarball "$user_provided_tarball_name" "dotnet-${tag}-original.tar.gz"
elif [[ -f "dotnet-${sdk_version}-SDK.tar.gz" ]]; then
./rename-tarball "dotnet-${sdk_version}-SDK.tar.gz" "dotnet-${tag}-original.tar.gz"
elif [[ -f "dotnet-${runtime_version}.tar.gz" ]]; then
./rename-tarball "dotnet-${runtime_version}.tar.gz" "dotnet-${tag}-original.tar.gz"
fi
fi
if [[ ! -f "dotnet-${tag}.tar.gz" ]]; then
./build-dotnet-tarball "${tag}"
fi
set -x
@ -52,12 +80,16 @@ sed -i -E "s|^%global host_version [[:digit:]]\.[[:digit:]]\.[[:digit:]]+|%globa
sed -i -E "s|^%global runtime_version [[:digit:]]\.[[:digit:]]\.[[:digit:]]+|%global runtime_version ${runtime_version}|" "$spec_file"
sed -i -E "s|^%global sdk_version [[:digit:]]\.[[:digit:]]\.[[:digit:]][[:digit:]][[:digit:]]|%global sdk_version ${sdk_version}|" "$spec_file"
comment="Update to .NET Core SDK ${sdk_version} and Runtime ${runtime_version}"
comment="Update to .NET SDK ${sdk_version} and Runtime ${runtime_version}"
for bug_id in "${bug_ids[@]}"; do
comment="$comment
- Resolves: RHBZ#$bug_id"
done
rpmdev-bumpspec -D --comment="$comment" $spec_file
rpmdev-bumpspec --comment="$comment" "$spec_file"
# Reset release to 1 in 'Release' tag
sed -i -E 's|^Release: [[:digit:]]+%|Release: 1%|' $spec_file
sed -i -E 's|^Release: [[:digit:]]+%|Release: 1%|' "$spec_file"
# Reset Release in changelog comment
# See https://stackoverflow.com/questions/18620153/find-matching-text-and-replace-next-line
sed -i -E '/^%changelog$/!b;n;s/-[[:digit:]]+$/-1/' $spec_file
sed -i -E '/^%changelog$/!b;n;s/-[[:digit:]]+$/-1/' "$spec_file"