Compare commits

...

No commits in common. "c8" and "c9s" have entirely different histories.
c8 ... c9s

44 changed files with 5878 additions and 364 deletions

View File

@ -1 +0,0 @@
12090bf3fa9d16f96a49119818246d432ec5e1e1 SOURCES/dotnet-v3.1.426-SDK.tar.gz

20
.gitignore vendored
View File

@ -1 +1,19 @@
SOURCES/dotnet-v3.1.426-SDK.tar.gz
/dotnet-v3.1.101-SDK.tar.gz
/dotnet-v3.1.102-SDK.tar.gz
/dotnet-v3.1.103.2-SDK.tar.gz
/dotnet-v3.1.104-SDK.tar.gz
/dotnet-v3.1.105-SDK.tar.gz
/dotnet-v3.1.105-SDK-arm64.tar.gz
/dotnet-v3.1.105-SDK-x64.tar.gz
/dotnet-v3.1.106-SDK.tar.gz
/dotnet-v3.1.107-SDK.tar.gz
/dotnet-v3.1.108-SDK.tar.gz
/dotnet-v3.1.109-SDK.tar.gz
/dotnet-v3.1.110-SDK.tar.gz
/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

133
README.md Normal file
View File

@ -0,0 +1,133 @@
# Overview
This is the .NET Core 3.1 package for Fedora.
This package is maintained by the Fedora DotNet SIG (Special Interest
Group). You can find out more about the DotNet SIG at:
- https://fedoraproject.org/wiki/SIGs/DotNet
- https://fedoraproject.org/wiki/DotNet
- https://lists.fedoraproject.org/archives/list/dotnet-sig@lists.fedoraproject.org/
Please report any issues [using
bugzilla](https://bugzilla.redhat.com/enter_bug.cgi?product=Fedora&component=dotnet3.1).
# Specification
This package follows [package naming and contents suggested by
upstream](https://docs.microsoft.com/en-us/dotnet/core/build/distribution-packaging),
with one exception. It installs dotnet to `/usr/lib64/dotnet` (aka
`%{_libdir}`).
# Contributing
## General Changes
1. Fork the repo.
2. Checkout the forked repository.
- `git clone ssh://$USER@pkgs.fedoraproject.org/forks/$USER/rpms/dotnet3.1.git`
- `cd dotnet3.1`
3. Make your changes. Don't forget to add a changelog.
4. Do local builds.
- `fedpkg local`
5. Fix any errors that come up and rebuild until it works locally.
6. Do builds in koji.
- `fedpkg scratch-build --srpm`
8. Commit the changes to the git repo.
- `git add` any new patches
- `git remove` any now-unnecessary patches
- `git commit -a`
- `git push`
9. Create a pull request with your changes.
10. Once the tests in the pull-request pass, and reviewers are happy, do a real
build.
- `fedpkg build`
11. For non-rawhide releases, file updates using bodhi to ship the just-built
package out to users.
- https://bodhi.fedoraproject.org/updates/new
OR
- `fedpkg update`
## Updating to an new upstream release
1. Fork the repo.
2. Checkout the forked repository.
- `git clone ssh://$USER@pkgs.fedoraproject.org/forks/$USER/rpms/dotnet3.1.git`
- `cd dotnet3.1`
3. Build the new upstream source tarball. Update the versions in the
spec file. Add a changelog. This is generally automated by the
following.
- `./update-release <sdk-version> <runtime-version>`
If this fails because of compiler errors, you might have to figure
out a fix, then add the patch in `build-dotnet-tarball` script
rather than the spec file.
4. Do local builds.
- `fedpkg local`
5. Fix any errors that come up and rebuild until it works locally. Any
patches that are needed at this point should be added to the spec file.
6. Do builds in koji.
- `fedpkg scratch-build --srpm`
7. Upload the source archive to the Fedora look-aside cache.
- `fedpkg new-sources path-to-generated-dotnet-source-tarball.tar.gz`
8. Commit the changes to the git repo.
- `git add` any new patches
- `git remove` any now-unnecessary patches
- `git commit -a`
- `git push`
9. Create a pull request with your changes.
10. Once the tests in the pull-request pass, and reviewers are happy, do a real
build.
- `fedpkg build`
11. For non-rawhide releases, file updates using bodhi to ship the just-built
package out to users.
- https://bodhi.fedoraproject.org/updates/new
OR
- `fedpkg update`
# Testing
This package uses CI tests as defined in `tests/test.yml`. Creating a
pull-request or running a build will fire off tests and flag any issues. We have
enabled gating (via `gating.yaml`) on the tests. That prevents a build
that fails any test from being released until the failures are waived.
The tests themselves are contained in this external repository:
https://github.com/redhat-developer/dotnet-regular-tests/

View File

@ -1,58 +0,0 @@
--- a/src/settings.cmake
+++ b/src/settings.cmake
@@ -69,55 +69,10 @@
endif (CMAKE_SYSTEM_NAME STREQUAL Darwin)
endif ()
-function(strip_symbols targetName outputFilename)
- if(CLR_CMAKE_PLATFORM_UNIX)
- if(STRIP_SYMBOLS)
-
- # On the older version of cmake (2.8.12) used on Ubuntu 14.04 the TARGET_FILE
- # generator expression doesn't work correctly returning the wrong path and on
- # the newer cmake versions the LOCATION property isn't supported anymore.
- if(CMAKE_VERSION VERSION_EQUAL 3.0 OR CMAKE_VERSION VERSION_GREATER 3.0)
- set(strip_source_file $<TARGET_FILE:${targetName}>)
- else()
- get_property(strip_source_file TARGET ${targetName} PROPERTY LOCATION)
- endif()
-
- if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
- set(strip_destination_file ${strip_source_file}.dwarf)
-
- add_custom_command(
- TARGET ${targetName}
- POST_BUILD
- VERBATIM
- COMMAND ${DSYMUTIL} --flat --minimize ${strip_source_file}
- COMMAND ${STRIP} -u -r ${strip_source_file}
- COMMENT Stripping symbols from ${strip_source_file} into file ${strip_destination_file}
- )
- else(CMAKE_SYSTEM_NAME STREQUAL Darwin)
- set(strip_destination_file ${strip_source_file}.dbg)
-
- add_custom_command(
- TARGET ${targetName}
- POST_BUILD
- VERBATIM
- COMMAND ${OBJCOPY} --only-keep-debug ${strip_source_file} ${strip_destination_file}
- COMMAND ${OBJCOPY} --strip-unneeded ${strip_source_file}
- COMMAND ${OBJCOPY} --add-gnu-debuglink=${strip_destination_file} ${strip_source_file}
- COMMENT Stripping symbols from ${strip_source_file} into file ${strip_destination_file}
- )
- endif(CMAKE_SYSTEM_NAME STREQUAL Darwin)
-
- set(${outputFilename} ${strip_destination_file} PARENT_SCOPE)
- endif(STRIP_SYMBOLS)
- endif(CLR_CMAKE_PLATFORM_UNIX)
-endfunction()
-
function(install_symbols targetName destination_path)
if(WIN32)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/${targetName}.pdb DESTINATION ${destination_path})
else()
- strip_symbols(${targetName} strip_destination_file)
- install(FILES ${strip_destination_file} DESTINATION ${destination_path})
endif()
endfunction()

View File

@ -1,27 +0,0 @@
From e900fff68af76d51a59ac085b35ace76939bc007 Mon Sep 17 00:00:00 2001
From: Omair Majid <omajid@redhat.com>
Date: Tue, 18 Jan 2022 21:45:52 -0500
Subject: [PATCH] Disable Werror
This is so late in the release cycle that fixing warnings is just not
really worth it. The general approach is to fix the issues in the
development branches and disable warnings in the older release branches.
---
src/settings.cmake | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/settings.cmake b/src/settings.cmake
index ff1e04f9..5cc9b3ef 100644
--- a/src/settings.cmake
+++ b/src/settings.cmake
@@ -201,7 +201,6 @@ else()
# compiling with -std=c++11.
# add_compile_options(-Weverything)
endif()
- add_compile_options(-Werror)
add_compile_options(-Wno-missing-field-initializers)
add_compile_options(-Wno-unused-function)
add_compile_options(-Wno-unused-local-typedef)
--
2.34.1

View File

@ -1,42 +0,0 @@
From 3dd725eca0079e2b49821dfeb0ec1cb166cc7414 Mon Sep 17 00:00:00 2001
From: Omair Majid <omajid@redhat.com>
Date: Fri, 4 Oct 2019 19:29:53 -0400
Subject: [PATCH] Handle glibc sys/sysctl.h deprecation
glibc has deprecated sys/sysctl.h:
In file included from /coreclr/src/pal/src/misc/sysinfo.cpp:32:
/usr/include/sys/sysctl.h:21:2: error: "The <sys/sysctl.h> header is deprecated and will be removed." [-Werror,-W#warnings]
#warning "The <sys/sysctl.h> header is deprecated and will be removed."
^
1 error generated.
Fix that by preferring sysconf and only including sys/sysctl.h if
HAVE_SYSCONF is not true. This mirrors the order of the implementation
code in this file (sysinfo.cpp) which checks for HAVE_SYSCONF
before HAVE_SYSCTL.
Fixes #27008
---
src/pal/src/misc/sysinfo.cpp | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/pal/src/misc/sysinfo.cpp b/src/pal/src/misc/sysinfo.cpp
index e1c949e38d53..50ccf3a75e16 100644
--- a/src/pal/src/misc/sysinfo.cpp
+++ b/src/pal/src/misc/sysinfo.cpp
@@ -28,9 +28,12 @@ Revision History:
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#include <sys/types.h>
-#if HAVE_SYSCTL
+
+#if HAVE_SYSCONF
+// <unistd.h> already included above
+#elif HAVE_SYSCTL
#include <sys/sysctl.h>
-#elif !HAVE_SYSCONF
+#else
#error Either sysctl or sysconf is required for GetSystemInfo.
#endif

50
build-bootstrap-tarball Executable file
View File

@ -0,0 +1,50 @@
#!/bin/bash
set -euo pipefail
set -x
sdk_version=3.1.105
arch=$(uname -m)
if [[ $arch == "x86_64" ]]; then
arch=x64
elif [[ $arch == "aarch64" ]]; then
arch=arm64
fi
if rpm -qa | grep libunwind; then
echo "error: libunwind is installed. Not a good idea for bootstrapping."
exit 1
fi
if rpm -qa | grep dotnet ; then
echo "error: dotnet is installed. Not a good idea for bootstrapping."
exit 1
fi
if [ -d /usr/lib/dotnet ] || [ -d /usr/lib64/dotnet ] || [ -d /usr/share/dotnet ] ; then
echo "error: one of /usr/lib/dotnet /usr/lib64/dotnet or /usr/share/dotnet/ exists. Not a good idea for bootstrapping."
exit 1
fi
if command -v dotnet ; then
echo "error: dotnet is in $PATH. Not a good idea for bootstrapping."
exit 1
fi
if [ ! -d dotnet-source-build-tarball ]; then
if [ ! -d source-build ]; then
git clone https://github.com/dotnet/source-build
fi
pushd source-build
sed -i -e 's|cmakeargs -DCLR_CMAKE_USE_SYSTEM_LIBUNWIND=TRUE||' repos/coreclr.common.props
git clean -xdf
./build-source-tarball.sh ../dotnet-source-build-tarball/ -- -p:DownloadSourceBuildReferencePackagesTimeoutSeconds=100000
popd
fi
rm -rf dotnet-v${sdk_version}-SDK dotnet-v${sdk_version}-SDK.tar.gz
cp -a dotnet-source-build-tarball dotnet-v${sdk_version}-SDK
cp -a source-build/artifacts/$arch/Release/Private.SourceBuilt.Artifacts.*.tar.gz dotnet-v${sdk_version}-SDK/packages/archive/Private.SourceBuilt.Artifacts.*.tar.gz
tar czf dotnet-v${sdk_version}-SDK-$arch.tar.gz dotnet-v${sdk_version}-SDK

View File

@ -0,0 +1,12 @@
diff --git a/configurecompiler.cmake b/configurecompiler.cmake
index d769e82f57..4936c8b00d 100644
--- a/configurecompiler.cmake
+++ b/configurecompiler.cmake
@@ -474,6 +474,7 @@ if (CLR_CMAKE_PLATFORM_UNIX)
add_compile_options(-Wno-unused-variable)
add_compile_options(-Wno-unused-value)
add_compile_options(-Wno-unused-function)
+ add_compile_options(-Wno-error=misleading-indentation)
#These seem to indicate real issues
add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-Wno-invalid-offsetof>)

129
build-dotnet-tarball Executable file
View File

@ -0,0 +1,129 @@
#!/bin/bash
# Usage:
# build-dotnet-tarball <tag-from-source-build>
#
# Creates a source archive from a tag (or commit) at github.com/dotnet/source-build
# Source-build is a little strange, we need to clone it, check out the
# tag, build it and then create a tarball from the archive directory
# it creates. Also, it is likely that the source archive is only
# buildable on the OS it was initially created in.
set -euo pipefail
IFS=$'\n\t'
print_usage() {
echo "Usage:"
echo "$0 <tag-from-source-build>"
echo
echo "Creates a source archive from a tag at https://github.com/dotnet/source-build"
}
clean_dotnet_cache() {
rm -rf ~/.aspnet ~/.dotnet/ ~/.nuget/ ~/.local/share/NuGet ~/.templateengine
rm -rf /tmp/NuGet /tmp/NuGetScratch /tmp/.NETCore* /tmp/.NETStandard* /tmp/.dotnet /tmp/dotnet.* /tmp/clr-debug-pipe* /tmp/Razor-Server /tmp/CoreFxPipe* /tmp/VBCSCompiler /tmp/.NETFramework*
}
function runtime_id {
declare -A archmap
archmap=(
["aarch64"]="arm64"
["amd64"]="x64"
["armv8l"]="arm"
["i686"]="x86"
["i386"]="x86"
["x86_64"]="x64"
)
arch=${archmap["$(uname -m)"]}
source /etc/os-release
case "${ID}" in
# Remove the RHEL minor version
rhel) rid_version=${VERSION_ID%.*} ;;
*) rid_version=${VERSION_ID} ;;
esac
echo "${ID}.${rid_version}-${arch}"
}
positional_args=()
while [[ "$#" -gt 0 ]]; do
arg="${1}"
case "${arg}" in
-h|--help)
print_usage
exit 0
;;
*)
positional_args+=("$1")
shift
;;
esac
done
tag=${positional_args[0]:-}
if [[ -z ${tag} ]]; then
echo "error: missing tag to build"
exit 1
fi
set -x
dir_name="dotnet-${tag}"
unmodified_tarball_name="${dir_name}-original"
tarball_name="${dir_name}"
if [ -f "${tarball_name}.tar.gz" ]; then
echo "error: ${tarball_name}.tar.gz already exists"
exit 1
fi
if [ ! -f "${unmodified_tarball_name}.tar.gz" ]; then
temp_dir=$(mktemp -d -p "$(pwd)")
pushd "${temp_dir}"
git clone https://github.com/dotnet/source-build
pushd source-build
git checkout "${tag}"
git submodule update --init --recursive
clean_dotnet_cache
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
./build-source-tarball.sh "${unmodified_tarball_name}" --skip-build
popd
popd
tar czf "${unmodified_tarball_name}.tar.gz" -C "${temp_dir}/source-build" "${unmodified_tarball_name}"
rm -rf "${temp_dir}"
fi
rm -rf "${tarball_name}"
tar xf "${unmodified_tarball_name}.tar.gz"
mv "${unmodified_tarball_name}" "${tarball_name}"
pushd "${tarball_name}"
# Remove files with funny licenses, crypto implementations and other
# not-very-useful artifacts to reduce tarball size
find -type f -iname '*.tar.gz' -delete
rm -rf .dotnet
rm -r src/aspnetcore.*/src/SignalR/clients/java/signalr/gradle*
find src/aspnetcore.*/src -type d -name samples -print0 | xargs -0 rm -r
rm -r src/NuGet.Client.*/test/EndToEnd/ProjectTemplates/NetCoreWebApplication1.0.zip
find src/coreclr.*/ -depth -name tests -print0 | xargs -0 rm -r
popd
tar czf "${tarball_name}.tar.gz" "${tarball_name}"

