import dotnet3.1-3.1.118-1.el9

This commit is contained in:
CentOS Sources 2021-11-03 17:54:43 -04:00 committed by Stepan Oksanichenko
commit c1a05ffdef
23 changed files with 5673 additions and 0 deletions

1
.dotnet3.1.metadata Normal file
View File

@ -0,0 +1 @@
a7bd4df33c2e8e207f3ffb03135b917468a05dd3 SOURCES/dotnet-v3.1.118-SDK.tar.gz

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
SOURCES/dotnet-v3.1.118-SDK.tar.gz

136
SOURCES/check-debug-symbols.py Executable file
View File

@ -0,0 +1,136 @@
#!/usr/bin/python3
"""
Check debug symbols are present in shared object and can identify
code.
It starts scanning from a directory and recursively scans all ELF
files found in it for various symbols to ensure all debuginfo is
present and nothing has been stripped.
Usage:
./check-debug-symbols /path/of/dir/to/scan/
Example:
./check-debug-symbols /usr/lib64
"""
# This technique was explained to me by Mark Wielaard (mjw).
import collections
import os
import re
import subprocess
import sys
ScanResult = collections.namedtuple('ScanResult',
'file_name debug_info debug_abbrev file_symbols gnu_debuglink')
def scan_file(file):
"Scan the provided file and return a ScanResult containing results of the scan."
# Test for .debug_* sections in the shared object. This is the main test.
# Stripped objects will not contain these.
readelf_S_result = subprocess.run(['eu-readelf', '-S', file],
stdout=subprocess.PIPE, encoding='utf-8', check=True)
has_debug_info = any(line for line in readelf_S_result.stdout.split('\n') if '] .debug_info' in line)
has_debug_abbrev = any(line for line in readelf_S_result.stdout.split('\n') if '] .debug_abbrev' in line)
# Test FILE symbols. These will most likely be removed by anyting that
# manipulates symbol tables because it's generally useless. So a nice test
# that nothing has messed with symbols.
def contains_file_symbols(line):
parts = line.split()
if len(parts) < 8:
return False
return \
parts[2] == '0' and parts[3] == 'FILE' and parts[4] == 'LOCAL' and parts[5] == 'DEFAULT' and \
parts[6] == 'ABS' and re.match(r'((.*/)?[-_a-zA-Z0-9]+\.(c|cc|cpp|cxx))?', parts[7])
readelf_s_result = subprocess.run(["eu-readelf", '-s', file],
stdout=subprocess.PIPE, encoding='utf-8', check=True)
has_file_symbols = any(line for line in readelf_s_result.stdout.split('\n') if contains_file_symbols(line))
# Test that there are no .gnu_debuglink sections pointing to another
# debuginfo file. There shouldn't be any debuginfo files, so the link makes
# no sense either.
has_gnu_debuglink = any(line for line in readelf_s_result.stdout.split('\n') if '] .gnu_debuglink' in line)
return ScanResult(file, has_debug_info, has_debug_abbrev, has_file_symbols, has_gnu_debuglink)
def is_elf(file):
result = subprocess.run(['file', file], stdout=subprocess.PIPE, encoding='utf-8', check=True)
return re.search('ELF 64-bit LSB (?:executable|shared object)', result.stdout)
def scan_file_if_sensible(file):
if is_elf(file):
# print(file)
return scan_file(file)
return None
def scan_dir(dir):
results = []
for root, _, files in os.walk(dir):
for name in files:
result = scan_file_if_sensible(os.path.join(root, name))
if result:
results.append(result)
return results
def scan(file):
file = os.path.abspath(file)
if os.path.isdir(file):
return scan_dir(file)
elif os.path.isfile(file):
return [scan_file_if_sensible(file)]
def is_bad_result(result):
return not result.debug_info or not result.debug_abbrev or not result.file_symbols or result.gnu_debuglink
def print_scan_results(results, verbose):
# print(results)
for result in results:
file_name = result.file_name
found_issue = False
if not result.debug_info:
found_issue = True
print('error: missing .debug_info section in', file_name)
if not result.debug_abbrev:
found_issue = True
print('error: missing .debug_abbrev section in', file_name)
if not result.file_symbols:
found_issue = True
print('error: missing FILE symbols in', file_name)
if result.gnu_debuglink:
found_issue = True
print('error: unexpected .gnu_debuglink section in', file_name)
if verbose and not found_issue:
print('OK: ', file_name)
def main(args):
verbose = False
files = []
for arg in args:
if arg == '--verbose' or arg == '-v':
verbose = True
else:
files.append(arg)
results = []
for file in files:
results.extend(scan(file))
print_scan_results(results, verbose)
if any(is_bad_result(result) for result in results):
return 1
return 0
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))

