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 4 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 @@ -12,16 +12,28 @@ internal static partial class OpenSsl
private static Version s_opensslVersion;

[DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_OpenSslVersionNumber")]
internal static extern uint OpenSslVersionNumber();
internal static extern long 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));
// 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 = 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);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is this used? I'm just surprised to see us parsing it like this, given that we explicitly opted to expose a long due to it being opaque data. Is this just for test code? And if so, should this OpenSslVersion property be moved into a test assembly somewhere?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this just for test code?

Yeah.

And if so, should this OpenSslVersion property be moved into a test assembly somewhere?

What a remarkably reasonable question that means I have more work to do. Okie dokie 😄.

}

return s_opensslVersion;
Expand Down
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
}
}
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>