19
core-setup-gcc11.patch Normal file
View File

@ -0,0 +1,19 @@
diff --git a/src/corehost/cli/test/nativehost/host_context_test.cpp b/src/corehost/cli/test/nativehost/host_context_test.cpp
index e6dc9f6d8..d42c0e0f2 100644
--- a/src/corehost/cli/test/nativehost/host_context_test.cpp
+++ b/src/corehost/cli/test/nativehost/host_context_test.cpp
@@ -11,6 +11,7 @@
#include <corehost_context_contract.h>
#include "host_context_test.h"
#include <utils.h>
+#include <thread>
namespace
{
@@ -539,4 +540,4 @@ bool host_context_test::load_assembly_and_get_function_pointer(
hostfxr_exports hostfxr{ hostfxr_path };
return load_assembly_and_get_function_pointer(hostfxr, config_path, argc, argv, config_log_prefix, test_output);
-}
\ No newline at end of file
+}

View File

@ -0,0 +1,402 @@
From 29e17d8d2ccbca07c423e3089a6d5ae8a1c9cb6e Mon Sep 17 00:00:00 2001
From: Yichao Yu <yyc1992@gmail.com>
Date: Tue, 31 Mar 2020 00:43:32 -0400
Subject: [PATCH] Fix compilation with -fno-common.
Making all other archs consistent with IA64 which should not have this problem.
Also move the FIXME to the correct place.
Also add some minimum comments about this...
---
src/aarch64/Ginit.c | 15 +++++++--------
src/arm/Ginit.c | 15 +++++++--------
src/coredump/_UPT_get_dyn_info_list_addr.c | 5 +++++
src/hppa/Ginit.c | 15 +++++++--------
src/ia64/Ginit.c | 1 +
src/mi/Gfind_dynamic_proc_info.c | 1 +
src/mips/Ginit.c | 15 +++++++--------
src/ppc32/Ginit.c | 11 +++++++----
src/ppc64/Ginit.c | 11 +++++++----
src/ptrace/_UPT_get_dyn_info_list_addr.c | 5 +++++
src/s390x/Ginit.c | 15 +++++++--------
src/sh/Ginit.c | 15 +++++++--------
src/tilegx/Ginit.c | 15 +++++++--------
src/x86/Ginit.c | 15 +++++++--------
src/x86_64/Ginit.c | 15 +++++++--------
15 files changed, 89 insertions(+), 80 deletions(-)
diff --git a/src/pal/src/libunwind/src/aarch64/Ginit.c b/src/pal/src/libunwind/src/aarch64/Ginit.c
index dec235c82..35389762f 100644
--- a/src/pal/src/libunwind/src/aarch64/Ginit.c
+++ b/src/pal/src/libunwind/src/aarch64/Ginit.c
@@ -61,13 +61,6 @@ tdep_uc_addr (unw_tdep_context_t *uc, int reg)
# endif /* UNW_LOCAL_ONLY */
-HIDDEN unw_dyn_info_list_t _U_dyn_info_list;
-
-/* XXX fix me: there is currently no way to locate the dyn-info list
- by a remote unwinder. On ia64, this is done via a special
- unwind-table entry. Perhaps something similar can be done with
- DWARF2 unwind info. */
-
static void
put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg)
{
@@ -78,7 +71,13 @@ static int
get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
void *arg)
{
- *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list;
+#ifndef UNW_LOCAL_ONLY
+# pragma weak _U_dyn_info_list_addr
+ if (!_U_dyn_info_list_addr)
+ return -UNW_ENOINFO;
+#endif
+ // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so.
+ *dyn_info_list_addr = _U_dyn_info_list_addr ();
return 0;
}
diff --git a/src/pal/src/libunwind/src/arm/Ginit.c b/ssrc/pal/src/libunwind/src/arm/Ginit.c
index 2720d063a..0bac0d72d 100644
--- a/src/pal/src/libunwind/src/arm/Ginit.c
+++ b/src/pal/src/libunwind/src/arm/Ginit.c
@@ -57,18 +57,17 @@ tdep_uc_addr (unw_tdep_context_t *uc, int reg)
# endif /* UNW_LOCAL_ONLY */
-HIDDEN unw_dyn_info_list_t _U_dyn_info_list;
-
-/* XXX fix me: there is currently no way to locate the dyn-info list
- by a remote unwinder. On ia64, this is done via a special
- unwind-table entry. Perhaps something similar can be done with
- DWARF2 unwind info. */
-
static int
get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
void *arg)
{
- *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list;
+#ifndef UNW_LOCAL_ONLY
+# pragma weak _U_dyn_info_list_addr
+ if (!_U_dyn_info_list_addr)
+ return -UNW_ENOINFO;
+#endif
+ // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so.
+ *dyn_info_list_addr = _U_dyn_info_list_addr ();
return 0;
}
diff --git a/src/pal/src/libunwind/src/coredump/_UPT_get_dyn_info_list_addr.c b/src/pal/src/libunwind/src/coredump/_UPT_get_dyn_info_list_addr.c
index 0d1190556..739ed0569 100644
--- a/src/pal/src/libunwind/src/coredump/_UPT_get_dyn_info_list_addr.c
+++ b/src/pal/src/libunwind/src/coredump/_UPT_get_dyn_info_list_addr.c
@@ -74,6 +74,11 @@ get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg,
#else
+/* XXX fix me: there is currently no way to locate the dyn-info list
+ by a remote unwinder. On ia64, this is done via a special
+ unwind-table entry. Perhaps something similar can be done with
+ DWARF2 unwind info. */
+
static inline int
get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg,
int *countp)
diff --git a/src/pal/src/libunwind/src/hppa/Ginit.c b/src/pal/src/libunwind/src/hppa/Ginit.c
index 461e4b93d..265455a68 100644
--- a/src/pal/src/libunwind/src/hppa/Ginit.c
+++ b/src/pal/src/libunwind/src/hppa/Ginit.c
@@ -64,13 +64,6 @@ _Uhppa_uc_addr (ucontext_t *uc, int reg)
# endif /* UNW_LOCAL_ONLY */
-HIDDEN unw_dyn_info_list_t _U_dyn_info_list;
-
-/* XXX fix me: there is currently no way to locate the dyn-info list
- by a remote unwinder. On ia64, this is done via a special
- unwind-table entry. Perhaps something similar can be done with
- DWARF2 unwind info. */
-
static void
put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg)
{
@@ -81,7 +74,13 @@ static int
get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
void *arg)
{
- *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list;
+#ifndef UNW_LOCAL_ONLY
+# pragma weak _U_dyn_info_list_addr
+ if (!_U_dyn_info_list_addr)
+ return -UNW_ENOINFO;
+#endif
+ // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so.
+ *dyn_info_list_addr = _U_dyn_info_list_addr ();
return 0;
}
diff --git a/src/pal/src/libunwind/src/ia64/Ginit.c b/src/pal/src/libunwind/src/ia64/Ginit.c
index b09a2ad57..8601bb3ca 100644
--- a/src/pal/src/libunwind/src/ia64/Ginit.c
+++ b/src/pal/src/libunwind/src/ia64/Ginit.c
@@ -68,6 +68,7 @@ get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
if (!_U_dyn_info_list_addr)
return -UNW_ENOINFO;
#endif
+ // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so.
*dyn_info_list_addr = _U_dyn_info_list_addr ();
return 0;
}
diff --git a/src/pal/src/libunwind/src/mi/Gfind_dynamic_proc_info.c b/src/pal/src/libunwind/src/mi/Gfind_dynamic_proc_info.c
index 98d350128..2e7c62e5e 100644
--- a/src/pal/src/libunwind/src/mi/Gfind_dynamic_proc_info.c
+++ b/src/pal/src/libunwind/src/mi/Gfind_dynamic_proc_info.c
@@ -49,6 +49,7 @@ local_find_proc_info (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
return -UNW_ENOINFO;
#endif
+ // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so.
list = (unw_dyn_info_list_t *) (uintptr_t) _U_dyn_info_list_addr ();
for (di = list->first; di; di = di->next)
if (ip >= di->start_ip && ip < di->end_ip)
diff --git a/src/pal/src/libunwind/src/mips/Ginit.c b/src/pal/src/libunwind/src/mips/Ginit.c
index 3df170c75..bf7a8f5a8 100644
--- a/src/pal/src/libunwind/src/mips/Ginit.c
+++ b/src/pal/src/libunwind/src/mips/Ginit.c
@@ -69,13 +69,6 @@ tdep_uc_addr (ucontext_t *uc, int reg)
# endif /* UNW_LOCAL_ONLY */
-HIDDEN unw_dyn_info_list_t _U_dyn_info_list;
-
-/* XXX fix me: there is currently no way to locate the dyn-info list
- by a remote unwinder. On ia64, this is done via a special
- unwind-table entry. Perhaps something similar can be done with
- DWARF2 unwind info. */
-
static void
put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg)
{
@@ -86,7 +79,13 @@ static int
get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
void *arg)
{
- *dyn_info_list_addr = (unw_word_t) (intptr_t) &_U_dyn_info_list;
+#ifndef UNW_LOCAL_ONLY
+# pragma weak _U_dyn_info_list_addr
+ if (!_U_dyn_info_list_addr)
+ return -UNW_ENOINFO;
+#endif
+ // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so.
+ *dyn_info_list_addr = _U_dyn_info_list_addr ();
return 0;
}
diff --git a/src/pal/src/libunwind/src/ppc32/Ginit.c b/src/pal/src/libunwind/src/ppc32/Ginit.c
index ba302448a..7b4545580 100644
--- a/src/pal/src/libunwind/src/ppc32/Ginit.c
+++ b/src/pal/src/libunwind/src/ppc32/Ginit.c
@@ -91,9 +91,6 @@ tdep_uc_addr (ucontext_t *uc, int reg)
# endif /* UNW_LOCAL_ONLY */
-HIDDEN unw_dyn_info_list_t _U_dyn_info_list;
-
-
static void
put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg)
{
@@ -104,7 +101,13 @@ static int
get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
void *arg)
{
- *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list;
+#ifndef UNW_LOCAL_ONLY
+# pragma weak _U_dyn_info_list_addr
+ if (!_U_dyn_info_list_addr)
+ return -UNW_ENOINFO;
+#endif
+ // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so.
+ *dyn_info_list_addr = _U_dyn_info_list_addr ();
return 0;
}
diff --git a/src/pal/src/libunwind/src/ppc64/Ginit.c b/src/pal/src/libunwind/src/ppc64/Ginit.c
index 4c88cd6e7..7bfb395a7 100644
--- a/src/pal/src/libunwind/src/ppc64/Ginit.c
+++ b/src/pal/src/libunwind/src/ppc64/Ginit.c
@@ -95,9 +95,6 @@ tdep_uc_addr (ucontext_t *uc, int reg)
# endif /* UNW_LOCAL_ONLY */
-HIDDEN unw_dyn_info_list_t _U_dyn_info_list;
-
-
static void
put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg)
{
@@ -108,7 +105,13 @@ static int
get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
void *arg)
{
- *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list;
+#ifndef UNW_LOCAL_ONLY
+# pragma weak _U_dyn_info_list_addr
+ if (!_U_dyn_info_list_addr)
+ return -UNW_ENOINFO;
+#endif
+ // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so.
+ *dyn_info_list_addr = _U_dyn_info_list_addr ();
return 0;
}
diff --git a/src/pal/src/libunwind/src/ptrace/_UPT_get_dyn_info_list_addr.c b/src/pal/src/libunwind/src/ptrace/_UPT_get_dyn_info_list_addr.c
index cc5ed0441..16671d453 100644
--- a/src/pal/src/libunwind/src/ptrace/_UPT_get_dyn_info_list_addr.c
+++ b/src/pal/src/libunwind/src/ptrace/_UPT_get_dyn_info_list_addr.c
@@ -71,6 +71,11 @@ get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg,
#else
+/* XXX fix me: there is currently no way to locate the dyn-info list
+ by a remote unwinder. On ia64, this is done via a special
+ unwind-table entry. Perhaps something similar can be done with
+ DWARF2 unwind info. */
+
static inline int
get_list_addr (unw_addr_space_t as, unw_word_t *dil_addr, void *arg,
int *countp)
diff --git a/src/pal/src/libunwind/src/sh/Ginit.c b/src/pal/src/libunwind/src/sh/Ginit.c
index 52988a721..9fe96d2bd 100644
--- a/src/pal/src/libunwind/src/sh/Ginit.c
+++ b/src/pal/src/libunwind/src/sh/Ginit.c
@@ -58,13 +58,6 @@ tdep_uc_addr (ucontext_t *uc, int reg)
# endif /* UNW_LOCAL_ONLY */
-HIDDEN unw_dyn_info_list_t _U_dyn_info_list;
-
-/* XXX fix me: there is currently no way to locate the dyn-info list
- by a remote unwinder. On ia64, this is done via a special
- unwind-table entry. Perhaps something similar can be done with
- DWARF2 unwind info. */
-
static void
put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg)
{
@@ -75,7 +68,13 @@ static int
get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
void *arg)
{
- *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list;
+#ifndef UNW_LOCAL_ONLY
+# pragma weak _U_dyn_info_list_addr
+ if (!_U_dyn_info_list_addr)
+ return -UNW_ENOINFO;
+#endif
+ // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so.
+ *dyn_info_list_addr = _U_dyn_info_list_addr ();
return 0;
}
diff --git a/src/pal/src/libunwind/src/tilegx/Ginit.c b/src/pal/src/libunwind/src/tilegx/Ginit.c
index 7564a558b..925e64132 100644
--- a/src/pal/src/libunwind/src/tilegx/Ginit.c
+++ b/src/pal/src/libunwind/src/tilegx/Ginit.c
@@ -64,13 +64,6 @@ tdep_uc_addr (ucontext_t *uc, int reg)
# endif /* UNW_LOCAL_ONLY */
-HIDDEN unw_dyn_info_list_t _U_dyn_info_list;
-
-/* XXX fix me: there is currently no way to locate the dyn-info list
- by a remote unwinder. On ia64, this is done via a special
- unwind-table entry. Perhaps something similar can be done with
- DWARF2 unwind info. */
-
static void
put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg)
{
@@ -81,7 +74,13 @@ static int
get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
void *arg)
{
- *dyn_info_list_addr = (unw_word_t) (intptr_t) &_U_dyn_info_list;
+#ifndef UNW_LOCAL_ONLY
+# pragma weak _U_dyn_info_list_addr
+ if (!_U_dyn_info_list_addr)
+ return -UNW_ENOINFO;
+#endif
+ // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so.
+ *dyn_info_list_addr = _U_dyn_info_list_addr ();
return 0;
}
diff --git a/src/pal/src/libunwind/src/x86/Ginit.c b/src/pal/src/libunwind/src/x86/Ginit.c
index f6b8dc27d..3cec74a21 100644
--- a/src/pal/src/libunwind/src/x86/Ginit.c
+++ b/src/pal/src/libunwind/src/x86/Ginit.c
@@ -54,13 +54,6 @@ tdep_uc_addr (ucontext_t *uc, int reg)
# endif /* UNW_LOCAL_ONLY */
-HIDDEN unw_dyn_info_list_t _U_dyn_info_list;
-
-/* XXX fix me: there is currently no way to locate the dyn-info list
- by a remote unwinder. On ia64, this is done via a special
- unwind-table entry. Perhaps something similar can be done with
- DWARF2 unwind info. */
-
static void
put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg)
{
@@ -71,7 +64,13 @@ static int
get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
void *arg)
{
- *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list;
+#ifndef UNW_LOCAL_ONLY
+# pragma weak _U_dyn_info_list_addr
+ if (!_U_dyn_info_list_addr)
+ return -UNW_ENOINFO;
+#endif
+ // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so.
+ *dyn_info_list_addr = _U_dyn_info_list_addr ();
return 0;
}
diff --git a/src/pal/src/libunwind/src/x86_64/Ginit.c b/src/pal/src/libunwind/src/x86_64/Ginit.c
index a865d3385..fd8d418b1 100644
--- a/src/pal/src/libunwind/src/x86_64/Ginit.c
+++ b/src/pal/src/libunwind/src/x86_64/Ginit.c
@@ -49,13 +49,6 @@ static struct unw_addr_space local_addr_space;
unw_addr_space_t unw_local_addr_space = &local_addr_space;
-HIDDEN unw_dyn_info_list_t _U_dyn_info_list;
-
-/* XXX fix me: there is currently no way to locate the dyn-info list
- by a remote unwinder. On ia64, this is done via a special
- unwind-table entry. Perhaps something similar can be done with
- DWARF2 unwind info. */
-
static void
put_unwind_info (unw_addr_space_t as, unw_proc_info_t *proc_info, void *arg)
{
@@ -66,7 +59,13 @@ static int
get_dyn_info_list_addr (unw_addr_space_t as, unw_word_t *dyn_info_list_addr,
void *arg)
{
- *dyn_info_list_addr = (unw_word_t) &_U_dyn_info_list;
+#ifndef UNW_LOCAL_ONLY
+# pragma weak _U_dyn_info_list_addr
+ if (!_U_dyn_info_list_addr)
+ return -UNW_ENOINFO;
+#endif
+ // Access the `_U_dyn_info_list` from `LOCAL_ONLY` library, i.e. libunwind.so.
+ *dyn_info_list_addr = _U_dyn_info_list_addr ();
return 0;
}

View File

@ -0,0 +1,391 @@
From 2b2273ea4ea1c28472fa0d6ad2ffeb6374500550 Mon Sep 17 00:00:00 2001
From: Omair Majid <omajid@redhat.com>
Date: Wed, 23 Oct 2019 17:45:59 -0400
Subject: [PATCH 1/2] Add cgroup v2 support to Interop.cgroups
Fix up code to adjust cgroup v1 assumptions and check cgroup v2 paths,
locations and values.
Continue using the older cgroup v1 terminology for APIs.
---
.../Interop/Linux/cgroups/Interop.cgroups.cs | 116 ++++++++++++++----
src/Common/tests/Common.Tests.csproj | 4 +
.../tests/Tests/Interop/cgroupsTests.cs | 107 ++++++++++++++++
.../tests/DescriptionNameTests.cs | 2 +-
4 files changed, 206 insertions(+), 23 deletions(-)
create mode 100644 src/Common/tests/Tests/Interop/cgroupsTests.cs
diff --git a/src/Common/src/Interop/Linux/cgroups/Interop.cgroups.cs b/src/Common/src/Interop/Linux/cgroups/Interop.cgroups.cs
index 0ffd4d7b7c03..186fe0516c5b 100644
--- a/src/Common/src/Interop/Linux/cgroups/Interop.cgroups.cs
+++ b/src/Common/src/Interop/Linux/cgroups/Interop.cgroups.cs
@@ -9,17 +9,22 @@
internal static partial class Interop
{
+ /// <summary>Provides access to some cgroup (v1 and v2) features</summary>
internal static partial class cgroups
{
+ // For cgroup v1, see https://www.kernel.org/doc/Documentation/cgroup-v1/
+ // For cgroup v2, see https://www.kernel.org/doc/Documentation/cgroup-v2.txt
+
+ /// <summary>The version of cgroup that's being used </summary>
+ internal enum CGroupVersion { None, CGroup1, CGroup2 };
+
/// <summary>Path to mountinfo file in procfs for the current process.</summary>
private const string ProcMountInfoFilePath = "/proc/self/mountinfo";
/// <summary>Path to cgroup directory in procfs for the current process.</summary>
private const string ProcCGroupFilePath = "/proc/self/cgroup";
- /// <summary>Path to the found cgroup location, or null if it couldn't be found.</summary>
- internal static readonly string s_cgroupMemoryPath = FindCGroupPath("memory");
- /// <summary>Path to the found cgroup memory limit_in_bytes path, or null if it couldn't be found.</summary>
- private static readonly string s_cgroupMemoryLimitPath = s_cgroupMemoryPath != null ? s_cgroupMemoryPath + "/memory.limit_in_bytes" : null;
+ /// <summary>Path to the found cgroup memory limit path, or null if it couldn't be found.</summary>
+ internal static readonly string s_cgroupMemoryLimitPath = FindCGroupMemoryLimitPath();
/// <summary>Tries to read the memory limit from the cgroup memory location.</summary>
/// <param name="limit">The read limit, or 0 if it couldn't be read.</param>
@@ -42,7 +47,7 @@ public static bool TryGetMemoryLimit(out ulong limit)
/// <param name="path">The path to the file to parse.</param>
/// <param name="result">The parsed result, or 0 if it couldn't be parsed.</param>
/// <returns>true if the value was read successfully; otherwise, false.</returns>
- private static bool TryReadMemoryValueFromFile(string path, out ulong result)
+ internal static bool TryReadMemoryValueFromFile(string path, out ulong result)
{
if (File.Exists(path))
{
@@ -79,6 +84,11 @@ private static bool TryReadMemoryValueFromFile(string path, out ulong result)
result = checked(ulongValue * multiplier);
return true;
}
+
+ // 'max' is also a possible valid value
+ //
+ // Treat this as 'no memory limit' and let the caller
+ // fallback to reading the real limit via other means
}
catch (Exception e)
{
@@ -90,12 +100,35 @@ private static bool TryReadMemoryValueFromFile(string path, out ulong result)
return false;
}
+ /// <summary>Find the cgroup memory limit path.</summary>
+ /// <returns>The limit path if found; otherwise, null.</returns>
+ private static string FindCGroupMemoryLimitPath()
+ {
+ string cgroupMemoryPath = FindCGroupPath("memory", out CGroupVersion version);
+ if (cgroupMemoryPath != null)
+ {
+ if (version == CGroupVersion.CGroup1)
+ {
+ return cgroupMemoryPath + "/memory.limit_in_bytes";
+ }
+
+ if (version == CGroupVersion.CGroup2)
+ {
+ // 'memory.high' is a soft limit; the process may get throttled
+ // 'memory.max' is where OOM killer kicks in
+ return cgroupMemoryPath + "/memory.max";
+ }
+ }
+
+ return null;
+ }
+
/// <summary>Find the cgroup path for the specified subsystem.</summary>
/// <param name="subsystem">The subsystem, e.g. "memory".</param>
/// <returns>The cgroup path if found; otherwise, null.</returns>
- private static string FindCGroupPath(string subsystem)
+ private static string FindCGroupPath(string subsystem, out CGroupVersion version)
{
- if (TryFindHierarchyMount(subsystem, out string hierarchyRoot, out string hierarchyMount) &&
+ if (TryFindHierarchyMount(subsystem, out version, out string hierarchyRoot, out string hierarchyMount) &&
TryFindCGroupPathForSubsystem(subsystem, out string cgroupPathRelativeToMount))
{
// For a host cgroup, we need to append the relative path.
@@ -113,19 +146,24 @@ private static string FindCGroupPath(string subsystem)
/// <param name="root">The path of the directory in the filesystem which forms the root of this mount; null if not found.</param>
/// <param name="path">The path of the mount point relative to the process's root directory; null if not found.</param>
/// <returns>true if the mount was found; otherwise, null.</returns>
- private static bool TryFindHierarchyMount(string subsystem, out string root, out string path)
+ private static bool TryFindHierarchyMount(string subsystem, out CGroupVersion version, out string root, out string path)
{
- if (File.Exists(ProcMountInfoFilePath))
+ return TryFindHierarchyMount(ProcMountInfoFilePath, subsystem, out version, out root, out path);
+ }
+
+ internal static bool TryFindHierarchyMount(string mountInfoFilePath, string subsystem, out CGroupVersion version, out string root, out string path)
+ {
+ if (File.Exists(mountInfoFilePath))
{
try
{
- using (var reader = new StreamReader(ProcMountInfoFilePath))
+ using (var reader = new StreamReader(mountInfoFilePath))
{
string line;
while ((line = reader.ReadLine()) != null)
{
// Look for an entry that has cgroup as the "filesystem type"
- // and that has options containing the specified subsystem.
+ // and, for cgroup1, that has options containing the specified subsystem
// See man page for /proc/[pid]/mountinfo for details, e.g.:
// (1)(2)(3) (4) (5) (6) (7) (8) (9) (10) (11)
// 36 35 98:0 /mnt1 /mnt2 rw,noatime master:1 - ext3 /dev/root rw,errors=continue
@@ -148,17 +186,35 @@ private static bool TryFindHierarchyMount(string subsystem, out string root, out
continue;
}
- if (postSeparatorlineParts[0] != "cgroup" ||
- Array.IndexOf(postSeparatorlineParts[2].Split(','), subsystem) < 0)
+ bool validCGroup1Entry = ((postSeparatorlineParts[0] == "cgroup") &&
+ (Array.IndexOf(postSeparatorlineParts[2].Split(','), subsystem) >= 0));
+ bool validCGroup2Entry = postSeparatorlineParts[0] == "cgroup2";
+
+ if (!validCGroup1Entry && !validCGroup2Entry)
{
// Not the relevant entry.
continue;
}
- // Found the relevant entry. Extract the mount root and path.
+ // Found the relevant entry. Extract the cgroup version, mount root and path.
+ switch (postSeparatorlineParts[0])
+ {
+ case "cgroup":
+ version = CGroupVersion.CGroup1;
+ break;
+ case "cgroup2":
+ version = CGroupVersion.CGroup2;
+ break;
+ default:
+ version = CGroupVersion.None;
+ Debug.Fail($"invalid value for CGroupVersion \"{postSeparatorlineParts[0]}\"");
+ break;
+ }
+
string[] lineParts = line.Substring(0, endOfOptionalFields).Split(' ');
root = lineParts[3];
path = lineParts[4];
+
return true;
}
}
@@ -169,6 +225,7 @@ private static bool TryFindHierarchyMount(string subsystem, out string root, out
}
}
+ version = CGroupVersion.None;
root = null;
path = null;
return false;
@@ -180,27 +237,42 @@ private static bool TryFindHierarchyMount(string subsystem, out string root, out
/// <returns></returns>
private static bool TryFindCGroupPathForSubsystem(string subsystem, out string path)
{
- if (File.Exists(ProcCGroupFilePath))
+ return TryFindCGroupPathForSubsystem(ProcCGroupFilePath, subsystem, out path);
+ }
+
+ internal static bool TryFindCGroupPathForSubsystem(string procCGroupFilePath, string subsystem, out string path)
+ {
+ if (File.Exists(procCGroupFilePath))
{
try
{
- using (var reader = new StreamReader(ProcCGroupFilePath))
+ using (var reader = new StreamReader(procCGroupFilePath))
{
string line;
while ((line = reader.ReadLine()) != null)
{
- // Find the first entry that has the subsystem listed in its controller
- // list. See man page for cgroups for /proc/[pid]/cgroups format, e.g:
- // hierarchy-ID:controller-list:cgroup-path
- // 5:cpuacct,cpu,cpuset:/daemons
-
string[] lineParts = line.Split(':');
+
if (lineParts.Length != 3)
{
// Malformed line.
continue;
}
+ // cgroup v2: Find the first entry that matches the cgroup v2 hierarchy:
+ // 0::$PATH
+
+ if ((lineParts[0] == "0") && (string.Empty == lineParts[1]))
+ {
+ path = lineParts[2];
+ return true;
+ }
+
+ // cgroup v1: Find the first entry that has the subsystem listed in its controller
+ // list. See man page for cgroups for /proc/[pid]/cgroups format, e.g:
+ // hierarchy-ID:controller-list:cgroup-path
+ // 5:cpuacct,cpu,cpuset:/daemons
+
if (Array.IndexOf(lineParts[1].Split(','), subsystem) < 0)
{
// Not the relevant entry.
@@ -214,7 +286,7 @@ private static bool TryFindCGroupPathForSubsystem(string subsystem, out string p
}
catch (Exception e)
{
- Debug.Fail($"Failed to read or parse \"{ProcMountInfoFilePath}\": {e}");
+ Debug.Fail($"Failed to read or parse \"{procCGroupFilePath}\": {e}");
}
}
diff --git a/src/Common/tests/Common.Tests.csproj b/src/Common/tests/Common.Tests.csproj
index a189d856348b..979c8dd7fbe6 100644
--- a/src/Common/tests/Common.Tests.csproj
+++ b/src/Common/tests/Common.Tests.csproj
@@ -12,6 +12,9 @@
<Compile Include="$(CommonTestPath)\System\Security\Cryptography\ByteUtils.cs">
<Link>Common\System\Security\Cryptography\ByteUtils.cs</Link>
</Compile>
+ <Compile Include="$(CommonPath)\Interop\Linux\cgroups\Interop.cgroups.cs">
+ <Link>Common\Interop\Linux\cgroups\Interop.cgroups.cs</Link>
+ </Compile>
<Compile Include="$(CommonPath)\Interop\Linux\procfs\Interop.ProcFsStat.cs">
<Link>Common\Interop\Linux\procfs\Interop.ProcFsStat.cs</Link>
</Compile>
@@ -69,6 +72,7 @@
<Compile Include="$(CommonPath)\CoreLib\System\PasteArguments.cs">
<Link>Common\CoreLib\System\PasteArguments.cs</Link>
</Compile>
+ <Compile Include="Tests\Interop\cgroupsTests.cs" />
<Compile Include="Tests\Interop\procfsTests.cs" />
<Compile Include="Tests\System\CharArrayHelpersTests.cs" />
<Compile Include="Tests\System\IO\PathInternal.Tests.cs" />
diff --git a/src/Common/tests/Tests/Interop/cgroupsTests.cs b/src/Common/tests/Tests/Interop/cgroupsTests.cs
new file mode 100644
index 000000000000..f16d9242879c
--- /dev/null
+++ b/src/Common/tests/Tests/Interop/cgroupsTests.cs
@@ -0,0 +1,107 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System;
+using System.IO;
+using System.Text;
+using Xunit;
+
+namespace Common.Tests
+{
+ public class cgroupsTests
+ {
+ [Theory]
+ [InlineData(true, "0", 0)]
+ [InlineData(false, "max", 0)]
+ [InlineData(true, "1k", 1024)]
+ [InlineData(true, "1K", 1024)]
+ public static void ValidateTryReadMemoryValue(bool expectedResult, string valueText, ulong expectedValue)
+ {
+ string path = Path.GetTempFileName();
+ try
+ {
+ File.WriteAllText(path, valueText);
+
+ bool result = Interop.cgroups.TryReadMemoryValueFromFile(path, out ulong val);
+
+ Assert.Equal(expectedResult, result);
+ if (result)
+ {
+ Assert.Equal(expectedValue, val);
+ }
+ }
+ finally
+ {
+ File.Delete(path);
+ }
+ }
+
+ [Theory]
+ [InlineData(false, "0 0 0:0 / /foo ignore ignore - overlay overlay ignore", "ignore", 0, "/", "/")]
+ [InlineData(true, "0 0 0:0 / /foo ignore ignore - cgroup2 cgroup2 ignore", "ignore", 2, "/", "/foo")]
+ [InlineData(true, "0 0 0:0 / /foo ignore ignore - cgroup2 cgroup2 ignore", "memory", 2, "/", "/foo")]
+ [InlineData(true, "0 0 0:0 / /foo ignore ignore - cgroup2 cgroup2 ignore", "cpu", 2, "/", "/foo")]
+ [InlineData(true, "0 0 0:0 / /foo ignore - cgroup2 cgroup2 ignore", "cpu", 2, "/", "/foo")]
+ [InlineData(true, "0 0 0:0 / /foo ignore ignore ignore - cgroup2 cgroup2 ignore", "cpu", 2, "/", "/foo")]
+ [InlineData(true, "0 0 0:0 / /foo-with-dashes ignore ignore - cgroup2 cgroup2 ignore", "ignore", 2, "/", "/foo-with-dashes")]
+ [InlineData(true, "0 0 0:0 / /foo ignore ignore - cgroup cgroup memory", "memory", 1, "/", "/foo")]
+ [InlineData(true, "0 0 0:0 / /foo-with-dashes ignore ignore - cgroup cgroup memory", "memory", 1, "/", "/foo-with-dashes")]
+ [InlineData(true, "0 0 0:0 / /foo ignore ignore - cgroup cgroup cpu,memory", "memory", 1, "/", "/foo")]
+ [InlineData(true, "0 0 0:0 / /foo ignore ignore - cgroup cgroup memory,cpu", "memory", 1, "/", "/foo")]
+ [InlineData(false, "0 0 0:0 / /foo ignore ignore - cgroup cgroup cpu", "memory", 0, "/", "/foo")]
+ public static void ParseValidateMountInfo(bool found, string procSelfMountInfoText, string subsystem, int expectedVersion, string expectedRoot, string expectedMount)
+ {
+ string path = Path.GetTempFileName();
+ try
+ {
+ File.WriteAllText(path, procSelfMountInfoText);
+
+ bool result = Interop.cgroups.TryFindHierarchyMount(path, subsystem, out Interop.cgroups.CGroupVersion version, out string root, out string mount);
+
+ Assert.Equal(found, result);
+ if (found)
+ {
+ Assert.Equal(expectedVersion, (int)version);
+ Assert.Equal(expectedRoot, root);
+ Assert.Equal(expectedMount, mount);
+ }
+ }
+ finally
+ {
+ File.Delete(path);
+ }
+ }
+
+ [Theory]
+ [InlineData(true, "0::/foo", "ignore", "/foo")]
+ [InlineData(true, "0::/bar", "ignore", "/bar")]
+ [InlineData(true, "0::frob", "ignore", "frob")]
+ [InlineData(false, "1::frob", "ignore", "ignore")]
+ [InlineData(true, "1:foo:bar", "foo", "bar")]
+ [InlineData(true, "2:foo:bar", "foo", "bar")]
+ [InlineData(false, "2:foo:bar", "bar", "ignore")]
+ [InlineData(true, "1:foo:bar\n2:eggs:spam", "foo", "bar")]
+ [InlineData(true, "1:foo:bar\n2:eggs:spam", "eggs", "spam")]
+ public static void ParseValidateProcCGroup(bool found, string procSelfCgroupText, string subsystem, string expectedMountPath)
+ {
+ string path = Path.GetTempFileName();
+ try
+ {
+ File.WriteAllText(path, procSelfCgroupText);
+
+ bool result = Interop.cgroups.TryFindCGroupPathForSubsystem(path, subsystem, out string mountPath);
+
+ Assert.Equal(found, result);
+ if (found)
+ {
+ Assert.Equal(expectedMountPath, mountPath);
+ }
+ }
+ finally
+ {
+ File.Delete(path);
+ }
+ }
+ }
+}
diff --git a/src/System.Runtime.InteropServices.RuntimeInformation/tests/DescriptionNameTests.cs b/src/System.Runtime.InteropServices.RuntimeInformation/tests/DescriptionNameTests.cs
index 910af2fd82b4..73f692898dbc 100644
--- a/src/System.Runtime.InteropServices.RuntimeInformation/tests/DescriptionNameTests.cs
+++ b/src/System.Runtime.InteropServices.RuntimeInformation/tests/DescriptionNameTests.cs
@@ -40,7 +40,7 @@ public void DumpRuntimeInformationToConsole()
Console.WriteLine($"### CURRENT DIRECTORY: {Environment.CurrentDirectory}");
- string cgroupsLocation = Interop.cgroups.s_cgroupMemoryPath;
+ string cgroupsLocation = Interop.cgroups.s_cgroupMemoryLimitPath;
if (cgroupsLocation != null)
{
Console.WriteLine($"### CGROUPS MEMORY: {cgroupsLocation}");

View File

@ -0,0 +1,129 @@
From 9a8c5e4014ffca8aff70808cc0e50a403d38c292 Mon Sep 17 00:00:00 2001
From: Stephen Toub <stoub@microsoft.com>
Date: Wed, 23 Oct 2019 20:35:49 -0400
Subject: [PATCH 2/2] Clean up new tests
---
.../tests/Tests/Interop/cgroupsTests.cs | 79 ++++++-------------
1 file changed, 25 insertions(+), 54 deletions(-)
diff --git a/src/Common/tests/Tests/Interop/cgroupsTests.cs b/src/Common/tests/Tests/Interop/cgroupsTests.cs
index f16d9242879c..fc6ab5c9753c 100644
--- a/src/Common/tests/Tests/Interop/cgroupsTests.cs
+++ b/src/Common/tests/Tests/Interop/cgroupsTests.cs
@@ -2,38 +2,27 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using System;
using System.IO;
-using System.Text;
using Xunit;
namespace Common.Tests
{
- public class cgroupsTests
+ public class cgroupsTests : FileCleanupTestBase
{
[Theory]
- [InlineData(true, "0", 0)]
- [InlineData(false, "max", 0)]
- [InlineData(true, "1k", 1024)]
- [InlineData(true, "1K", 1024)]
- public static void ValidateTryReadMemoryValue(bool expectedResult, string valueText, ulong expectedValue)
+ [InlineData(true, "0", 0)]
+ [InlineData(false, "max", 0)]
+ [InlineData(true, "1k", 1024)]
+ [InlineData(true, "1K", 1024)]
+ public void ValidateTryReadMemoryValue(bool expectedResult, string valueText, ulong expectedValue)
{
- string path = Path.GetTempFileName();
- try
- {
- File.WriteAllText(path, valueText);
-
- bool result = Interop.cgroups.TryReadMemoryValueFromFile(path, out ulong val);
+ string path = GetTestFilePath();
+ File.WriteAllText(path, valueText);
- Assert.Equal(expectedResult, result);
- if (result)
- {
- Assert.Equal(expectedValue, val);
- }
- }
- finally
+ Assert.Equal(expectedResult, Interop.cgroups.TryReadMemoryValueFromFile(path, out ulong val));
+ if (expectedResult)
{
- File.Delete(path);
+ Assert.Equal(expectedValue, val);
}
}
@@ -50,26 +39,17 @@ public static void ValidateTryReadMemoryValue(bool expectedResult, string valueT
[InlineData(true, "0 0 0:0 / /foo ignore ignore - cgroup cgroup cpu,memory", "memory", 1, "/", "/foo")]
[InlineData(true, "0 0 0:0 / /foo ignore ignore - cgroup cgroup memory,cpu", "memory", 1, "/", "/foo")]
[InlineData(false, "0 0 0:0 / /foo ignore ignore - cgroup cgroup cpu", "memory", 0, "/", "/foo")]
- public static void ParseValidateMountInfo(bool found, string procSelfMountInfoText, string subsystem, int expectedVersion, string expectedRoot, string expectedMount)
+ public void ParseValidateMountInfo(bool expectedFound, string procSelfMountInfoText, string subsystem, int expectedVersion, string expectedRoot, string expectedMount)
{
- string path = Path.GetTempFileName();
- try
- {
- File.WriteAllText(path, procSelfMountInfoText);
-
- bool result = Interop.cgroups.TryFindHierarchyMount(path, subsystem, out Interop.cgroups.CGroupVersion version, out string root, out string mount);
+ string path = GetTestFilePath();
+ File.WriteAllText(path, procSelfMountInfoText);
- Assert.Equal(found, result);
- if (found)
- {
- Assert.Equal(expectedVersion, (int)version);
- Assert.Equal(expectedRoot, root);
- Assert.Equal(expectedMount, mount);
- }
- }
- finally
+ Assert.Equal(expectedFound, Interop.cgroups.TryFindHierarchyMount(path, subsystem, out Interop.cgroups.CGroupVersion version, out string root, out string mount));
+ if (expectedFound)
{
- File.Delete(path);
+ Assert.Equal(expectedVersion, (int)version);
+ Assert.Equal(expectedRoot, root);
+ Assert.Equal(expectedMount, mount);
}
}
@@ -83,24 +63,15 @@ public static void ParseValidateMountInfo(bool found, string procSelfMountInfoTe
[InlineData(false, "2:foo:bar", "bar", "ignore")]
[InlineData(true, "1:foo:bar\n2:eggs:spam", "foo", "bar")]
[InlineData(true, "1:foo:bar\n2:eggs:spam", "eggs", "spam")]
- public static void ParseValidateProcCGroup(bool found, string procSelfCgroupText, string subsystem, string expectedMountPath)
+ public void ParseValidateProcCGroup(bool expectedFound, string procSelfCgroupText, string subsystem, string expectedMountPath)
{
- string path = Path.GetTempFileName();
- try
- {
- File.WriteAllText(path, procSelfCgroupText);
+ string path = GetTestFilePath();
+ File.WriteAllText(path, procSelfCgroupText);
- bool result = Interop.cgroups.TryFindCGroupPathForSubsystem(path, subsystem, out string mountPath);
-
- Assert.Equal(found, result);
- if (found)
- {
- Assert.Equal(expectedMountPath, mountPath);
- }
- }
- finally
+ Assert.Equal(expectedFound, Interop.cgroups.TryFindCGroupPathForSubsystem(path, subsystem, out string mountPath));
+ if (expectedFound)
{
- File.Delete(path);
+ Assert.Equal(expectedMountPath, mountPath);
}
}
}

View File

@ -0,0 +1,70 @@
From 58d6cd09bd2d5b1085c6572c1d97b8533cf8294b Mon Sep 17 00:00:00 2001
From: Omair Majid <omajid@redhat.com>
Date: Fri, 3 Apr 2020 13:53:09 -0400
Subject: [PATCH] Fix corefx to build on clang 10
Clang 10 adds/enables new warnings, some of which is affecting
the corefx code.
Clang 10 has added -Walloca to warn about uses of alloca. This commit
replaces the only non-compliant use of that with a single fixed
stack-allocated buffer.
Clang 10 has also added -Wimplicit-int-float-conversion. This commit
uses explicit casts to double to avoid the warnings.
This is a backport of dotnet/runtime#33734 to corefx.
After this commit, I can build all of corefx with Clang 10.
---
src/Native/Unix/System.Native/pal_io.c | 20 +++++++++++---------
src/Native/Unix/System.Native/pal_time.c | 2 +-
2 files changed, 12 insertions(+), 10 deletions(-)
diff --git a/src/Native/Unix/System.Native/pal_io.c b/src/Native/Unix/System.Native/pal_io.c
index 2d51edacf5ee..c7c42eb3e72b 100644
--- a/src/Native/Unix/System.Native/pal_io.c
+++ b/src/Native/Unix/System.Native/pal_io.c
@@ -906,18 +906,20 @@ int32_t SystemNative_Poll(PollEvent* pollEvents, uint32_t eventCount, int32_t mi
return Error_EINVAL;
}
- size_t bufferSize;
- if (!multiply_s(sizeof(struct pollfd), (size_t)eventCount, &bufferSize))
+ struct pollfd stackBuffer[(uint32_t)(2048/sizeof(struct pollfd))];
+ int useStackBuffer = eventCount <= (sizeof(stackBuffer)/sizeof(stackBuffer[0]));
+ struct pollfd* pollfds = NULL;
+ if (useStackBuffer)
{
- return SystemNative_ConvertErrorPlatformToPal(EOVERFLOW);
+ pollfds = (struct pollfd*)&stackBuffer[0];
}
-
-
- int useStackBuffer = bufferSize <= 2048;
- struct pollfd* pollfds = (struct pollfd*)(useStackBuffer ? alloca(bufferSize) : malloc(bufferSize));
- if (pollfds == NULL)
+ else
{
- return Error_ENOMEM;
+ pollfds = (struct pollfd*)calloc(eventCount, sizeof(*pollfds));
+ if (pollfds == NULL)
+ {
+ return Error_ENOMEM;
+ }
}
for (uint32_t i = 0; i < eventCount; i++)
diff --git a/src/Native/Unix/System.Native/pal_time.c b/src/Native/Unix/System.Native/pal_time.c
index 1a7c862749d1..54ebde60a83b 100644
--- a/src/Native/Unix/System.Native/pal_time.c
+++ b/src/Native/Unix/System.Native/pal_time.c
@@ -169,7 +169,7 @@ int32_t SystemNative_GetCpuUtilization(ProcessCpuInformation* previousCpuInfo)
uint64_t resolution = SystemNative_GetTimestampResolution();
uint64_t timestamp = SystemNative_GetTimestamp();
- uint64_t currentTime = (uint64_t)(timestamp * ((double)SecondsToNanoSeconds / resolution));
+ uint64_t currentTime = (uint64_t)((double)timestamp * ((double)SecondsToNanoSeconds / (double)resolution));
uint64_t lastRecordedCurrentTime = previousCpuInfo->lastRecordedCurrentTime;
uint64_t lastRecordedKernelTime = previousCpuInfo->lastRecordedKernelTime;

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

View File

@ -5,9 +5,9 @@ index 7d804a1e54..717c2718d7 100644
@@ -25,7 +25,7 @@ add_compile_options(-fPIC)
add_compile_options(-Wthread-safety)
add_compile_options(-Wno-thread-safety-analysis)
+ add_compile_options(-Wno-alloca)
endif()
-add_compile_options(-Werror)
+add_compile_options(-Wno-unused-result)
if(CMAKE_SYSTEM_NAME STREQUAL Emscripten)
set(CLR_CMAKE_PLATFORM_WASM 1)

1
dead.package Normal file
View File

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

View File

@ -0,0 +1,11 @@
--- Directory.Build.props 2020-06-04 17:54:26.587622453 -0500
+++ Directory.Build.props 2020-06-04 17:54:43.948536557 -0500
@@ -145,8 +145,6 @@
<!-- The location of the local installation of the .NET Core shared framework. -->
<PropertyGroup>
<LocalDotNetRoot>$(RepoRoot).dotnet\</LocalDotNetRoot>
- <!-- Override the SDK default and point to local .dotnet folder. -->
- <NetCoreTargetingPackRoot>$(LocalDotNetRoot)packs\</NetCoreTargetingPackRoot>
</PropertyGroup>
<Import Project="eng\tools\RepoTasks\RepoTasks.tasks" Condition="'$(MSBuildProjectName)' != 'RepoTasks' AND '$(DesignTimeBuild)' != 'true'" />

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

@ -14,26 +14,24 @@
%global __provides_exclude ^(%{privlibs})\\.so
%global __requires_exclude ^(%{privlibs})\\.so
# Filter flags not supported by clang/dotnet:
# -fstack-clash-protection is not supported by clang
# -specs= is not supported by clang
%global dotnet_cflags %(echo %optflags | sed -e 's/-fstack-clash-protection//' | sed -re 's/-specs=[^ ]*//g')
%if 0%{?fedora} < 30 && ! 0%{?rhel}
# on Fedora 29, clang, -fcf-protection and binutils interact in strage ways leading to
# "<corrupt x86 feature size: 0x8>" errors.
%global dotnet_cflags %(echo %dotnet_cflags | sed -e 's/ -fcf-protection//')
%endif
%global dotnet_ldflags %(echo %{__global_ldflags} | sed -re 's/-specs=[^ ]*//g')
# LTO triggers a compilation error for a source level issue. Given that LTO should not
# change the validity of any given source and the nature of the error (undefined enum), I
# suspect a generator program is mis-behaving in some way. This needs further debugging,
# until that's done, disable LTO. This has to happen before setting the flags below.
%define _lto_cflags %{nil}
%global host_version 3.1.32
%global runtime_version 3.1.32
%global host_version 3.1.18
%global runtime_version 3.1.18
%global aspnetcore_runtime_version %{runtime_version}
%global sdk_version 3.1.426
%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 }')
%global host_rpm_version %{host_version}
%global runtime_rpm_version %{runtime_version}
%global aspnetcore_runtime_rpm_version %{aspnetcore_runtime_version}
%global runtime_rpm_version %{runtime_version}
%global sdk_rpm_version %{sdk_version}
%if 0%{?fedora} || 0%{?rhel} < 8
@ -42,6 +40,10 @@
%global use_bundled_libunwind 1
%endif
%ifarch aarch64
%global use_bundled_libunwind 1
%endif
%ifarch x86_64
%global runtime_arch x64
%endif
@ -49,45 +51,62 @@
%global runtime_arch arm64
%endif
%if 0%{?fedora}
%global runtime_id fedora.%{fedora}-%{runtime_arch}
%else
%if 0%{?centos}
%global runtime_id centos.%{centos}-%{runtime_arch}
%else
%global runtime_id rhel.%{rhel}-%{runtime_arch}
%endif
%endif
%{!?runtime_id:%global runtime_id %(. /etc/os-release ; echo "${ID}.${VERSION_ID%%.*}")-%{runtime_arch}}
Name: dotnet3.1
Version: %{sdk_rpm_version}
Release: 1%{?dist}
Summary: .NET Core CLI tools and runtime
License: MIT and ASL 2.0 and BSD
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/
# ./build-dotnet-tarball dotnet-v%%{sdk_version}-SDK
Source0: dotnet-v%{sdk_version}-SDK.tar.gz
#Source0: dotnet-v%%{sdk_version}-SDK-x64-bootstrap.tar.gz
# The source is generated on a Fedora box via:
# ./build-dotnet-tarball v%%{src_version}-SDK
Source0: dotnet-v%{src_version}-SDK.tar.gz
Source1: check-debug-symbols.py
Source2: dotnet.sh.in
Source100: check-debug-symbols.py
Source101: dotnet.sh.in
Patch1: source-build-ilasm-ildasm-path-fix.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
# Add some support for cgroupv2 in corefx
# All these patches are upstreamed for 5.0
Patch101: corefx-39686-cgroupv2-01.patch
Patch102: corefx-39686-cgroupv2-02.patch
Patch103: corefx-39633-cgroupv2-mountpoints.patch
Patch200: coreclr-27048-sysctl-deprecation.patch
# Already applied at tarball build time
# 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
# Fix build with clang 10; Already applied at tarball-build time
# Patch200: coreclr-clang10.patch
# Fix build on recent versions of gcc/clang
# https://github.com/libunwind/libunwind/pull/166
# Already applied
#Patch201: coreclr-libunwind-fno-common.patch
Patch300: core-setup-do-not-strip.patch
Patch301: core-setup-no-werror.patch
# Disable telemetry by default; make it opt-in
Patch500: cli-telemetry-optout.patch
%if 0%{?fedora} > 32 || 0%{?rhel} > 8
ExclusiveArch: aarch64 x86_64
%else
ExclusiveArch: x86_64
%endif
BuildRequires: clang
BuildRequires: cmake
@ -97,6 +116,7 @@ BuildRequires: dotnet-build-reference-packages
BuildRequires: dotnet-sdk-3.1
BuildRequires: dotnet-sdk-3.1-source-built-artifacts
%endif
BuildRequires: findutils
BuildRequires: git
%if 0%{?fedora} || 0%{?rhel} > 7
BuildRequires: glibc-langpack-en
@ -111,8 +131,13 @@ BuildRequires: libunwind-devel
BuildRequires: lldb-devel
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
BuildRequires: zlib-devel
@ -191,10 +216,8 @@ Summary: NET Core 3.1 runtime
Requires: dotnet-hostfxr-3.1%{?_isa} >= %{host_rpm_version}-%{release}
# libicu is dlopen()ed
Requires: libicu
Requires: libicu%{?_isa}
# See src/corefx.*/src/Native/AnyOS/brotli-version.txt
Provides: bundled(libbrotli) = 1.0.9
%if %{use_bundled_libunwind}
Provides: bundled(libunwind) = 1.3
%endif
@ -254,6 +277,9 @@ applications and micro-services.
Version: %{sdk_rpm_version}
Summary: .NET Core 3.1 Software Development Kit
Provides: bundled(js-jquery)
Provides: bundled(npm)
Requires: dotnet-runtime-3.1%{?_isa} >= %{runtime_rpm_version}-%{release}
Requires: aspnetcore-runtime-3.1%{?_isa} >= %{aspnetcore_runtime_rpm_version}-%{release}
@ -275,16 +301,16 @@ It particularly focuses on creating console applications, web
applications and micro-services.
%define dotnet_targeting_pack() %{expand:
%global dotnet_targeting_pack() %{expand:
%package -n %{1}
Version: %{2}
Summary: Targeting Pack for %{3} %{4}
Requires: dotnet-host
Requires: dotnet-host%{?_isa}
%description -n %{1}
This package provides a targetting pack for %{3} %{4}
This package provides a targeting pack for %{3} %{4}
that allows developers to compile against and target %{3} %{4}
applications using the .NET Core SDK.
@ -296,7 +322,8 @@ applications using the .NET Core SDK.
%dotnet_targeting_pack dotnet-apphost-pack-3.1 %{runtime_rpm_version} Microsoft.NETCore.App 3.1 Microsoft.NETCore.App.Host.%{runtime_id}
%dotnet_targeting_pack dotnet-targeting-pack-3.1 %{runtime_rpm_version} Microsoft.NETCore.App 3.1 Microsoft.NETCore.App.Ref
%dotnet_targeting_pack aspnetcore-targeting-pack-3.1 %{aspnetcore_runtime_rpm_version} Microsoft.AspNetCore.App 3.1 Microsoft.AspNetCore.App.Ref
#%%dotnet_targeting_pack netstandard-targeting-pack-2.1 %%{sdk_rpm_version} NETStandard.Library 2.1 NETStandard.Library.Ref
%dotnet_targeting_pack netstandard-targeting-pack-2.1 %{sdk_rpm_version} NETStandard.Library 2.1 NETStandard.Library.Ref
%package -n dotnet-sdk-3.1-source-built-artifacts
@ -311,18 +338,7 @@ These are not meant for general use.
%prep
%if %{with bootstrap}
%ifarch x86_64
%setup T -b0 -q -n dotnet-v%{sdk_version}-SDK-%{runtime_arch}-bootstrap
%endif
%ifarch aarch64
%setup T -b1 -q -n dotnet-v%{sdk_version}-SDK-%{runtime_arch}-bootstrap
%endif
%else
%setup -q -n dotnet-v%{sdk_version}-SDK
%endif
%setup -q -n dotnet-v%{src_version}-SDK
%if %{without bootstrap}
# Remove all prebuilts
@ -342,32 +358,45 @@ ln -s %{_libdir}/dotnet/reference-packages/Private.SourceBuild.ReferencePackages
%endif
# Fix bad hardcoded path in build
sed -i 's|/usr/share/dotnet|%{_libdir}/dotnet|' src/dotnet-core-setup.*/src/corehost/common/pal.unix.cpp
sed -i 's|/usr/share/dotnet|%{_libdir}/dotnet|' src/core-setup.*/src/corehost/common/pal.unix.cpp
# Disable warnings
sed -i 's|skiptests|skiptests ignorewarnings|' repos/coreclr.common.props
sed -i 's|skiptests|skiptests ignorewarnings|' repos/coreclr.proj
%patch1 -p1
%patch2 -p1
pushd src/dotnet-corefx.*
pushd src/corefx.*
%patch100 -p1
%patch101 -p1
%patch102 -p1
%patch103 -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/dotnet-coreclr.*
%patch200 -p1
pushd src/coreclr.*
#%%patch200 -p1
#%%patch201 -p1
popd
pushd src/dotnet-core-setup.*
%patch300 -p1
%patch301 -p1
pushd src/core-setup.*
popd
pushd src/dotnet-cli.*
pushd src/cli.*
%patch500 -p1
popd
# If CLR_CMAKE_USE_SYSTEM_LIBUNWIND=TRUE is misisng, add it back
grep CLR_CMAKE_USE_SYSTEM_LIBUNWIND repos/coreclr.common.props || \
sed -i 's|\$(BuildArguments) </BuildArguments>|$(BuildArguments) cmakeargs -DCLR_CMAKE_USE_SYSTEM_LIBUNWIND=TRUE</BuildArguments>|' repos/coreclr.common.props
@ -376,6 +405,11 @@ grep CLR_CMAKE_USE_SYSTEM_LIBUNWIND repos/coreclr.common.props || \
sed -i 's|-DCLR_CMAKE_USE_SYSTEM_LIBUNWIND=TRUE|-DCLR_CMAKE_USE_SYSTEM_LIBUNWIND=FALSE|' repos/coreclr.common.props
%endif
%ifnarch x86_64
mkdir -p artifacts/obj/%{runtime_arch}/Release
cp artifacts/obj/x64/Release/PackageVersions.props artifacts/obj/%{runtime_arch}/Release/PackageVersions.props
%endif
cat source-build-info.txt
find -iname 'nuget.config' -exec echo {}: \; -exec cat {} \; -exec echo \;
@ -389,9 +423,40 @@ cat /etc/os-release
cp -a %{_libdir}/dotnet previously-built-dotnet
%endif
%if 0%{?fedora} > 32 || 0%{?rhel} > 8
# Setting this macro ensures that only clang supported options will be
# added to ldflags and cflags.
%global toolchain clang
%set_build_flags
%else
# Filter flags not supported by clang
# -specs=
%global dotnet_cflags %(echo %optflags | sed -re 's/-specs=[^ ]*//g')
%global dotnet_ldflags %(echo %{__global_ldflags} | sed -re 's/-specs=[^ ]*//g')
export CFLAGS="%{dotnet_cflags}"
export CXXFLAGS="%{dotnet_cflags}"
export LDFLAGS="%{dotnet_ldflags}"
%endif
%ifarch aarch64
# mbranch-protection=standard breaks unwinding in CoreCLR through libunwind
CFLAGS=$(echo $CFLAGS | sed -e 's/-mbranch-protection=standard //')
CXXFLAGS=$(echo $CXXFLAGS | sed -e 's/-mbranch-protection=standard //')
%endif
# fstack-clash-protection breaks CoreCLR
CFLAGS=$(echo $CFLAGS | sed -e 's/-fstack-clash-protection//' )
CXXFLAGS=$(echo $CXXFLAGS | sed -e 's/-fstack-clash-protection//' )
echo $CFLAGS
echo $CXXFLAGS
echo $LDFLAGS
#%%if %%{without bootstrap}
# --with-ref-packages %%{_libdir}/dotnet/reference-packages/ \
# --with-packages %%{_libdir}/dotnet/source-built-artifacts/*.tar.gz \
# --with-sdk %%{_libdir}/dotnet \
#%%endif
VERBOSE=1 ./build.sh \
%if %{without bootstrap}
@ -405,12 +470,12 @@ VERBOSE=1 ./build.sh \
/p:ContinueOnPrebuiltBaselineError=true \
sed -e 's|[@]LIBDIR[@]|%{_libdir}|g' %{SOURCE101} > dotnet.sh
sed -e 's|[@]LIBDIR[@]|%{_libdir}|g' %{SOURCE2} > dotnet.sh
%install
install -dm 0755 %{buildroot}%{_libdir}/dotnet
find artifacts/%{runtime_arch}/Release
ls artifacts/%{runtime_arch}/Release
tar xf artifacts/%{runtime_arch}/Release/dotnet-sdk-%{sdk_version}-%{runtime_id}.tar.gz -C %{buildroot}%{_libdir}/dotnet/
# Install managed symbols
@ -424,44 +489,30 @@ find %{buildroot}%{_libdir}/dotnet/ -type f -name '*.props' -exec chmod -x {} \;
find %{buildroot}%{_libdir}/dotnet/ -type f -name '*.pubxml' -exec chmod -x {} \;
find %{buildroot}%{_libdir}/dotnet/ -type f -name '*.targets' -exec chmod -x {} \;
chmod 0755 %{buildroot}/%{_libdir}/dotnet/sdk/%{sdk_version}/AppHostTemplate/apphost
chmod 0644 %{buildroot}/%{_libdir}/dotnet/packs/Microsoft.AspNetCore.App.Ref/3.1.10/data/FrameworkList.xml
chmod 0644 %{buildroot}/%{_libdir}/dotnet/packs/Microsoft.AspNetCore.App.Ref/3.1.10/data/PackageOverrides.txt
chmod 0644 %{buildroot}/%{_libdir}/dotnet/packs/Microsoft.AspNetCore.App.Ref/3.1.10/data/PlatformManifest.txt
chmod 0644 %{buildroot}/%{_libdir}/dotnet/packs/Microsoft.AspNetCore.App.Ref/3.1.10/ref/netcoreapp3.1/*.xml
chmod 0644 %{buildroot}/%{_libdir}/dotnet/packs/Microsoft.NETCore.App.Host.%{runtime_id}/%{runtime_version}/runtimes/%{runtime_id}/native/nethost.h
chmod 0644 %{buildroot}/%{_libdir}/dotnet/packs/Microsoft.NETCore.App.Ref/3.1.0/data/FrameworkList.xml
chmod 0644 %{buildroot}/%{_libdir}/dotnet/packs/Microsoft.NETCore.App.Ref/3.1.0/data/PackageOverrides.txt
chmod 0644 %{buildroot}/%{_libdir}/dotnet/packs/Microsoft.NETCore.App.Ref/3.1.0/data/PlatformManifest.txt
chmod 0644 %{buildroot}/%{_libdir}/dotnet/packs/NETStandard.Library.Ref/2.1.0/data/FrameworkList.xml
chmod 0644 %{buildroot}/%{_libdir}/dotnet/packs/NETStandard.Library.Ref/2.1.0/data/PackageOverrides.txt
chmod 0755 %{buildroot}/%{_libdir}/dotnet/packs/Microsoft.NETCore.App.Host.%{runtime_id}/%{runtime_version}/runtimes/%{runtime_id}/native/apphost
chmod 0755 %{buildroot}/%{_libdir}/dotnet/packs/Microsoft.NETCore.App.Host.%{runtime_id}/%{runtime_version}/runtimes/%{runtime_id}/native/libnethost.so
chmod 0755 %{buildroot}/%{_libdir}/dotnet/packs/Microsoft.NETCore.App.Host.%{runtime_id}/%{runtime_version}/runtimes/%{runtime_id}/native/apphost
chmod 0644 %{buildroot}/%{_libdir}/dotnet/packs/Microsoft.NETCore.App.Host.%{runtime_id}/%{runtime_version}/runtimes/%{runtime_id}/native/nethost.h
# Provided by dotnet-host from another SRPM
#install -dm 0755 %%{buildroot}%%{_sysconfdir}/profile.d/
#install dotnet.sh %%{buildroot}%%{_sysconfdir}/profile.d/
install -dm 0755 %{buildroot}%{_sysconfdir}/profile.d/
install dotnet.sh %{buildroot}%{_sysconfdir}/profile.d/
# Provided by dotnet-host from another SRPM
#install -dm 0755 %%{buildroot}/%%{_datadir}/bash-completion/completions
install -dm 0755 %{buildroot}/%{_datadir}/bash-completion/completions
# dynamic completion needs the file to be named the same as the base command
#install src/dotnet-cli.*/scripts/register-completions.bash %%{buildroot}/%%{_datadir}/bash-completion/completions/dotnet
install src/cli.*/scripts/register-completions.bash %{buildroot}/%{_datadir}/bash-completion/completions/dotnet
# TODO: the zsh completion script needs to be ported to use #compdef
#install -dm 755 %%{buildroot}/%%{_datadir}/zsh/site-functions
#install src/dotnet-cli/scripts/register-completions.zsh %%{buildroot}/%%{_datadir}/zsh/site-functions/_dotnet
#install src/cli/scripts/register-completions.zsh %%{buildroot}/%%{_datadir}/zsh/site-functions/_dotnet
# Provided by dotnet-host from another SRPM
#install -dm 0755 %%{buildroot}%%{_bindir}
#ln -s ../../%%{_libdir}/dotnet/dotnet %%{buildroot}%%{_bindir}/
install -dm 0755 %{buildroot}%{_bindir}
ln -s ../../%{_libdir}/dotnet/dotnet %{buildroot}%{_bindir}/
# Provided by dotnet-host from another SRPM
#install -dm 0755 %%{buildroot}%%{_mandir}/man1/
#find -iname 'dotnet*.1' -type f -exec cp {} %%{buildroot}%%{_mandir}/man1/ \;
install -dm 0755 %{buildroot}%{_mandir}/man1/
find -iname 'dotnet*.1' -type f -exec cp {} %{buildroot}%{_mandir}/man1/ \;
# Provided by dotnet-host from another SRPM
#echo "%%{_libdir}/dotnet" >> install_location
#install -dm 0755 %%{buildroot}%%{_sysconfdir}/dotnet
#install install_location %%{buildroot}%%{_sysconfdir}/dotnet/
echo "%{_libdir}/dotnet" >> install_location
install -dm 0755 %{buildroot}%{_sysconfdir}/dotnet
install install_location %{buildroot}%{_sysconfdir}/dotnet/
install -dm 0755 %{buildroot}%{_libdir}/dotnet/source-built-artifacts
install artifacts/%{runtime_arch}/Release/Private.SourceBuilt.Artifacts.*.tar.gz %{buildroot}/%{_libdir}/dotnet/source-built-artifacts/
@ -470,18 +521,30 @@ install artifacts/%{runtime_arch}/Release/Private.SourceBuilt.Artifacts.*.tar.gz
# because native binaries are stripped by rpm-build after %%install.
# So we need to do this check earlier.
echo "Testing build results for debug symbols..."
%{SOURCE100} -v %{buildroot}%{_libdir}/dotnet/
%{SOURCE1} -v %{buildroot}%{_libdir}/dotnet/
# Self-check
%check
%{buildroot}%{_libdir}/dotnet/dotnet --info
# Provided by dotnet-host from another SRPM
rm %{buildroot}%{_libdir}/dotnet/LICENSE.txt
rm %{buildroot}%{_libdir}/dotnet/ThirdPartyNotices.txt
rm %{buildroot}%{_libdir}/dotnet/dotnet
# Provided by netstandard-targeting-pack-2.1 from another SRPM
rm -rf %{buildroot}%{_libdir}/dotnet/packs/NETStandard.Library.Ref/2.1.0
%files -n dotnet
# empty package useful for dependencies
%files -n dotnet-host
%dir %{_libdir}/dotnet
%{_libdir}/dotnet/dotnet
%dir %{_libdir}/dotnet/host
%dir %{_libdir}/dotnet/host/fxr
%{_bindir}/dotnet
%license %{_libdir}/dotnet/LICENSE.txt
%license %{_libdir}/dotnet/ThirdPartyNotices.txt
%doc %{_mandir}/man1/dotnet*.1.gz
%{_sysconfdir}/profile.d/dotnet.sh
%{_sysconfdir}/dotnet
%dir %{_datadir}/bash-completion
%dir %{_datadir}/bash-completion/completions
%{_datadir}/bash-completion/completions/dotnet
%files -n dotnet-hostfxr-3.1
%dir %{_libdir}/dotnet/host/fxr
@ -510,181 +573,158 @@ rm -rf %{buildroot}%{_libdir}/dotnet/packs/NETStandard.Library.Ref/2.1.0
%dir %{_libdir}/dotnet
%{_libdir}/dotnet/source-built-artifacts
%changelog
* Wed Nov 30 2022 Omair Majid <omajid@redhat.com> - 3.1.426-1
- Update to .NET SDK 3.1.426 and Runtime 3.1.32
- Resolves: RHBZ#2148219
* Wed Sep 14 2022 Omair Majid <omajid@redhat.com> - 3.1.423-2
- Update to .NET SDK 3.1.423 and Runtime 3.1.29
- Resolves: RHBZ#2123784
* Tue Aug 09 2022 Omair Majid <omajid@redhat.com> - 3.1.422-2
- Update to .NET SDK 3.1.422 and Runtime 3.1.28
- Resolves: RHBZ#2115350
* Thu Jul 21 2022 Omair Majid <omajid@redhat.com> - 3.1.421-2
- Update to .NET SDK 3.1.421 and Runtime 3.1.27
- Resolves: RHBZ#2103273
* Thu Jun 23 2022 Omair Majid <omajid@redhat.com> - 3.1.420-1
- Update to .NET SDK 3.1.420 and Runtime 3.1.26
- Resolves: RHBZ#2096318
* Mon May 16 2022 Omair Majid <omajid@redhat.com> - 3.1.419-1
- Update to .NET SDK 3.1.419 and Runtime 3.1.25
- Resolves: RHBZ#2081442
* Wed Apr 27 2022 Omair Majid <omajid@redhat.com> - 3.1.418-2
- Bump release
- Related: RHBZ#2072012
* Mon Apr 25 2022 Omair Majid <omajid@redhat.com> - 3.1.418-1
- Update to .NET SDK 3.1.418 and Runtime 3.1.24
- Resolves: RHBZ#2072012
* Tue Jan 25 2022 Omair Majid <omajid@redhat.com> - 3.1.416-4
- Update to .NET SDK 3.1.416 and Runtime 3.1.22
- Resolves: RHBZ#2011820
- Resolves: RHBZ#2003077
- Resolves: RHBZ#2031428
* Sat Aug 14 2021 Omair Majid <omajid@redhat.com> - 3.1.118-1
* 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#1990174
- Resolves: RHBZ#1961848
* Wed Aug 11 2021 Omair Majid <omajid@redhat.com> - 3.1.117-1
* 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#1978389
- 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#1965499
- Resolves: RHBZ#1966998
- Resolves: RHBZ#1961848
* Wed Jun 02 2021 Omair Majid <omajid@redhat.com> - 3.1.115-1
* 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#1954324
- Resolves: RHBZ#1961848
* Thu Apr 22 2021 Omair Majid <omajid@redhat.com> - 3.1.114-2
- Update to .NET SDK 3.1.114 and Runtime 3.1.14
- Add dotnet-sdk-3.1-source-built-artifacts subpackage
- Resolves: RHBZ#1946721
* Wed Apr 21 2021 Omair Majid <omajid@redhat.com> - 3.1.113-3
- Fix build by adding CentOS 9 RIDs
- Resolves: RHBZ#1951312
* Wed Feb 10 2021 Omair Majid <omajid@redhat.com> - 3.1.112-2
* Thu Apr 15 2021 Mohan Boddu <mboddu@redhat.com> - 3.1.113-3
- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937
* Tue Mar 30 2021 Jonathan Wakely <jwakely@redhat.com> - 3.1.113-2
- Rebuilt for removed libstdc++ symbol (#1937698)
* Wed Mar 17 2021 Omair Majid <omajid@redhat.com> - 3.1.113-1
- Update to .NET Core SDK 3.1.113 and Runtime 3.1.13
* Wed Feb 17 2021 Omair Majid <omajid@redhat.com> - 3.1.112-3
- Hack an RID for RHEL 9 into the build SDK
* Wed Feb 17 2021 Omair Majid <omajid@redhat.com> - 3.1.112-2
- Add Fedora 35 Runtime ID
* Fri Feb 12 2021 Omair Majid <omajid@redhat.com> - 3.1.112-1
- Update to .NET Core SDK 3.1.112 and Runtime 3.1.12
- Resolves: RHBZ#1923370
* Wed Jan 13 2021 Omair Majid <omajid@redhat.com> - 3.1.111-2
* Tue Jan 26 2021 Fedora Release Engineering <releng@fedoraproject.org> - 3.1.111-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
* Fri Jan 15 2021 Omair Majid <omajid@redhat.com> - 3.1.111-1
- Update to .NET Core SDK 3.1.111 and Runtime 3.1.11
- Resolves: RHBZ#1907627
* Fri Nov 06 2020 Omair Majid <omajid@redhat.com> - 3.1.110-2
* Sun Dec 06 2020 Jeff Law <law@redhat.com> - 3.1.110-2
- Fix missing #include for gcc-11
* Tue Nov 10 2020 Omair Majid <omajid@redhat.com> - 3.1.110-1
- Update to .NET Core SDK 3.1.110 and Runtime 3.1.10
- Resolves: RHBZ#1893778
* Tue Oct 13 2020 Omair Majid <omajid@redhat.com> - 3.1.109-3
* Wed Oct 14 2020 Omair Majid <omajid@redhat.com> - 3.1.109-1
- Update to .NET Core SDK 3.1.109 and Runtime 3.1.9
- Resolves: RHBZ#1886546
* Fri Sep 18 2020 Omair Majid <omajid@redhat.com> - 3.1.108-3
- Bump release to preserve upgrade path
- Resolves: RHBZ#1874503
* Mon Sep 21 2020 Tom Stellard <tstellar@redhat.com> - 3.1.108-2
- Use toolchain macro for setting clang-specific c/ld flags
* Fri Sep 04 2020 Omair Majid <omajid@redhat.com> - 3.1.108-2
- Stop producing netstandard-targeting-pack-2.1
- Resolves: RHBZ#1874503
* Wed Sep 16 2020 Troy Dawson <tdawson@redhat.com> - 3.1.108-1
- Generate runtime_id the same way that it does in the various build scripts
* Fri Sep 04 2020 Omair Majid <omajid@redhat.com> - 3.1.108-1
* Fri Sep 11 2020 Omair Majid <omajid@redhat.com> - 3.1.108-1
- Update to .NET Core SDK 3.1.108 and Runtime 3.1.8
- Resolves: RHBZ#1874503
- Resolves: RHBZ#1873454
* Mon Aug 17 2020 Omair Majid <omajid@redhat.com> - 3.1.107-2
- Remove subpackages that conflict with dotnet5.0
- Resolves: RHBZ#1862590
* Wed Sep 09 2020 Omair Majid <omajid@redhat.com> - 3.1.107-1
- Add Fedora 34 RID
- Fix build of bundled libunwind
* Thu Aug 13 2020 Omair Majid <omajid@redhat.com> - 3.1.107-1
- Update to .NET Core SDK 3.1.107 and Runtime 3.1.7
- Resolves: RHBZ#1862590
- Resolves: RHBZ#1861114
* Wed Aug 19 2020 Omair Majid <omajid@redhat.com> - 3.1.107-1
- Update to .NET Core Runtime 3.1.7 and SDK 3.1.107
* Thu Jul 30 2020 Omair Majid <omajid@redhat.com> - 3.1.106-6
- Remove duplicate LDFLAGS (actually typoed ASMFLAGS) for build
- Resolves: RHBZ#1811776
* Thu Aug 13 2020 Omair Majid <omajid@redhat.com> - 3.1.106-3
- Filter out -mbranch-protection=standard from cflags
* Wed Jul 29 2020 Omair Majid <omajid@redhat.com> - 3.1.106-5
- Export ASMFLAGS during build
- Resolves: RHBZ#1811776
* Sat Aug 01 2020 Fedora Release Engineering <releng@fedoraproject.org> - 3.1.106-3
- Second attempt - Rebuilt for
https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
* Tue Jul 28 2020 Omair Majid <omajid@redhat.com> - 3.1.106-4
- Enable -fcf-protection
- Resolves: RHBZ#1811776
* Mon Jul 27 2020 Fedora Release Engineering <releng@fedoraproject.org> - 3.1.106-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
* Mon Jul 27 2020 Omair Majid <omajid@redhat.com> - 3.1.106-3
- Improve hardening in core-setup and corefx
- Resolves: RHBZ#1811776
* Tue Jul 21 2020 Jo Shields <joshield@microsoft.com> - 3.1.106-1
- Update to .NET Core Runtime 3.1.6 and SDK 3.1.106
* Fri Jul 24 2020 Omair Majid <omajid@redhat.com> - 3.1.106-2
- Improve hardening in CoreCLR
- Resolves: RHBZ#1811776
* Tue Jul 21 2020 Omair Majid <omajid@redhat.com> - 3.1.105-5
- Fix up commented-out define for disabling LTO
* Thu Jul 16 2020 Omair Majid <omajid@redhat.com> - 3.1.106-1
- Update to .NET Core SDK 3.1.106 and Runtime 3.1.6
- Resolves: RHBZ#1853772
- Resolves: RHBZ#1856939
* Mon Jul 20 2020 Jeff Law <law@redhat.com> - 3.1.105-5
- Disable LTO
* Tue Jun 09 2020 Omair Majid <omajid@redhat.com> - 3.1.105-1
* Sat Jun 27 2020 Omair Majid <omajid@redhat.com> - 3.1.105-4
- Disable bootstrap
* Fri Jun 26 2020 Omair Majid <omajid@redhat.com> - 3.1.105-3
- Re-bootstrap aarch64
* Fri Jun 19 2020 Omair Majid <omajid@redhat.com> - 3.1.105-3
- Disable bootstrap
* Thu Jun 18 2020 Omair Majid <omajid@redhat.com> - 3.1.105-1
- Bootstrap aarch64
* Tue Jun 16 2020 Chris Rummel <crummel@microsoft.com> - 3.1.105-1
- Update to .NET Core Runtime 3.1.5 and SDK 3.1.105
- Resolves: RHBZ#1844491
* Mon Jun 01 2020 Omair Majid <omajid@redhat.com> - 3.1.104-3
* Fri Jun 05 2020 Chris Rummel <crummel@microsoft.com> - 3.1.104-1
- Update to .NET Core Runtime 3.1.4 and SDK 3.1.104
- Resolves: RHBZ#1832685
* Fri Mar 20 2020 Omair Majid <omajid@redhat.com> - 3.1.103-2
* Thu Apr 09 2020 Chris Rummel <crummel@microsoft.com> - 3.1.103-1
- Update to .NET Core Runtime 3.1.3 and SDK 3.1.103
- Resolves: RHBZ#1815632
* Wed Feb 19 2020 Omair Majid <omajid@redhat.com> - 3.1.102-2
* Mon Mar 16 2020 Omair Majid <omajid@redhat.com> - 3.1.102-1
- Update to .NET Core Runtime 3.1.2 and SDK 3.1.102
- Resolves: RHBZ#1804452
* Thu Jan 23 2020 Omair Majid <omajid@redhat.com> - 3.1.101-2
* Fri Feb 28 2020 Omair Majid <omajid@redhat.com> - 3.1.101-4
- Disable bootstrap
* Fri Feb 28 2020 Omair Majid <omajid@redhat.com> - 3.1.101-3
- Enable bootstrap
- Add Fedora 33 runtime ids
* Thu Feb 27 2020 Omair Majid <omajid@redhat.com> - 3.1.101-2
- Disable bootstrap
* Tue Jan 21 2020 Omair Majid <omajid@redhat.com> - 3.1.101-1
- Update to .NET Core Runtime 3.1.1 and SDK 3.1.101
- Resolves: RHBZ#1789154
* Wed Dec 04 2019 Omair Majid <omajid@redhat.com> - 3.1.100-2
- Remove arm64 variant of the source tarball
- Resolves: RHBZ#1711405
* Tue Dec 03 2019 Omair Majid <omajid@redhat.com> - 3.1.100-1
* Thu Dec 05 2019 Omair Majid <omajid@redhat.com> - 3.1.100-1
- Update to .NET Core Runtime 3.1.0 and SDK 3.1.100
- Resolves: RHBZ#1711405
* Wed Nov 27 2019 Omair Majid <omajid@redhat.com> - 3.1.100-0.7.preview3
- Extract self-contained executables under $HOME
- Resolves: RHBZ#1711405
* Wed Nov 27 2019 Omair Majid <omajid@redhat.com> - 3.1.100-0.6.preview3
- Drop local fixes for cgroupv2
- Resolves: RHBZ#1711405
* Mon Nov 18 2019 Omair Majid <omajid@redhat.com> - 3.1.100-0.5.preview3
- Fix permissions on apphost
- Resolves: RHBZ#1711405
* Mon Nov 18 2019 Omair Majid <omajid@redhat.com> - 3.1.100-0.4.preview3
- Update to .NET Core Runtime 3.1.0-preview3.19553.2 and SDK 3.1.100-preview3-014645
- Resolves: RHBZ#1711405
- Fix apphost permissions
* Wed Nov 13 2019 Omair Majid <omajid@redhat.com> - 3.1.100-0.3
- Add gating tests
- Resolves: RHBZ#1711405
* Wed Nov 13 2019 Omair Majid <omajid@redhat.com> - 3.1.100-0.2
- Initial import from Fedora into RHEL
- Resolves: RHBZ#1711405
* Fri Nov 15 2019 Omair Majid <omajid@redhat.com> - 3.1.100-0.3.preview3
- Update to .NET Core Runtime 3.1.0-preview3.19553.2 and SDK
3.1.100-preview3-014645
* Wed Nov 06 2019 Omair Majid <omajid@redhat.com> - 3.1.100-0.2
- Update to .NET Core 3.1 Preview 2
@ -737,7 +777,7 @@ rm -rf %{buildroot}%{_libdir}/dotnet/packs/NETStandard.Library.Ref/2.1.0
* Wed Jun 26 2019 Omair Majid <omajid@redhat.com> - 3.0.0-0.6.preview6
- Update to .NET Core Runtime 3.0.0-preview6-27804-01 and SDK 3.0.100-preview6-012264
- Set dotnet installation location in /etc/dotnet/install_location
- Update targetting packs
- Update targeting packs
- Install managed symbols
- Completely conditionalize libunwind bundling

20
gating.yaml Normal file
View File

@ -0,0 +1,20 @@
--- !Policy
product_versions:
- fedora-*
decision_context: bodhi_update_push_testing
subject_type: koji_build
rules:
- !PassingTestCaseRule {test_case_name: fedora-ci.koji-build.tier0.functional}
--- !Policy
product_versions:
- fedora-*
decision_context: bodhi_update_push_stable
subject_type: koji_build
rules:
- !PassingTestCaseRule {test_case_name: fedora-ci.koji-build.tier0.functional}
--- !Policy
product_versions:
- rhel-*
decision_context: osci_compose_gate
rules:
- !PassingTestCaseRule {test_case_name: osci.brew-build.tier0.functional}

51
rename-tarball Executable file
View File

@ -0,0 +1,51 @@
#!/bin/bash
# Usage:
# ./rename-tarball original-name.tar.gz new-name.tar.gz
set -euo pipefail
IFS=$'\n\t'
positional_args=()
while [[ "$#" -gt 0 ]]; do
arg="${1}"
case "${arg}" in
-h|--help)
print_usage
exit 0
;;
*)
positional_args+=("$1")
shift
;;
esac
done
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"
exit 1
fi
original_name=${original_name/%.tar.gz}
new_name=${new_name/.tar.gz}
echo "Original: ${original_name}.tar.gz"
echo "New name: ${new_name}.tar.gz"
mkdir "temp-${new_name}"
pushd "temp-${new_name}"
tar xf "${original_path}"
mv -- * "${new_name}"
tar czf ../"${new_name}.tar.gz" "${new_name}"
rm -rf "${new_name}"
popd
rmdir "temp-${new_name}"

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,21 @@
From c82976fd5eb4cbcf67faaba62f0bc59634d30338 Mon Sep 17 00:00:00 2001
From: Chris Rummel <crummel@microsoft.com>
Date: Fri, 14 Aug 2020 15:34:07 -0500
Subject: [PATCH] Disable XLiff warning as error
---
repos/xliff-tasks.proj | 1 +
1 file changed, 1 insertion(+)
diff --git a/repos/xliff-tasks.proj b/repos/xliff-tasks.proj
index da2ae79c5b..9b86754018 100644
--- a/repos/xliff-tasks.proj
+++ b/repos/xliff-tasks.proj
@@ -7,6 +7,7 @@
<BuildCommandArgs>$(BuildCommandArgs) /v:$(LogVerbosity)</BuildCommandArgs>
<BuildCommandArgs>$(BuildCommandArgs) /flp:Verbosity=Diag</BuildCommandArgs>
<BuildCommandArgs>$(BuildCommandArgs) /bl</BuildCommandArgs>
+ <BuildCommandArgs>$(BuildCommandArgs) /p:TreatWarningsAsErrors=false</BuildCommandArgs>
<BuildCommandArgs>$(BuildCommandArgs) $(RedirectRepoOutputToLog)</BuildCommandArgs>
<BuildCommand>$(DotnetToolCommand) $(BuildCommandArgs)</BuildCommand>

1
sources Normal file
View File

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

1
tests/.fmf/version Normal file
View File

@ -0,0 +1 @@
2

6
tests/provision.fmf Normal file
View File

@ -0,0 +1,6 @@
---
standard-inventory-qcow2:
qemu:
m: 5G

34
tests/tests.yml Normal file
View File

@ -0,0 +1,34 @@
---
- hosts: localhost
roles:
- role: standard-test-basic
tags:
- classic
- container
- atomic
repositories:
- repo: "https://github.com/redhat-developer/dotnet-regular-tests.git"
dest: "dotnet-regular-tests"
version: "main"
tests:
- download_test_runner:
dir: ./
run: wget --no-verbose https://github.com/redhat-developer/dotnet-bunny/releases/latest/download/turkey-$(uname -m) -O turkey && chmod +x ./turkey
- print_test_runner_version:
dir: ./
run: ./turkey --version
- regular:
dir: ./
run: ./turkey -l={{ remote_artifacts }} dotnet-regular-tests
required_packages:
- bash-completion
- binutils
- compat-openssl11
- expect
- jq
- lldb
- npm
- python3
- strace
- wget
- which

95
update-release Executable file
View File

@ -0,0 +1,95 @@
#!/bin/bash
# Usage:
# ./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 [--bug bug-id] [--tarball tarball-name]"
}
user_provided_tarball_name=""
positional_args=()
bug_ids=()
while [[ "$#" -gt 0 ]]; do
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
;;
esac
done
spec_files=( ./*.spec )
spec_file="${spec_files[0]}"
sdk_version=${positional_args[0]:-}
if [[ -z ${sdk_version} ]]; then
echo "error: missing sdk version"
exit 1
fi
runtime_version=${positional_args[1]:-}
if [[ -z ${runtime_version} ]]; then
echo "error: missing runtime version"
exit 1
fi
host_version="$runtime_version"
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
sed -i -E "s|^%global host_version [[:digit:]]\.[[:digit:]]\.[[:digit:]]+|%global host_version ${host_version}|" "$spec_file"
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 SDK ${sdk_version} and Runtime ${runtime_version}"
for bug_id in "${bug_ids[@]}"; do
comment="$comment
- Resolves: RHBZ#$bug_id"
done
rpmdev-bumpspec --comment="$comment" "$spec_file"
# Reset release to 1 in 'Release' tag
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"