View File

@ -0,0 +1,18 @@
diff --git a/src/dotnet/Program.cs b/src/dotnet/Program.cs
index de1ebb9e6..6bbf479de 100644
--- a/src/dotnet/Program.cs
+++ b/src/dotnet/Program.cs
@@ -28,6 +28,13 @@ public class Program
public static int Main(string[] args)
{
+ // opt out of telemetry by default if the env var is unset
+ string telemetryValue = Environment.GetEnvironmentVariable("DOTNET_CLI_TELEMETRY_OPTOUT");
+ if (String.IsNullOrEmpty(telemetryValue))
+ {
+ Environment.SetEnvironmentVariable("DOTNET_CLI_TELEMETRY_OPTOUT", "1");
+ }
+
DebugHelper.HandleDebugSwitch(ref args);
new MulticoreJitActivator().TryActivateMulticoreJit();

View File

@ -0,0 +1,46 @@
From 1864630f762160e1cb439362cc0577471624192a Mon Sep 17 00:00:00 2001
From: Omair Majid <omajid@redhat.com>
Date: Fri, 19 Jul 2019 19:18:51 -0400
Subject: [PATCH] Fix up cgroup2fs in Interop.MountPoints.FormatInfo
`stat -fc %T /sys/fs/cgroup` calls this file system `cgroup2fs`
Add the cgroup2fs file system magic number. Available from:
- https://www.kernel.org/doc/Documentation/cgroup-v2.txt
- man 2 statfs
Move cgroup2fs next to cgroupfs in the drive type list, since it is also
DriveType.Ram.
---
.../Unix/System.Native/Interop.MountPoints.FormatInfo.cs | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/Common/src/Interop/Unix/System.Native/Interop.MountPoints.FormatInfo.cs b/src/Common/src/Interop/Unix/System.Native/Interop.MountPoints.FormatInfo.cs
index af38a2285ba2..4240bd4853ab 100644
--- a/src/Common/src/Interop/Unix/System.Native/Interop.MountPoints.FormatInfo.cs
+++ b/src/Common/src/Interop/Unix/System.Native/Interop.MountPoints.FormatInfo.cs
@@ -47,6 +47,7 @@ internal enum UnixFileSystemTypes : long
btrfs = 0x9123683E,
ceph = 0x00C36400,
cgroupfs = 0x0027E0EB,
+ cgroup2fs = 0x63677270,
cifs = 0xFF534D42,
coda = 0x73757245,
coherent = 0x012FF7B7,
@@ -231,7 +232,6 @@ private static DriveType GetDriveType(string fileSystemName)
case "bpf_fs":
case "btrfs":
case "btrfs_test":
- case "cgroup2fs":
case "coh":
case "daxfs":
case "drvfs":
@@ -384,6 +384,7 @@ private static DriveType GetDriveType(string fileSystemName)
case "binfmt_misc":
case "cgroup":
case "cgroupfs":
+ case "cgroup2fs":
case "configfs":
case "cramfs":
case "cramfs-wend":

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,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

@ -0,0 +1,40 @@
diff --git a/src/Native/Unix/CMakeLists.txt b/src/Native/Unix/CMakeLists.txt
index 7d804a1e54..717c2718d7 100644
--- a/src/Native/Unix/CMakeLists.txt
+++ b/src/Native/Unix/CMakeLists.txt
@@ -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)
if(CMAKE_SYSTEM_NAME STREQUAL Emscripten)
set(CLR_CMAKE_PLATFORM_WASM 1)
diff --git a/src/Native/Unix/configure.cmake b/src/Native/Unix/configure.cmake
index f4a30ad6cb..f2db68402a 100644
--- a/src/Native/Unix/configure.cmake
+++ b/src/Native/Unix/configure.cmake
@@ -27,6 +27,12 @@ else ()
message(FATAL_ERROR "Unknown platform. Cannot define PAL_UNIX_NAME, used by RuntimeInformation.")
endif ()
+
+set (PREVIOUS_CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
+set (CMAKE_CXX_FLAGS "-D_GNU_SOURCE")
+set (PREVIOUS_CMAKE_C_FLAGS ${CMAKE_C_FLAGS})
+set (CMAKE_C_FLAGS "-D_GNU_SOURCE")
+
# We compile with -Werror, so we need to make sure these code fragments compile without warnings.
# Older CMake versions (3.8) do not assign the result of their tests, causing unused-value errors
# which are not distinguished from the test failing. So no error for that one.
@@ -698,6 +704,9 @@ endif()
set (CMAKE_REQUIRED_LIBRARIES)
+set (CMAKE_CXX_FLAGS "${PREVIOUS_CMAKE_CXX_FLAGS}")
+set (CMAKE_C_FLAGS "${PREVIOUS_CMAKE_C_FLAGS}")
+
check_c_source_compiles(
"
#include <sys/inotify.h>

14
SOURCES/dotnet.sh.in Normal file
View File

@ -0,0 +1,14 @@
# Set location for AppHost lookup
[ -z "$DOTNET_ROOT" ] && export DOTNET_ROOT=@LIBDIR@/dotnet
# Add dotnet tools directory to PATH
DOTNET_TOOLS_PATH="$HOME/.dotnet/tools"
case "$PATH" in
*"$DOTNET_TOOLS_PATH"* ) true ;;
* ) PATH="$PATH:$DOTNET_TOOLS_PATH" ;;
esac
# Extract self-contained executables under HOME
# to avoid multi-user issues from using the default '/var/tmp'.
[ -z "$DOTNET_BUNDLE_EXTRACT_BASE_DIR" ] && export DOTNET_BUNDLE_EXTRACT_BASE_DIR="${XDG_CACHE_HOME:-"$HOME"/.cache}/dotnet_bundle_extract"

