Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
/ corefx Public archive

Add API to enable comparision of corefx's OpenSSL with a 3rd party P/Invoke #32900

Merged
merged 5 commits into from
Oct 20, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ internal enum CurlFeatures : int

private static string DetermineRequiredOpenSslDescription()
{
uint ver = Interop.OpenSsl.OpenSslVersionNumber();
long ver = Interop.OpenSsl.OpenSslVersionNumber();

// OpenSSL version numbers are encoded as
// 0xMNNFFPPS: major (one nybble), minor (one byte, unaligned),
Expand Down Expand Up @@ -107,7 +107,7 @@ private static string DetermineRequiredOpenSslDescription()
patch = new string((char)('`' + patchValue), 1);
}

return $"{OpenSslDescriptionPrefix}{ver >> 28:x}.{(byte)(ver >> 20):x}.{(byte)(ver >> 12):x}{patch}";
return $"{OpenSslDescriptionPrefix}{(ver >> 28) & 0xF:x}.{(byte)(ver >> 20):x}.{(byte)(ver >> 12):x}{patch}";
}
#endif
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,13 @@
// 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.Runtime.InteropServices;

internal static partial class Interop
{
internal static partial class OpenSsl
{
private static Version s_opensslVersion;

[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_OpenSslVersionNumber")]
internal static extern uint OpenSslVersionNumber();

internal static Version OpenSslVersion
{
get
{
if (s_opensslVersion == null)
{
uint versionNumber = OpenSslVersionNumber();
s_opensslVersion = new Version((int)(versionNumber >> 28), (int)((versionNumber >> 20) & 0xff), (int)((versionNumber >> 12) & 0xff));
}

return s_opensslVersion;
}
}
internal static extern long OpenSslVersionNumber();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,5 +65,16 @@ public SafeEvpPKeyHandle DuplicateHandle()
safeHandle.SetHandle(handle);
return safeHandle;
}

#if !INTERNAL_ASYMMETRIC_IMPLEMENTATIONS
/// <summary>
/// The runtime version number for the loaded version of OpenSSL.
/// </summary>
/// <remarks>
/// For OpenSSL 1.1+ this is the result of <code>OpenSSL_version_num()</code>,
/// for OpenSSL 1.0.x this is the result of <code>SSLeay()</code>.
/// </remarks>
public static long OpenSslVersion { get; } = Interop.OpenSsl.OpenSslVersionNumber();
#endif
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public static partial class PlatformDetection

public static Version OSXVersion { get; } = ToVersion(Microsoft.DotNet.PlatformAbstractions.RuntimeEnvironment.OperatingSystemVersion);

public static Version OpenSslVersion => RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ? Interop.OpenSsl.OpenSslVersion : throw new PlatformNotSupportedException();
public static Version OpenSslVersion => RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ? GetOpenSslVersion() : throw new PlatformNotSupportedException();

public static string GetDistroVersionString()
{
Expand Down Expand Up @@ -269,6 +269,30 @@ private static Version GetOSXProductVersion()
return new Version(0, 0, 0);
}

private static Version s_opensslVersion;
private static Version GetOpenSslVersion()
{
if (s_opensslVersion == null)
{
// OpenSSL version numbers are encoded as
// 0xMNNFFPPS: major (one nybble), minor (one byte, unaligned),
// "fix" (one byte, unaligned), patch (one byte, unaligned), status (one nybble)
//
// e.g. 1.0.2a final is 0x1000201F
//
// Currently they don't exceed 29-bit values, but we use long here to account
// for the expanded range on their 64-bit C-long return value.
long versionNumber = Interop.OpenSsl.OpenSslVersionNumber();
int major = (int)((versionNumber >> 28) & 0xF);
int minor = (int)((versionNumber >> 20) & 0xFF);
int fix = (int)((versionNumber >> 12) & 0xFF);

s_opensslVersion = new Version(major, minor, fix);
}

return s_opensslVersion;
}

[DllImport("libc", SetLastError = true)]
private static extern int sysctlbyname(string ctlName, byte[] oldp, ref IntPtr oldpLen, byte[] newp, IntPtr newpLen);

Expand Down
4 changes: 2 additions & 2 deletions src/Native/Unix/System.Security.Cryptography.Native/openssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1276,9 +1276,9 @@ Gets the version of openssl library.
Return values:
Version number as MNNFFRBB (major minor fix final beta/patch)
*/
uint32_t CryptoNative_OpenSslVersionNumber()
int64_t CryptoNative_OpenSslVersionNumber()
{
return (uint32_t)OpenSSL_version_num();
return (int64_t)OpenSSL_version_num();
}

#ifdef NEED_OPENSSL_1_0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,4 @@ DLLEXPORT int32_t CryptoNative_LookupFriendlyNameByOid(const char* oidValue, con

DLLEXPORT int32_t CryptoNative_EnsureOpenSslInitialized(void);

DLLEXPORT uint32_t CryptoNative_OpenSslVersionNumber(void);
DLLEXPORT int64_t CryptoNative_OpenSslVersionNumber(void);
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ Returns 1 on success, 0 on failure.
static long TrySetECDHNamedCurve(SSL_CTX* ctx)
{
#ifdef NEED_OPENSSL_1_0
uint32_t version = CryptoNative_OpenSslVersionNumber();
int64_t version = CryptoNative_OpenSslVersionNumber();
long result = 0;

if (version >= OPENSSL_VERSION_1_1_0_RTM)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,5 +93,6 @@ public sealed partial class SafeEvpPKeyHandle : System.Runtime.InteropServices.S
public override bool IsInvalid { get { throw null; } }
public System.Security.Cryptography.SafeEvpPKeyHandle DuplicateHandle() { throw null; }
protected override bool ReleaseHandle() { throw null; }
public static long OpenSslVersion { get; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@
<Compile Include="$(CommonPath)\Interop\Unix\System.Security.Cryptography.Native\Interop.Initialization.cs">
<Link>Common\Interop\Unix\System.Security.Cryptography.Native\Interop.Initialization.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Interop\Unix\System.Security.Cryptography.Native\Interop.OpenSslVersion.cs">
<Link>Common\Interop\Unix\System.Security.Cryptography.Native\Interop.OpenSslVersion.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Interop\Unix\System.Security.Cryptography.Native\Interop.Rsa.cs">
<Link>Common\Interop\Unix\System.Security.Cryptography.Native\Interop.Rsa.cs</Link>
</Compile>
Expand Down Expand Up @@ -162,4 +165,4 @@
<Reference Include="System.Text.Encoding.Extensions" />
<Reference Include="System.Threading" />
</ItemGroup>
</Project>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using Xunit;

namespace System.Security.Cryptography.OpenSsl.Tests
{
public static class SafeEvpPKeyHandleTests
{
[Fact]
public static void TestOpenSslVersion()
{
long version = SafeEvpPKeyHandle.OpenSslVersion;
long version2 = SafeEvpPKeyHandle.OpenSslVersion;

Assert.Equal(version, version2);

// A value representing OpenSSL 1.0.0's development (pre-beta) build.
const long MinValue = 0x10000000;

// Until a platform+build is discovered which violates this constraint, assert that it
// is between 1.0.0-devel and (signed) int.MaxValue as a sanity check on reading the
// value.
//
// NOTE: The OpenSslVersion value should not be depended upon for anything other than
// an equality check, to assert that a component outside of .NET Core which is utilizing
// SafeEvpPKeyHandle is using the same version as .NET Core (to avoid sending the pointers
// from one library into another). The exception is this test, in asserting that we're
// getting "sensible" values.
Assert.InRange(version, MinValue, int.MaxValue);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -153,5 +153,6 @@
<Compile Include="$(CommonTestPath)\System\Security\Cryptography\AlgorithmImplementations\RSA\SignVerify.netcoreapp.cs">
<Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\RSA\SignVerify.netcoreapp.cs</Link>
</Compile>
<Compile Include="SafeEvpPKeyHandleTests.cs" />
</ItemGroup>
</Project>
</Project>