View File

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

View File

@ -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>

900
SPECS/dotnet3.1.spec Normal file
View File

@ -0,0 +1,900 @@
%bcond_with bootstrap
# Avoid provides/requires from private libraries
%global privlibs libhostfxr
%global privlibs %{privlibs}|libclrjit
%global privlibs %{privlibs}|libcoreclr
%global privlibs %{privlibs}|libcoreclrtraceptprovider
%global privlibs %{privlibs}|libdbgshim
%global privlibs %{privlibs}|libhostpolicy
%global privlibs %{privlibs}|libmscordaccore
%global privlibs %{privlibs}|libmscordbi
%global privlibs %{privlibs}|libsos
%global privlibs %{privlibs}|libsosplugin
%global __provides_exclude ^(%{privlibs})\\.so
%global __requires_exclude ^(%{privlibs})\\.so
# 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.18
%global runtime_version 3.1.18
%global aspnetcore_runtime_version %{runtime_version}
%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 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
%global use_bundled_libunwind 0
%else
%global use_bundled_libunwind 1
%endif
%ifarch aarch64
%global use_bundled_libunwind 1
%endif
%ifarch x86_64
%global runtime_arch x64
%endif
%ifarch aarch64
%global runtime_arch arm64
%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 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/
# 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
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
# 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
# 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
BuildRequires: coreutils
%if %{without bootstrap}
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
%endif
BuildRequires: hostname
BuildRequires: krb5-devel
BuildRequires: libcurl-devel
BuildRequires: libicu-devel
%if ! %{use_bundled_libunwind}
BuildRequires: libunwind-devel
%endif
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
%description
.NET Core is a fast, lightweight and modular platform for creating
cross platform applications that work on Linux, macOS and Windows.
It particularly focuses on creating console applications, web
applications and micro-services.
.NET Core contains a runtime conforming to .NET Standards a set of
framework libraries, an SDK containing compilers and a 'dotnet'
application to drive everything.
%package -n dotnet
Version: %{sdk_rpm_version}
Summary: .NET Core CLI tools and runtime
Requires: dotnet-sdk-3.1%{?_isa} >= %{sdk_rpm_version}-%{release}
%description -n dotnet
.NET Core is a fast, lightweight and modular platform for creating
cross platform applications that work on Linux, macOS and Windows.
It particularly focuses on creating console applications, web
applications and micro-services.
.NET Core contains a runtime conforming to .NET Standards a set of
framework libraries, an SDK containing compilers and a 'dotnet'
application to drive everything.
%package -n dotnet-host
Version: %{host_rpm_version}
Summary: .NET command line launcher
%description -n dotnet-host
The .NET Core host is a command line program that runs a standalone
.NET core application or launches the SDK.
.NET Core is a fast, lightweight and modular platform for creating
cross platform applications that work on Linux, Mac and Windows.
It particularly focuses on creating console applications, web
applications and micro-services.
%package -n dotnet-hostfxr-3.1
Version: %{host_rpm_version}
Summary: .NET Core command line host resolver
# Theoretically any version of the host should work. But lets aim for the one
# provided by this package, or from a newer version of .NET Core
Requires: dotnet-host%{?_isa} >= %{host_rpm_version}-%{release}
%description -n dotnet-hostfxr-3.1
The .NET Core host resolver contains the logic to resolve and select
the right version of the .NET Core SDK or runtime to use.
.NET Core is a fast, lightweight and modular platform for creating
cross platform applications that work on Linux, Mac and Windows.
It particularly focuses on creating console applications, web
applications and micro-services.
%package -n dotnet-runtime-3.1
Version: %{runtime_rpm_version}
Summary: NET Core 3.1 runtime
Requires: dotnet-hostfxr-3.1%{?_isa} >= %{host_rpm_version}-%{release}
# libicu is dlopen()ed
Requires: libicu%{?_isa}
%if %{use_bundled_libunwind}
Provides: bundled(libunwind) = 1.3
%endif
%description -n dotnet-runtime-3.1
The .NET Core runtime contains everything needed to run .NET Core applications.
It includes a high performance Virtual Machine as well as the framework
libraries used by .NET Core applications.
.NET Core is a fast, lightweight and modular platform for creating
cross platform applications that work on Linux, Mac and Windows.
It particularly focuses on creating console applications, web
applications and micro-services.
%package -n aspnetcore-runtime-3.1
Version: %{aspnetcore_runtime_rpm_version}
Summary: ASP.NET Core 3.1 runtime
Requires: dotnet-runtime-3.1%{?_isa} >= %{runtime_rpm_version}-%{release}
%description -n aspnetcore-runtime-3.1
The ASP.NET Core runtime contains everything needed to run .NET Core
web applications. It includes a high performance Virtual Machine as
well as the framework libraries used by .NET Core applications.
ASP.NET Core is a fast, lightweight and modular platform for creating
cross platform web applications that work on Linux, Mac and Windows.
It particularly focuses on creating console applications, web
applications and micro-services.
%package -n dotnet-templates-3.1
Version: %{sdk_rpm_version}
Summary: .NET Core 3.1 templates
# Theoretically any version of the host should work. But lets aim for the one
# provided by this package, or from a newer version of .NET Core
Requires: dotnet-host%{?_isa} >= %{host_rpm_version}-%{release}
%description -n dotnet-templates-3.1
This package contains templates used by the .NET Core SDK.
ASP.NET Core is a fast, lightweight and modular platform for creating
cross platform web applications that work on Linux, Mac and Windows.
It particularly focuses on creating console applications, web
applications and micro-services.
%package -n dotnet-sdk-3.1
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}
Requires: dotnet-apphost-pack-3.1%{?_isa} >= %{runtime_rpm_version}-%{release}
Requires: dotnet-targeting-pack-3.1%{?_isa} >= %{runtime_rpm_version}-%{release}
Requires: aspnetcore-targeting-pack-3.1%{?_isa} >= %{aspnetcore_runtime_rpm_version}-%{release}
Requires: netstandard-targeting-pack-2.1%{?_isa} >= %{sdk_rpm_version}-%{release}
Requires: dotnet-templates-3.1%{?_isa} >= %{sdk_rpm_version}-%{release}
%description -n dotnet-sdk-3.1
The .NET Core SDK is a collection of command line applications to
create, build, publish and run .NET Core applications.
.NET Core is a fast, lightweight and modular platform for creating
cross platform applications that work on Linux, Mac and Windows.
It particularly focuses on creating console applications, web
applications and micro-services.
%global dotnet_targeting_pack() %{expand:
%package -n %{1}
Version: %{2}
Summary: Targeting Pack for %{3} %{4}
Requires: dotnet-host%{?_isa}
%description -n %{1}
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.
%files -n %{1}
%dir %{_libdir}/dotnet/packs
%{_libdir}/dotnet/packs/%{5}
}
%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
%package -n dotnet-sdk-3.1-source-built-artifacts
Version: %{sdk_rpm_version}
Summary: Internal package for building .NET Core 3.1 Software Development Kit
%description -n dotnet-sdk-3.1-source-built-artifacts
The .NET Core source-built archive is a collection of packages needed
to build the .NET Core SDK itself.
These are not meant for general use.
%prep
%setup -q -n dotnet-v%{src_version}-SDK
%if %{without bootstrap}
# Remove all prebuilts
find -iname '*.dll' -type f -delete
find -iname '*.so' -type f -delete
find -iname '*.tar.gz' -type f -delete
find -iname '*.nupkg' -type f -delete
find -iname '*.zip' -type f -delete
rm -rf .dotnet/
rm -rf packages/source-built
%endif
%if %{without bootstrap}
mkdir -p packages/archive
ln -s %{_libdir}/dotnet/source-built-artifacts/*.tar.gz packages/archive/
ln -s %{_libdir}/dotnet/reference-packages/Private.SourceBuild.ReferencePackages*.tar.gz packages/archive
%endif
# Fix bad hardcoded path in build
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.proj
%patch1 -p1
%patch2 -p1
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/coreclr.*
#%%patch200 -p1
#%%patch201 -p1
popd
pushd src/core-setup.*
popd
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
%if %{use_bundled_libunwind}
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 \;
%build
cat /etc/os-release
%if %{without bootstrap}
# We need to create a copy because we will mutate this
cp -a %{_libdir}/dotnet previously-built-dotnet
%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}
--with-sdk previously-built-dotnet \
%endif
-- \
/v:n \
/p:SkipPortableRuntimeBuild=true \
/p:LogVerbosity=n \
/p:MinimalConsoleLogOutput=false \
/p:ContinueOnPrebuiltBaselineError=true \
sed -e 's|[@]LIBDIR[@]|%{_libdir}|g' %{SOURCE2} > dotnet.sh
%install
install -dm 0755 %{buildroot}%{_libdir}/dotnet
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
tar xf artifacts/%{runtime_arch}/Release/runtime/dotnet-runtime-symbols-%{runtime_version}-%{runtime_id}.tar.gz \
-C %{buildroot}/%{_libdir}/dotnet/shared/Microsoft.NETCore.App/%{runtime_version}/
# Fix executable permissions on files
find %{buildroot}%{_libdir}/dotnet/ -type f -name '*.dll' -exec chmod -x {} \;
find %{buildroot}%{_libdir}/dotnet/ -type f -name '*.pdb' -exec chmod -x {} \;
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 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
install -dm 0755 %{buildroot}%{_sysconfdir}/profile.d/
install dotnet.sh %{buildroot}%{_sysconfdir}/profile.d/
install -dm 0755 %{buildroot}/%{_datadir}/bash-completion/completions
# dynamic completion needs the file to be named the same as the base command
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/cli/scripts/register-completions.zsh %%{buildroot}/%%{_datadir}/zsh/site-functions/_dotnet
install -dm 0755 %{buildroot}%{_bindir}
ln -s ../../%{_libdir}/dotnet/dotnet %{buildroot}%{_bindir}/
install -dm 0755 %{buildroot}%{_mandir}/man1/
find -iname 'dotnet*.1' -type f -exec cp {} %{buildroot}%{_mandir}/man1/ \;
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/
# Check debug symbols in all elf objects. This is not in %%check
# 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..."
%{SOURCE1} -v %{buildroot}%{_libdir}/dotnet/
%check
%{buildroot}%{_libdir}/dotnet/dotnet --info
%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
%{_libdir}/dotnet/host/fxr/%{host_version}
%files -n dotnet-runtime-3.1
%dir %{_libdir}/dotnet/shared
%dir %{_libdir}/dotnet/shared/Microsoft.NETCore.App
%{_libdir}/dotnet/shared/Microsoft.NETCore.App/%{runtime_version}
%files -n aspnetcore-runtime-3.1
%dir %{_libdir}/dotnet/shared
%dir %{_libdir}/dotnet/shared/Microsoft.AspNetCore.App
%{_libdir}/dotnet/shared/Microsoft.AspNetCore.App/%{aspnetcore_runtime_version}
%files -n dotnet-templates-3.1
%dir %{_libdir}/dotnet/templates
%{_libdir}/dotnet/templates/%{templates_version}
%files -n dotnet-sdk-3.1
%dir %{_libdir}/dotnet/sdk
%{_libdir}/dotnet/sdk/%{sdk_version}
%dir %{_libdir}/dotnet/packs
%files -n dotnet-sdk-3.1-source-built-artifacts
%dir %{_libdir}/dotnet
%{_libdir}/dotnet/source-built-artifacts
%changelog
* Fri Aug 27 2021 Omair Majid <omajid@redhat.com> - 3.1.118-1
- Update to .NET SDK 3.1.118 and Runtime 3.1.18
- Resolves: RHBZ#1961848
* Tue Aug 24 2021 Omair Majid <omajid@redhat.com> - 3.1.117-2
- Fix building and running against OpenSSL 3.0
- Resolves: RHBZ#1991050
* Thu Aug 12 2021 Omair Majid <omajid@redhat.com> - 3.1.117-1
- Update to .NET SDK 3.1.117 and Runtime 3.1.17
- Resolves: RHBZ#1961848
* Mon Aug 09 2021 Mohan Boddu <mboddu@redhat.com> - 3.1.116-3
- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
Related: rhbz#1991688
* Wed Jun 16 2021 Mohan Boddu <mboddu@redhat.com> - 3.1.116-2
- Rebuilt for RHEL 9 BETA for openssl 3.0
Related: rhbz#1971065
* Fri Jun 11 2021 Omair Majid <omajid@redhat.com> - 3.1.116-1
- Update to .NET SDK 3.1.116 and Runtime 3.1.16
- Resolves: RHBZ#1961848
* Mon Jun 07 2021 Omair Majid <omajid@redhat.com> - 3.1.115-2
- Support building against OpenSSL 3.0
- Resolves: RHBZ#1965045
* Tue May 18 2021 Omair Majid <omajid@redhat.com> - 3.1.115-1
- Update to .NET SDK 3.1.115 and Runtime 3.1.15
- Resolves: RHBZ#1961848
* Wed Apr 21 2021 Omair Majid <omajid@redhat.com> - 3.1.113-3
- Fix build by adding CentOS 9 RIDs
- Resolves: RHBZ#1951312
* 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
* 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
* 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
* 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
* Mon Sep 21 2020 Tom Stellard <tstellar@redhat.com> - 3.1.108-2
- Use toolchain macro for setting clang-specific c/ld flags
* 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 11 2020 Omair Majid <omajid@redhat.com> - 3.1.108-1
- Update to .NET Core SDK 3.1.108 and Runtime 3.1.8
* Wed Sep 09 2020 Omair Majid <omajid@redhat.com> - 3.1.107-1
- Add Fedora 34 RID
- Fix build of bundled libunwind
* 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 Aug 13 2020 Omair Majid <omajid@redhat.com> - 3.1.106-3
- Filter out -mbranch-protection=standard from cflags
* 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
* Mon Jul 27 2020 Fedora Release Engineering <releng@fedoraproject.org> - 3.1.106-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
* 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
* Tue Jul 21 2020 Omair Majid <omajid@redhat.com> - 3.1.105-5
- Fix up commented-out define for disabling LTO
* Mon Jul 20 2020 Jeff Law <law@redhat.com> - 3.1.105-5
- Disable LTO
* 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
* 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
* 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
* 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
* 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
* 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
* Mon Nov 18 2019 Omair Majid <omajid@redhat.com> - 3.1.100-0.4.preview3
- Fix apphost permissions
* 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
* Wed Oct 30 2019 Omair Majid <omajid@redhat.com> - 3.1.100-0.1
- Update to .NET Core 3.1 Preview 1
* Thu Oct 24 2019 Omair Majid <omajid@redhat.com> - 3.0.100-5
- Add cgroupv2 support to .NET Core
* Wed Oct 16 2019 Omair Majid <omajid@redhat.com> - 3.0.100-4
- Include fix from coreclr for building on Fedora 32
* Wed Oct 16 2019 Omair Majid <omajid@redhat.com> - 3.0.100-3
- Harden built binaries to pass annocheck
* Fri Oct 11 2019 Omair Majid <omajid@redhat.com> - 3.0.100-2
- Export DOTNET_ROOT in profile to make apphost lookup work
* Fri Sep 27 2019 Omair Majid <omajid@redhat.com> - 3.0.100-1
- Update to .NET Core Runtime 3.0.0 and SDK 3.0.100
* Wed Sep 25 2019 Omair Majid <omajid@redhat.com> - 3.0.100-0.18.rc1
- Update to .NET Core Runtime 3.0.0-rc1-19456-20 and SDK 3.0.100-rc1-014190
* Tue Sep 17 2019 Omair Majid <omajid@redhat.com> - 3.0.100-0.16.preview9
- Fix files duplicated between dotnet-apphost-pack-3.0 and dotnet-targeting-pack-3.0
- Fix dependencies between .NET SDK and the targeting packs
* Mon Sep 16 2019 Omair Majid <omajid@redhat.com> - 3.0.100-0.15.preview9
- Update to .NET Core Runtime 3.0.0-preview 9 and SDK 3.0.100-preview9
* Mon Aug 19 2019 Omair Majid <omajid@redhat.com> - 3.0.100-0.11.preview8
- Update to .NET Core Runtime 3.0.0-preview8-28405-07 and SDK
3.0.100-preview8-013656
* Tue Jul 30 2019 Omair Majid <omajid@redhat.com> - 3.0.100-0.9.preview7
- Update to .NET Core Runtime 3.0.0-preview7-27912-14 and SDK
3.0.100-preview7-012821
* Fri Jul 26 2019 Omair Majid <omajid@redhat.com> - 3.0.100-0.8.preview7
- Update to .NET Core Runtime 3.0.0-preview7-27902-19 and SDK
3.0.100-preview7-012802
* Wed Jun 26 2019 Omair Majid <omajid@redhat.com> - 3.0.0-0.7.preview6
- Obsolete dotnet-sdk-3.0.1xx
- Add supackages for targeting packs
- Add -fcf-protection to CFLAGS
* 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 targeting packs
- Install managed symbols
- Completely conditionalize libunwind bundling
* Tue May 07 2019 Omair Majid <omajid@redhat.com> - 3.0.0-0.3.preview4
- Update to .NET Core 3.0 preview 4
* Tue Dec 18 2018 Omair Majid <omajid@redhat.com> - 3.0.0-0.1.preview1
- Update to .NET Core 3.0 preview 1
* Fri Dec 07 2018 Omair Majid <omajid@redhat.com> - 2.2.100
- Update to .NET Core 2.2.0
* Wed Nov 07 2018 Omair Majid <omajid@redhat.com> - 2.2.100-0.2.preview3
- Update to .NET Core 2.2.0-preview3
* Fri Nov 02 2018 Omair Majid <omajid@redhat.com> - 2.1.403-3
- Add host-fxr-2.1 subpackage
* Mon Oct 15 2018 Omair Majid <omajid@redhat.com> - 2.1.403-2
- Disable telemetry by default
- Users have to manually export DOTNET_CLI_TELEMETRY_OPTOUT=0 to enable
* Tue Oct 02 2018 Omair Majid <omajid@redhat.com> - 2.1.403-1
- Update to .NET Core Runtime 2.1.5 and SDK 2.1.403
* Wed Sep 26 2018 Omair Majid <omajid@redhat.com> - 2.1.402-2
- Add ~/.dotnet/tools to $PATH to make it easier to use dotnet tools
* Thu Sep 13 2018 Omair Majid <omajid@redhat.com> - 2.1.402-1
- Update to .NET Core Runtime 2.1.4 and SDK 2.1.402
* Wed Sep 05 2018 Omair Majid <omajid@redhat.com> - 2.1.401-2
- Use distro-standard flags when building .NET Core
* Tue Aug 21 2018 Omair Majid <omajid@redhat.com> - 2.1.401-1
- Update to .NET Core Runtime 2.1.3 and SDK 2.1.401
* Mon Aug 20 2018 Omair Majid <omajid@redhat.com> - 2.1.302-1
- Update to .NET Core Runtime 2.1.2 and SDK 2.1.302
* Fri Jul 20 2018 Omair Majid <omajid@redhat.com> - 2.1.301-1
- Update to .NET Core 2.1
* Thu May 03 2018 Omair Majid <omajid@redhat.com> - 2.0.7-1
- Update to .NET Core 2.0.7
* Wed Mar 28 2018 Omair Majid <omajid@redhat.com> - 2.0.6-2
- Enable bash completion for dotnet
- Remove redundant buildrequires and requires
* Wed Mar 14 2018 Omair Majid <omajid@redhat.com> - 2.0.6-1
- Update to .NET Core 2.0.6
* Fri Feb 23 2018 Omair Majid <omajid@redhat.com> - 2.0.5-1
- Update to .NET Core 2.0.5
* Wed Jan 24 2018 Omair Majid <omajid@redhat.com> - 2.0.3-5
- Don't apply corefx clang warnings fix on clang < 5
* Fri Jan 19 2018 Omair Majid <omajid@redhat.com> - 2.0.3-4
- Add a test script to sanity check debug and symbol info.
- Build with clang 5.0
- Make main package real instead of using a virtual provides (see RHBZ 1519325)
* Wed Nov 29 2017 Omair Majid <omajid@redhat.com> - 2.0.3-3
- Add a Provides for 'dotnet'
- Fix conditional macro
* Tue Nov 28 2017 Omair Majid <omajid@redhat.com> - 2.0.3-2
- Fix build on Fedora 27
* Fri Nov 17 2017 Omair Majid <omajid@redhat.com> - 2.0.3-1
- Update to .NET Core 2.0.3
* Thu Oct 19 2017 Omair Majid <omajid@redhat.com> - 2.0.0-4
- Add a hack to let omnisharp work
* Wed Aug 30 2017 Omair Majid <omajid@redhat.com> - 2.0.0-3
- Add a patch for building coreclr and core-setup correctly on Fedora >= 27
* Fri Aug 25 2017 Omair Majid <omajid@redhat.com> - 2.0.0-2
- Move libicu/libcurl/libunwind requires to runtime package
- Make sdk depend on the exact version of the runtime package
* Thu Aug 24 2017 Omair Majid <omajid@redhat.com> - 2.0.0-1
- Update to 2.0.0 final release
* Wed Jul 26 2017 Omair Majid <omajid@redhat.com> - 2.0.0-0.3.preview2
- Add man pages
* Tue Jul 25 2017 Omair Majid <omajid@redhat.com> - 2.0.0-0.2.preview2
- Add Requires on libicu
- Split into multiple packages
- Do not repeat first-run message
* Fri Jul 21 2017 Omair Majid <omajid@redhat.com> - 2.0.0-0.1.preview2
- Update to .NET Core 2.0 Preview 2
* Thu Mar 16 2017 Nemanja Milošević <nmilosevnm@gmail.com> - 1.1.0-7
- rebuilt with latest libldb
* Wed Feb 22 2017 Nemanja Milosevic <nmilosev@fedoraproject.org> - 1.1.0-6
- compat-openssl 1.0 for F26 for now
* Sun Feb 19 2017 Nemanja Milosevic <nmilosev@fedoraproject.org> - 1.1.0-5
- Fix wrong commit id's
* Sat Feb 18 2017 Nemanja Milosevic <nmilosev@fedoraproject.org> - 1.1.0-4
- Use commit id's instead of branch names
* Sat Feb 18 2017 Nemanja Milosevic <nmilosev@fedoraproject.org> - 1.1.0-3
- Improper patch5 fix
* Sat Feb 18 2017 Nemanja Milosevic <nmilosev@fedoraproject.org> - 1.1.0-2
- SPEC cleanup
- git removal (using all tarballs for reproducible builds)
- more reasonable versioning
* Thu Feb 09 2017 Nemanja Milosevic <nmilosev@fedoraproject.org> - 1.1.0-1
- Fixed debuginfo going to separate package (Patch1)
- Added F25/F26 RIL and fixed the version info (Patch2)
- Added F25/F26 RIL in Microsoft.NETCore.App suported runtime graph (Patch3)
- SPEC file cleanup
* Wed Jan 11 2017 Nemanja Milosevic <nmilosev@fedoraproject.org> - 1.1.0-0
- Initial RPM for Fedora 25/26.