diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/EC/CurveDef.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/EC/CurveDef.cs index b0c5823145a87b..68b29962f0b768 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/EC/CurveDef.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/EC/CurveDef.cs @@ -14,16 +14,15 @@ public CurveDef() { } public bool RequiredOnPlatform; public string DisplayName; - public bool IsCurveValidOnPlatform - { - get - { - // Assume curve is valid if required; tests will fail if not present - return RequiredOnPlatform || - (Curve.IsNamed && (EcDsa.Tests.ECDsaFactory.IsCurveValid(Curve.Oid) || EcDiffieHellman.Tests.ECDiffieHellmanFactory.IsCurveValid(Curve.Oid))) || - (Curve.IsExplicit && (EcDsa.Tests.ECDsaFactory.ExplicitCurvesSupported || EcDiffieHellman.Tests.ECDiffieHellmanFactory.ExplicitCurvesSupported)); - } - } + public bool IsCurveValidOnPlatform(EcDsa.Tests.ECDsaProvider provider) => + RequiredOnPlatform || + (Curve.IsNamed && provider.IsCurveValid(Curve.Oid)) || + (Curve.IsExplicit && provider.ExplicitCurvesSupported); + + public bool IsCurveValidOnPlatform(EcDiffieHellman.Tests.ECDiffieHellmanProvider provider) => + RequiredOnPlatform || + (Curve.IsNamed && provider.IsCurveValid(Curve.Oid)) || + (Curve.IsExplicit && provider.ExplicitCurvesSupported); public bool IsCurveTypeEqual(ECCurve.ECCurveType actual) { diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/EC/ECKeyFileTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/EC/ECKeyFileTests.cs index 1a6686c4326db3..36313ef90136f1 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/EC/ECKeyFileTests.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/EC/ECKeyFileTests.cs @@ -16,28 +16,20 @@ public abstract partial class ECKeyFileTests where T : ECAlgorithm protected virtual Func PublicKeyWriteArrayFunc { get; } = null; protected virtual WriteKeyToSpanFunc PublicKeyWriteSpanFunc { get; } = null; - // This would need to be virtualized if there was ever a platform that - // allowed explicit in ECDH or ECDSA but not the other. - public static bool SupportsExplicitCurves { get; } = - EcDiffieHellman.Tests.ECDiffieHellmanFactory.ExplicitCurvesSupported || - EcDiffieHellman.Tests.ECDiffieHellmanFactory.ExplicitCurvesSupportFailOnUseOnly; + protected abstract bool SupportsExplicitCurves { get; } + protected abstract bool CanDeriveNewPublicKey { get; } - public static bool CanDeriveNewPublicKey { get; } = EcDiffieHellman.Tests.ECDiffieHellmanFactory.CanDeriveNewPublicKey; - - public static bool SupportsBrainpool { get; } = IsCurveSupported(ECCurve.NamedCurves.brainpoolP160r1.Oid); - public static bool SupportsSect163k1 { get; } = IsCurveSupported(EccTestData.Sect163k1Key1.Curve.Oid); - public static bool SupportsSect283k1 { get; } = IsCurveSupported(EccTestData.Sect283k1Key1.Curve.Oid); - public static bool SupportsC2pnb163v1 { get; } = IsCurveSupported(EccTestData.C2pnb163v1Key1.Curve.Oid); + public bool SupportsBrainpool => IsCurveSupported(ECCurve.NamedCurves.brainpoolP160r1.Oid); + public bool SupportsSect163k1 => IsCurveSupported(EccTestData.Sect163k1Key1.Curve.Oid); + public bool SupportsSect283k1 => IsCurveSupported(EccTestData.Sect283k1Key1.Curve.Oid); + public bool SupportsC2pnb163v1 => IsCurveSupported(EccTestData.C2pnb163v1Key1.Curve.Oid); // Some platforms support explicitly specifying these curves, but do not support specifying them by name. - public static bool ExplicitNamedSameSupport { get; } = !PlatformDetection.IsAndroid; - public static bool SupportsSect163k1Explicit { get; } = SupportsSect163k1 || (!ExplicitNamedSameSupport && SupportsExplicitCurves); - public static bool SupportsC2pnb163v1Explicit { get; } = SupportsC2pnb163v1 || (!ExplicitNamedSameSupport && SupportsExplicitCurves); + public bool ExplicitNamedSameSupport => !PlatformDetection.IsAndroid; + public bool SupportsSect163k1Explicit => SupportsSect163k1 || (!ExplicitNamedSameSupport && SupportsExplicitCurves); + public bool SupportsC2pnb163v1Explicit => SupportsC2pnb163v1 || (!ExplicitNamedSameSupport && SupportsExplicitCurves); - private static bool IsCurveSupported(Oid oid) - { - return EcDiffieHellman.Tests.ECDiffieHellmanFactory.IsCurveValid(oid); - } + protected abstract bool IsCurveSupported(Oid oid); [Theory] [InlineData(false)] diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/EC/EccTestBase.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/EC/EccTestBase.cs index 8cc2391ba8dce8..ae3be642729ddf 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/EC/EccTestBase.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/EC/EccTestBase.cs @@ -22,20 +22,15 @@ public abstract class EccTestBase internal const string ECDSA_P521_OID_VALUE = "1.3.132.0.35"; // Also called nistP521 or secP521r1 internal const string ECDSA_Sect193r1_OID_VALUE = "1.3.132.0.24"; //Char-2 curve - public static IEnumerable TestCurvesFull + public static IEnumerable AllTestCurves { get { - var curveDefs = - from curveDef in TestCurvesRaw - where curveDef.IsCurveValidOnPlatform == true - select curveDef; - - foreach (CurveDef cd in curveDefs) + foreach (CurveDef cd in PublicTestCurvesRaw) yield return new[] { cd }; // return again with IncludePrivate = true - foreach (CurveDef cd in curveDefs) + foreach (CurveDef cd in PublicTestCurvesRaw) { cd.IncludePrivate = true; yield return new[] { cd }; @@ -43,51 +38,16 @@ from curveDef in TestCurvesRaw } } - public static IEnumerable TestCurves + public static IEnumerable PublicTestCurves { get { - var curveDefs = - from curveDef in TestCurvesRaw - where curveDef.IsCurveValidOnPlatform == true - select curveDef; - - foreach (CurveDef curveDef in curveDefs) - yield return new[] { curveDef }; - } - } - - public static IEnumerable TestInvalidCurves - { - get - { - var curveDefs = - from curveDef in TestCurvesRaw - where curveDef.IsCurveValidOnPlatform == false - select curveDef; - - foreach (CurveDef curveDef in curveDefs) - yield return new[] { curveDef }; - } - } - - public static IEnumerable TestNewCurves - { - get - { - var curveDefs = - from curveDef in TestCurvesRaw - where - curveDef.IsCurveValidOnPlatform == true && - curveDef.RequiredOnPlatform == false - select curveDef; - - foreach (CurveDef curveDef in curveDefs) - yield return new[] { curveDef }; + foreach (CurveDef cd in PublicTestCurvesRaw) + yield return new[] { cd }; } } - private static IEnumerable TestCurvesRaw + protected static IEnumerable PublicTestCurvesRaw { get { diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDhKeyFileTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDhKeyFileTests.cs index efa3a99d2e3711..2e4f841c341d08 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDhKeyFileTests.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDhKeyFileTests.cs @@ -8,10 +8,16 @@ namespace System.Security.Cryptography.EcDiffieHellman.Tests { [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] [ActiveIssue("https://github.com/dotnet/runtime/issues/64389", TestPlatforms.Windows)] - public class ECDhKeyFileTests : ECKeyFileTests + public abstract class ECDhKeyFileTests : ECKeyFileTests { + protected abstract ECDiffieHellmanProvider ECDiffieHellmanFactory { get; } + protected override ECDiffieHellman CreateKey() => ECDiffieHellmanFactory.Create(); protected override void Exercise(ECDiffieHellman key) => key.Exercise(); + protected override bool CanDeriveNewPublicKey => ECDiffieHellmanFactory.CanDeriveNewPublicKey; + protected override bool SupportsExplicitCurves => + ECDiffieHellmanFactory.ExplicitCurvesSupported || ECDiffieHellmanFactory.ExplicitCurvesSupportFailOnUseOnly; + protected override bool IsCurveSupported(Oid oid) => ECDiffieHellmanFactory.IsCurveValid(oid); protected override Func PublicKeyWriteArrayFunc { get; } = key => diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanFactory.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanFactory.cs deleted file mode 100644 index c8e9cd762da117..00000000000000 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanFactory.cs +++ /dev/null @@ -1,58 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Security.Cryptography.EcDiffieHellman.Tests -{ - public interface IECDiffieHellmanProvider - { - ECDiffieHellman Create(); - ECDiffieHellman Create(int keySize); -#if NET - ECDiffieHellman Create(ECCurve curve); -#endif - bool IsCurveValid(Oid oid); - bool ExplicitCurvesSupported { get; } - - // In OSSL 3+ we use EVP_PKEY APIs instead of EC_KEY APIs so import and export of explicit curves also fails for SymCrypt. - bool ExplicitCurvesSupportFailOnUseOnly => PlatformDetection.IsSymCryptOpenSsl && SafeEvpPKeyHandle.OpenSslVersion < 0x3_00_00_00_0; - - bool CanDeriveNewPublicKey { get; } - bool SupportsRawDerivation { get; } - bool SupportsSha3 { get; } - } - - public static partial class ECDiffieHellmanFactory - { - public static ECDiffieHellman Create() - { - return s_provider.Create(); - } - - public static ECDiffieHellman Create(int keySize) - { - return s_provider.Create(keySize); - } - -#if NET - public static ECDiffieHellman Create(ECCurve curve) - { - return s_provider.Create(curve); - } -#endif - - public static bool IsCurveValid(Oid oid) - { - return s_provider.IsCurveValid(oid); - } - - public static bool ExplicitCurvesSupported => s_provider.ExplicitCurvesSupported; - - public static bool CanDeriveNewPublicKey => s_provider.CanDeriveNewPublicKey; - - public static bool SupportsRawDerivation => s_provider.SupportsRawDerivation; - - public static bool SupportsSha3 => s_provider.SupportsSha3; - - public static bool ExplicitCurvesSupportFailOnUseOnly => s_provider.ExplicitCurvesSupportFailOnUseOnly; - } -} diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanFactoryTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanFactoryTests.cs index 059772aed20d2f..bc00edf4536671 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanFactoryTests.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanFactoryTests.cs @@ -7,24 +7,26 @@ namespace System.Security.Cryptography.EcDiffieHellman.Tests { [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] - public static class ECDiffieHellmanFactoryTests + public abstract class ECDiffieHellmanFactoryTests { + protected abstract ECDiffieHellmanProvider ECDiffieHellmanFactory { get; } + [Fact] - public static void ECDiffieHellmanCreateDefault_Equals_SameInstance() + public void ECDiffieHellmanCreateDefault_Equals_SameInstance() { using ECDiffieHellman ecdh = ECDiffieHellmanFactory.Create(); AssertExtensions.TrueExpression(ecdh.Equals(ecdh)); } [Fact] - public static void ECDiffieHellmanCreateKeySize_Equals_SameInstance() + public void ECDiffieHellmanCreateKeySize_Equals_SameInstance() { using ECDiffieHellman ecdh = ECDiffieHellmanFactory.Create(256); AssertExtensions.TrueExpression(ecdh.Equals(ecdh)); } [Fact] - public static void ECDiffieHellmanCreateKeySize_Equals_DifferentInstance_FalseForSameKeyMaterial() + public void ECDiffieHellmanCreateKeySize_Equals_DifferentInstance_FalseForSameKeyMaterial() { using ECDiffieHellman ecdh1 = ECDiffieHellmanFactory.Create(); using ECDiffieHellman ecdh2 = ECDiffieHellmanFactory.Create(); @@ -35,7 +37,7 @@ public static void ECDiffieHellmanCreateKeySize_Equals_DifferentInstance_FalseFo #if NET [Fact] - public static void ECDiffieHellmanCreateCurve_Equals_SameInstance() + public void ECDiffieHellmanCreateCurve_Equals_SameInstance() { using ECDiffieHellman ecdh = ECDiffieHellmanFactory.Create(ECCurve.NamedCurves.nistP256); AssertExtensions.TrueExpression(ecdh.Equals(ecdh)); diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanKeyPemTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanKeyPemTests.cs index e2c03c2076d79c..8848545c288532 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanKeyPemTests.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanKeyPemTests.cs @@ -4,11 +4,13 @@ using System.Security.Cryptography.Tests; using Xunit; -namespace System.Security.Cryptography.EcDsa.Tests +namespace System.Security.Cryptography.EcDiffieHellman.Tests { [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] - public sealed class ECDiffieHellmanKeyPemTests : ECKeyPemTests + public abstract class ECDiffieHellmanKeyPemTests : ECKeyPemTests { - protected override ECDiffieHellman CreateKey() => ECDiffieHellman.Create(); + protected abstract ECDiffieHellmanProvider ECDiffieHellmanFactory { get; } + + protected override ECDiffieHellman CreateKey() => ECDiffieHellmanFactory.Create(); } } diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanProvider.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanProvider.cs new file mode 100644 index 00000000000000..940f839c989a18 --- /dev/null +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanProvider.cs @@ -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. + +using Microsoft.Win32.SafeHandles; + +namespace System.Security.Cryptography.EcDiffieHellman.Tests +{ + public abstract class ECDiffieHellmanProvider + { + public abstract ECDiffieHellman Create(); + public abstract ECDiffieHellman Create(int keySize); + public abstract ECDiffieHellman Create(ECCurve curve); + public abstract bool IsCurveValid(Oid oid); + public abstract bool ExplicitCurvesSupported { get; } + + // In OSSL 3+ we use EVP_PKEY APIs instead of EC_KEY APIs so import and export of explicit curves also fails for SymCrypt. + public bool ExplicitCurvesSupportFailOnUseOnly => PlatformDetection.IsSymCryptOpenSsl && SafeEvpPKeyHandle.OpenSslVersion < 0x3_00_00_00_0; + + public abstract bool CanDeriveNewPublicKey { get; } + public abstract bool SupportsRawDerivation { get; } + public abstract bool SupportsSha3 { get; } + } +} diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.Hash.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.Hash.cs index ae8d32b02cc665..71a66ea9807d24 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.Hash.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.Hash.cs @@ -2,6 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; +using System.Security.Cryptography.Tests; +using Microsoft.DotNet.XUnitExtensions; using Test.Cryptography; using Xunit; @@ -10,7 +12,7 @@ namespace System.Security.Cryptography.EcDiffieHellman.Tests public partial class ECDiffieHellmanTests { [Fact] - public static void HashDerivation_OtherKeyRequired() + public void HashDerivation_OtherKeyRequired() { using (ECDiffieHellman ecdh = ECDiffieHellmanFactory.Create()) { @@ -19,9 +21,10 @@ public static void HashDerivation_OtherKeyRequired() } } - [Theory] - [MemberData(nameof(MismatchedKeysizes))] - public static void HashDerivation_SameSizeOtherKeyRequired(int aliceSize, int bobSize) + [Fact] + public void HashDerivation_SameSizeOtherKeyRequired() => ForEachMismatchedKeySize(HashDerivation_SameSizeOtherKeyRequiredImpl); + + private void HashDerivation_SameSizeOtherKeyRequiredImpl(int aliceSize, int bobSize) { using (ECDiffieHellman alice = ECDiffieHellmanFactory.Create(aliceSize)) using (ECDiffieHellman bob = ECDiffieHellmanFactory.Create(bobSize)) @@ -33,7 +36,7 @@ public static void HashDerivation_SameSizeOtherKeyRequired(int aliceSize, int bo } [Fact] - public static void HashDerivation_AlgorithmRequired() + public void HashDerivation_AlgorithmRequired() { using (ECDiffieHellman ecdh = ECDiffieHellmanFactory.Create()) using (ECDiffieHellmanPublicKey publicKey = ecdh.PublicKey) @@ -43,9 +46,10 @@ public static void HashDerivation_AlgorithmRequired() } } - [Theory] - [MemberData(nameof(EveryKeysize))] - public static void HashDerivation(int keySize) + [Fact] + public void HashDerivation() => ForEachKeySize(HashDerivationImpl); + + private void HashDerivationImpl(int keySize) { using (ECDiffieHellman alice = ECDiffieHellmanFactory.Create(keySize)) using (ECDiffieHellman bob = ECDiffieHellmanFactory.Create(keySize)) @@ -60,7 +64,7 @@ public static void HashDerivation(int keySize) } [Fact] - public static void HashDerivationVariesOnPublicKey() + public void HashDerivationVariesOnPublicKey() { using (ECDiffieHellman alice = ECDiffieHellmanFactory.Create()) using (ECDiffieHellman bob = ECDiffieHellmanFactory.Create()) @@ -77,7 +81,7 @@ public static void HashDerivationVariesOnPublicKey() } [Fact] - public static void HashDerivationVariesOnAlgorithm() + public void HashDerivationVariesOnAlgorithm() { using (ECDiffieHellman alice = ECDiffieHellmanFactory.Create()) using (ECDiffieHellman bob = ECDiffieHellmanFactory.Create()) @@ -91,9 +95,10 @@ public static void HashDerivationVariesOnAlgorithm() } } - [Theory] - [MemberData(nameof(EveryKeysize))] - public static void SymmetricDerivation_HashPrepend(int keySize) + [Fact] + public void SymmetricDerivation_HashPrepend() => ForEachKeySize(SymmetricDerivation_HashPrependImpl); + + private void SymmetricDerivation_HashPrependImpl(int keySize) { byte[] prefix = new byte[10]; @@ -110,7 +115,7 @@ public static void SymmetricDerivation_HashPrepend(int keySize) } [Fact] - public static void HashDerivationVariesOnPrepend() + public void HashDerivationVariesOnPrepend() { byte[] alicePrefix = new byte[10]; byte[] bobPrefix = new byte[alicePrefix.Length]; @@ -128,9 +133,10 @@ public static void HashDerivationVariesOnPrepend() } } - [Theory] - [MemberData(nameof(EveryKeysize))] - public static void SymmetricDerivation_HashAppend(int keySize) + [Fact] + public void SymmetricDerivation_HashAppend() => ForEachKeySize(SymmetricDerivation_HashAppendImpl); + + private void SymmetricDerivation_HashAppendImpl(int keySize) { byte[] suffix = new byte[10]; @@ -147,7 +153,7 @@ public static void SymmetricDerivation_HashAppend(int keySize) } [Fact] - public static void HashDerivationVariesOnAppend() + public void HashDerivationVariesOnAppend() { byte[] aliceSuffix = new byte[10]; byte[] bobSuffix = new byte[aliceSuffix.Length]; @@ -166,7 +172,7 @@ public static void HashDerivationVariesOnAppend() } [Fact] - public static void HashDerivationIsStable() + public void HashDerivationIsStable() { using (ECDiffieHellman alice = ECDiffieHellmanFactory.Create()) using (ECDiffieHellman bob = ECDiffieHellmanFactory.Create()) @@ -180,7 +186,7 @@ public static void HashDerivationIsStable() } [Fact] - public static void SimpleHashMethodForwardsNull() + public void SimpleHashMethodForwardsNull() { using (ECDiffieHellman ecdh = ECDiffieHellmanFactory.Create()) using (ECDiffieHellmanPublicKey publicKey = ecdh.PublicKey) @@ -193,7 +199,7 @@ public static void SimpleHashMethodForwardsNull() } [Fact] - public static void DeriveKeyMaterialEquivalentToDeriveKeyFromHash() + public void DeriveKeyMaterialEquivalentToDeriveKeyFromHash() { using (ECDiffieHellman ecdh = ECDiffieHellmanFactory.Create()) using (ECDiffieHellmanPublicKey publicKey = ecdh.PublicKey) @@ -255,50 +261,50 @@ public static IEnumerable HashDerivationTestCases() "7DB5520A5D6351595FC286CD53509D964FBB152C289F072581CB5E16EBF319E8", }; - if (ECDiffieHellmanFactory.SupportsSha3) + // SHA3 test cases - skipped at runtime if not supported + + // Created with: + // (echo -n -e '\x01\x03\0x05'; openssl pkeyutl -derive -inkey private.key -peerkey public.key; echo -n -e '\x02\x04\0x06\0x08') | openssl dgst -sha3-256 + yield return new object[] { - // Created with: - // (echo -n -e '\x01\x03\0x05'; openssl pkeyutl -derive -inkey private.key -peerkey public.key; echo -n -e '\x02\x04\0x06\0x08') | openssl dgst -sha3-256 - yield return new object[] - { - HashAlgorithmName.SHA3_256, - "010305", - "02040608", - "2AF6DA738DADF26607513ECB56451B5A476C7D42CFEC89872791B7A6C136A4F9", - }; - - // Created with: - // (echo -n -e '\x01\x03\0x05'; openssl pkeyutl -derive -inkey private.key -peerkey public.key; echo -n -e '\x02\x04\0x06\0x08') | openssl dgst -sha3-384 - yield return new object[] - { - HashAlgorithmName.SHA3_384, - "010305", - "02040608", - "EE9C10A3E60EA06296699195B3E338575DA529BA167A7520CA8BF50C86C4A08AB153DD7B97ADEE58CE5A9CAAC2F52ED1", - }; - - // Created with: - // (echo -n -e '\x01\x03\0x05'; openssl pkeyutl -derive -inkey private.key -peerkey public.key; echo -n -e '\x02\x04\0x06\0x08') | openssl dgst -sha3-512 - yield return new object[] - { - HashAlgorithmName.SHA3_512, - "010305", - "02040608", - "3614398AFC4A09B0490E095A7901FEA3C9C217E742064A371F2E04D6363EF864" + - "FE52EEEEA976FEC3FF98DE55D1E78E864F009FD834E1D301FA069BD44F6ECD52", - }; - } + HashAlgorithmName.SHA3_256, + "010305", + "02040608", + "2AF6DA738DADF26607513ECB56451B5A476C7D42CFEC89872791B7A6C136A4F9", + }; + + // Created with: + // (echo -n -e '\x01\x03\0x05'; openssl pkeyutl -derive -inkey private.key -peerkey public.key; echo -n -e '\x02\x04\0x06\0x08') | openssl dgst -sha3-384 + yield return new object[] + { + HashAlgorithmName.SHA3_384, + "010305", + "02040608", + "EE9C10A3E60EA06296699195B3E338575DA529BA167A7520CA8BF50C86C4A08AB153DD7B97ADEE58CE5A9CAAC2F52ED1", + }; + + // Created with: + // (echo -n -e '\x01\x03\0x05'; openssl pkeyutl -derive -inkey private.key -peerkey public.key; echo -n -e '\x02\x04\0x06\0x08') | openssl dgst -sha3-512 + yield return new object[] + { + HashAlgorithmName.SHA3_512, + "010305", + "02040608", + "3614398AFC4A09B0490E095A7901FEA3C9C217E742064A371F2E04D6363EF864" + + "FE52EEEEA976FEC3FF98DE55D1E78E864F009FD834E1D301FA069BD44F6ECD52", + }; } -#if NET - [Theory] + [ConditionalTheory] [MemberData(nameof(HashDerivationTestCases))] - public static void HashDerivation_KnownResults( + public void HashDerivation_KnownResults( HashAlgorithmName hashAlgorithm, string prependBytes, string appendBytes, string answerBytes) { + SkipTestException.ThrowWhen(hashAlgorithm.Name.StartsWith("SHA3", StringComparison.Ordinal) && !ECDiffieHellmanFactory.SupportsSha3); + byte[] prepend = prependBytes?.HexToByteArray(); byte[] append = appendBytes?.HexToByteArray(); byte[] answer = answerBytes.HexToByteArray(); @@ -312,6 +318,5 @@ public static void HashDerivation_KnownResults( Assert.Equal(answer, output); } -#endif } } diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.Hmac.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.Hmac.cs index 575a9d853fe266..1d59b294de1f3a 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.Hmac.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.Hmac.cs @@ -4,6 +4,8 @@ using System; using System.Collections.Generic; using System.Security.Cryptography; +using System.Security.Cryptography.Tests; +using Microsoft.DotNet.XUnitExtensions; using Test.Cryptography; using Xunit; @@ -14,7 +16,7 @@ public partial class ECDiffieHellmanTests private static readonly byte[] s_sampleHmacKey = { 0, 1, 2, 3, 4, 5 }; [Fact] - public static void HmacDerivation_OtherKeyRequired() + public void HmacDerivation_OtherKeyRequired() { using (ECDiffieHellman ecdh = ECDiffieHellmanFactory.Create()) { @@ -23,9 +25,10 @@ public static void HmacDerivation_OtherKeyRequired() } } - [Theory] - [MemberData(nameof(MismatchedKeysizes))] - public static void HmacDerivation_SameSizeOtherKeyRequired(int aliceSize, int bobSize) + [Fact] + public void HmacDerivation_SameSizeOtherKeyRequired() => ForEachMismatchedKeySize(HmacDerivation_SameSizeOtherKeyRequiredImpl); + + private void HmacDerivation_SameSizeOtherKeyRequiredImpl(int aliceSize, int bobSize) { using (ECDiffieHellman alice = ECDiffieHellmanFactory.Create(aliceSize)) using (ECDiffieHellman bob = ECDiffieHellmanFactory.Create(bobSize)) @@ -36,9 +39,10 @@ public static void HmacDerivation_SameSizeOtherKeyRequired(int aliceSize, int bo } } - [Theory] - [MemberData(nameof(EveryKeysize))] - public static void SymmetricDerivation_Hmac(int keySize) + [Fact] + public void SymmetricDerivation_Hmac() => ForEachKeySize(SymmetricDerivation_HmacImpl); + + private void SymmetricDerivation_HmacImpl(int keySize) { using (ECDiffieHellman alice = ECDiffieHellmanFactory.Create(keySize)) using (ECDiffieHellman bob = ECDiffieHellmanFactory.Create(keySize)) @@ -53,7 +57,7 @@ public static void SymmetricDerivation_Hmac(int keySize) } [Fact] - public static void HmacDerivationVariesOnPublicKey() + public void HmacDerivationVariesOnPublicKey() { using (ECDiffieHellman alice = ECDiffieHellmanFactory.Create()) using (ECDiffieHellman bob = ECDiffieHellmanFactory.Create()) @@ -70,7 +74,7 @@ public static void HmacDerivationVariesOnPublicKey() } [Fact] - public static void HmacDerivationVariesOnAlgorithm() + public void HmacDerivationVariesOnAlgorithm() { using (ECDiffieHellman alice = ECDiffieHellmanFactory.Create()) using (ECDiffieHellman bob = ECDiffieHellmanFactory.Create()) @@ -85,7 +89,7 @@ public static void HmacDerivationVariesOnAlgorithm() } [Fact] - public static void HmacDerivationVariesOnKey() + public void HmacDerivationVariesOnKey() { byte[] hmacKeyAlice = { 0, 1, 2, 3, 4, 5 }; byte[] hmacKeyBob = { 10, 1, 2, 3, 4, 5 }; @@ -102,9 +106,10 @@ public static void HmacDerivationVariesOnKey() } } - [Theory] - [MemberData(nameof(EveryKeysize))] - public static void SymmetricDerivation_HmacPrepend(int keySize) + [Fact] + public void SymmetricDerivation_HmacPrepend() => ForEachKeySize(SymmetricDerivation_HmacPrependImpl); + + private void SymmetricDerivation_HmacPrependImpl(int keySize) { byte[] prefix = new byte[10]; @@ -121,7 +126,7 @@ public static void SymmetricDerivation_HmacPrepend(int keySize) } [Fact] - public static void HmacDerivationVariesOnPrepend() + public void HmacDerivationVariesOnPrepend() { byte[] alicePrefix = new byte[10]; byte[] bobPrefix = new byte[alicePrefix.Length]; @@ -139,9 +144,10 @@ public static void HmacDerivationVariesOnPrepend() } } - [Theory] - [MemberData(nameof(EveryKeysize))] - public static void SymmetricDerivation_HmacAppend(int keySize) + [Fact] + public void SymmetricDerivation_HmacAppend() => ForEachKeySize(SymmetricDerivation_HmacAppendImpl); + + private void SymmetricDerivation_HmacAppendImpl(int keySize) { byte[] suffix = new byte[10]; @@ -158,7 +164,7 @@ public static void SymmetricDerivation_HmacAppend(int keySize) } [Fact] - public static void HmacDerivationVariesOnAppend() + public void HmacDerivationVariesOnAppend() { byte[] aliceSuffix = new byte[10]; byte[] bobSuffix = new byte[aliceSuffix.Length]; @@ -177,7 +183,7 @@ public static void HmacDerivationVariesOnAppend() } [Fact] - public static void HmacDerivationIsStable() + public void HmacDerivationIsStable() { using (ECDiffieHellman alice = ECDiffieHellmanFactory.Create()) using (ECDiffieHellman bob = ECDiffieHellmanFactory.Create()) @@ -190,9 +196,10 @@ public static void HmacDerivationIsStable() } } - [Theory] - [MemberData(nameof(EveryKeysize))] - public static void SymmetricDerivation_HmacNullKey(int keySize) + [Fact] + public void SymmetricDerivation_HmacNullKey() => ForEachKeySize(SymmetricDerivation_HmacNullKeyImpl); + + private void SymmetricDerivation_HmacNullKeyImpl(int keySize) { using (ECDiffieHellman alice = ECDiffieHellmanFactory.Create(keySize)) using (ECDiffieHellman bob = ECDiffieHellmanFactory.Create(keySize)) @@ -207,7 +214,7 @@ public static void SymmetricDerivation_HmacNullKey(int keySize) } [Fact] - public static void HmacNullKeyDerivationIsStable() + public void HmacNullKeyDerivationIsStable() { using (ECDiffieHellman alice = ECDiffieHellmanFactory.Create()) using (ECDiffieHellman bob = ECDiffieHellmanFactory.Create()) @@ -221,7 +228,7 @@ public static void HmacNullKeyDerivationIsStable() } [Fact] - public static void SimpleHmacMethodForwardsNull() + public void SimpleHmacMethodForwardsNull() { using (ECDiffieHellman ecdh = ECDiffieHellmanFactory.Create()) using (ECDiffieHellmanPublicKey publicKey = ecdh.PublicKey) @@ -234,7 +241,7 @@ public static void SimpleHmacMethodForwardsNull() } [Fact] - public static void SimpleHmacNullKeyForwardsNull() + public void SimpleHmacNullKeyForwardsNull() { using (ECDiffieHellman ecdh = ECDiffieHellmanFactory.Create()) using (ECDiffieHellmanPublicKey publicKey = ecdh.PublicKey) @@ -311,54 +318,54 @@ public static IEnumerable HmacDerivationTestCases() "AE3CD974F262B199B0859D9F933207D2F6E3E04434D60089FE0BE801ED38D370", }; - if (ECDiffieHellmanFactory.SupportsSha3) + // SHA3 test cases - skipped at runtime if not supported + + // Created with: + // (echo -n -e '\x01\x03\0x05'; openssl pkeyutl -derive -inkey private.key -peerkey public.key; echo -n -e '\x02\x04\0x06\0x08') | openssl sha3-256 -mac HMAC -macopt hexkey:030609 + yield return new object[] { - // Created with: - // (echo -n -e '\x01\x03\0x05'; openssl pkeyutl -derive -inkey private.key -peerkey public.key; echo -n -e '\x02\x04\0x06\0x08') | openssl sha3-256 -mac HMAC -macopt hexkey:030609 - yield return new object[] - { - HashAlgorithmName.SHA3_256, - "030609", - "010305", - "02040608", - "23E7E5648EF46D537F4159F7F40E686279D89ADFD7EF6CFA110034F42EC8CEF7", - }; - - // Created with: - // (echo -n -e '\x01\x03\0x05'; openssl pkeyutl -derive -inkey private.key -peerkey public.key; echo -n -e '\x02\x04\0x06\0x08') | openssl sha3-384 -mac HMAC -macopt hexkey:030609 - yield return new object[] - { - HashAlgorithmName.SHA3_384, - "030609", - "010305", - "02040608", - "FD0F7B11489F641DE0964F81D83EF90E33C46D1628C51FA79A85AD1034A9CAD36F8A38C3925704AC0E404BC6FE50ECA4", - }; - - // Created with: - // (echo -n -e '\x01\x03\0x05'; openssl pkeyutl -derive -inkey private.key -peerkey public.key; echo -n -e '\x02\x04\0x06\0x08') | openssl sha3-512 -mac HMAC -macopt hexkey:030609 - yield return new object[] - { - HashAlgorithmName.SHA3_512, - "030609", - "010305", - "02040608", - "2C32BBFBF8A41118AAD3BAA94C8995B5B027246EA3D972937C1BFD9F460C6492" + - "44EEC68EF570B4BB74B0D3BBD463F18526400A77211B5CB39311CDE21104E209", - }; - } + HashAlgorithmName.SHA3_256, + "030609", + "010305", + "02040608", + "23E7E5648EF46D537F4159F7F40E686279D89ADFD7EF6CFA110034F42EC8CEF7", + }; + + // Created with: + // (echo -n -e '\x01\x03\0x05'; openssl pkeyutl -derive -inkey private.key -peerkey public.key; echo -n -e '\x02\x04\0x06\0x08') | openssl sha3-384 -mac HMAC -macopt hexkey:030609 + yield return new object[] + { + HashAlgorithmName.SHA3_384, + "030609", + "010305", + "02040608", + "FD0F7B11489F641DE0964F81D83EF90E33C46D1628C51FA79A85AD1034A9CAD36F8A38C3925704AC0E404BC6FE50ECA4", + }; + + // Created with: + // (echo -n -e '\x01\x03\0x05'; openssl pkeyutl -derive -inkey private.key -peerkey public.key; echo -n -e '\x02\x04\0x06\0x08') | openssl sha3-512 -mac HMAC -macopt hexkey:030609 + yield return new object[] + { + HashAlgorithmName.SHA3_512, + "030609", + "010305", + "02040608", + "2C32BBFBF8A41118AAD3BAA94C8995B5B027246EA3D972937C1BFD9F460C6492" + + "44EEC68EF570B4BB74B0D3BBD463F18526400A77211B5CB39311CDE21104E209", + }; } -#if NET - [Theory] + [ConditionalTheory] [MemberData(nameof(HmacDerivationTestCases))] - public static void HmacDerivation_KnownResults( + public void HmacDerivation_KnownResults( HashAlgorithmName hashAlgorithm, string hmacKeyBytes, string prependBytes, string appendBytes, string answerBytes) { + SkipTestException.ThrowWhen(hashAlgorithm.Name.StartsWith("SHA3", StringComparison.Ordinal) && !ECDiffieHellmanFactory.SupportsSha3); + byte[] hmacKey = hmacKeyBytes?.HexToByteArray(); byte[] prepend = prependBytes?.HexToByteArray(); byte[] append = appendBytes?.HexToByteArray(); @@ -373,6 +380,5 @@ public static void HmacDerivation_KnownResults( Assert.Equal(answer, output); } -#endif } } diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.ImportExport.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.ImportExport.cs index ff4cb7cc792238..883f7e0e39239a 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.ImportExport.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.ImportExport.cs @@ -3,27 +3,27 @@ using System.Collections.Generic; using System.Security.Cryptography.Tests; +using Microsoft.DotNet.XUnitExtensions; using Test.Cryptography; using Xunit; namespace System.Security.Cryptography.EcDiffieHellman.Tests { -#if NET public partial class ECDiffieHellmanTests { // On CentOS, secp224r1 (also called nistP224) appears to be disabled. To prevent test failures on that platform, // probe for this capability before depending on it. - internal static bool ECDsa224Available => + internal bool ECDsa224Available => ECDiffieHellmanFactory.IsCurveValid(new Oid(ECDSA_P224_OID_VALUE)); - internal static bool CanDeriveNewPublicKey { get; } - = EcDiffieHellman.Tests.ECDiffieHellmanFactory.CanDeriveNewPublicKey; + internal bool CanDeriveNewPublicKey => + ECDiffieHellmanFactory.CanDeriveNewPublicKey; - [Theory, MemberData(nameof(TestCurvesFull))] - public static void TestNamedCurves(CurveDef curveDef) + [ConditionalTheory, MemberData(nameof(AllTestCurves))] + public void TestNamedCurves(CurveDef curveDef) { - if (!curveDef.Curve.IsNamed) - return; + SkipTestException.ThrowUnless(curveDef.Curve.IsNamed); + SkipTestException.ThrowUnless(curveDef.IsCurveValidOnPlatform(ECDiffieHellmanFactory)); using (ECDiffieHellman ec1 = ECDiffieHellmanFactory.Create(curveDef.Curve)) { @@ -41,11 +41,11 @@ public static void TestNamedCurves(CurveDef curveDef) } } - [Theory, MemberData(nameof(TestInvalidCurves))] - public static void TestNamedCurvesNegative(CurveDef curveDef) + [ConditionalTheory, MemberData(nameof(PublicTestCurves))] + public void TestNamedCurvesNegative(CurveDef curveDef) { - if (!curveDef.Curve.IsNamed) - return; + SkipTestException.ThrowUnless(curveDef.Curve.IsNamed); + SkipTestException.ThrowWhen(curveDef.IsCurveValidOnPlatform(ECDiffieHellmanFactory)); // An exception may be thrown during Create() if the Oid is bad, or later during native calls Assert.Throws(() => @@ -55,13 +55,11 @@ public static void TestNamedCurvesNegative(CurveDef curveDef) }); } - [Theory, MemberData(nameof(TestCurvesFull))] - public static void TestExplicitCurves(CurveDef curveDef) + [ConditionalTheory, MemberData(nameof(AllTestCurves))] + public void TestExplicitCurves(CurveDef curveDef) { - if (!ECDiffieHellmanFactory.ExplicitCurvesSupported) - { - return; - } + SkipTestException.ThrowUnless(ECDiffieHellmanFactory.ExplicitCurvesSupported); + SkipTestException.ThrowUnless(curveDef.IsCurveValidOnPlatform(ECDiffieHellmanFactory)); using (ECDiffieHellman ec1 = ECDiffieHellmanFactory.Create(curveDef.Curve)) { @@ -79,13 +77,11 @@ public static void TestExplicitCurves(CurveDef curveDef) } } - [Theory, MemberData(nameof(TestCurves))] - public static void TestExplicitCurvesKeyAgree(CurveDef curveDef) + [ConditionalTheory, MemberData(nameof(PublicTestCurves))] + public void TestExplicitCurvesKeyAgree(CurveDef curveDef) { - if (!ECDiffieHellmanFactory.ExplicitCurvesSupported) - { - return; - } + SkipTestException.ThrowUnless(ECDiffieHellmanFactory.ExplicitCurvesSupported); + SkipTestException.ThrowUnless(curveDef.IsCurveValidOnPlatform(ECDiffieHellmanFactory)); using (ECDiffieHellman ecdh1Named = ECDiffieHellmanFactory.Create(curveDef.Curve)) { @@ -131,7 +127,7 @@ public static void TestExplicitCurvesKeyAgree(CurveDef curveDef) } [Fact] - public static void TestNamedCurveNegative() + public void TestNamedCurveNegative() { Assert.Throws( () => ECDiffieHellmanFactory.Create(ECCurve.CreateFromFriendlyName("Invalid")).ExportExplicitParameters(false)); @@ -141,7 +137,7 @@ public static void TestNamedCurveNegative() } [Fact] - public static void TestKeySizeCreateKey() + public void TestKeySizeCreateKey() { using (ECDiffieHellman ec = ECDiffieHellmanFactory.Create(ECCurve.NamedCurves.nistP256)) { @@ -157,14 +153,11 @@ public static void TestKeySizeCreateKey() } } - [Fact] + [ConditionalFact] [SkipOnPlatform(TestPlatforms.Android, "Android does not validate curve parameters")] - public static void TestExplicitImportValidationNegative() + public void TestExplicitImportValidationNegative() { - if (!ECDiffieHellmanFactory.ExplicitCurvesSupported) - { - return; - } + SkipTestException.ThrowUnless(ECDiffieHellmanFactory.ExplicitCurvesSupported); unchecked { @@ -211,13 +204,10 @@ public static void TestExplicitImportValidationNegative() } } - [Fact] - public static void ImportExplicitWithSeedButNoHash() + [ConditionalFact] + public void ImportExplicitWithSeedButNoHash() { - if (!ECDiffieHellmanFactory.ExplicitCurvesSupported) - { - return; - } + SkipTestException.ThrowUnless(ECDiffieHellmanFactory.ExplicitCurvesSupported); using (ECDiffieHellman ec = ECDiffieHellmanFactory.Create()) { @@ -234,14 +224,11 @@ public static void ImportExplicitWithSeedButNoHash() } } - [Fact] + [ConditionalFact] [PlatformSpecific(TestPlatforms.Windows/* "parameters.Curve.Hash doesn't round trip on Unix." */)] - public static void ImportExplicitWithHashButNoSeed() + public void ImportExplicitWithHashButNoSeed() { - if (!ECDiffieHellmanFactory.ExplicitCurvesSupported) - { - return; - } + SkipTestException.ThrowUnless(ECDiffieHellmanFactory.ExplicitCurvesSupported); using (ECDiffieHellman ec = ECDiffieHellmanFactory.Create()) { @@ -258,13 +245,11 @@ public static void ImportExplicitWithHashButNoSeed() } } - [ConditionalFact(typeof(ECDiffieHellmanTests), nameof(ECDsa224Available))] - public static void TestNamedImportValidationNegative() + [ConditionalFact] + public void TestNamedImportValidationNegative() { - if (!ECDiffieHellmanFactory.ExplicitCurvesSupported) - { - return; - } + SkipTestException.ThrowUnless(ECDsa224Available); + SkipTestException.ThrowUnless(ECDiffieHellmanFactory.ExplicitCurvesSupported); unchecked { @@ -293,13 +278,10 @@ public static void TestNamedImportValidationNegative() } } - [Fact] - public static void TestGeneralExportWithExplicitParameters() + [ConditionalFact] + public void TestGeneralExportWithExplicitParameters() { - if (!ECDiffieHellmanFactory.ExplicitCurvesSupported) - { - return; - } + SkipTestException.ThrowUnless(ECDiffieHellmanFactory.ExplicitCurvesSupported); using (ECDiffieHellman ecdsa = ECDiffieHellmanFactory.Create()) { @@ -316,13 +298,11 @@ public static void TestGeneralExportWithExplicitParameters() } } - [Fact] - public static void TestExplicitCurveImportOnUnsupportedPlatform() + [ConditionalFact] + public void TestExplicitCurveImportOnUnsupportedPlatform() { - if (ECDiffieHellmanFactory.ExplicitCurvesSupported || ECDiffieHellmanFactory.ExplicitCurvesSupportFailOnUseOnly) - { - return; - } + SkipTestException.ThrowWhen( + ECDiffieHellmanFactory.ExplicitCurvesSupported || ECDiffieHellmanFactory.ExplicitCurvesSupportFailOnUseOnly); using (ECDiffieHellman ecdh = ECDiffieHellmanFactory.Create()) { @@ -343,13 +323,11 @@ public static void TestExplicitCurveImportOnUnsupportedPlatform() } } - [ConditionalFact(typeof(ECDiffieHellmanTests), nameof(ECDsa224Available))] - public static void TestNamedCurveWithExplicitKey() + [ConditionalFact] + public void TestNamedCurveWithExplicitKey() { - if (!ECDiffieHellmanFactory.ExplicitCurvesSupported) - { - return; - } + SkipTestException.ThrowUnless(ECDsa224Available); + SkipTestException.ThrowUnless(ECDiffieHellmanFactory.ExplicitCurvesSupported); using (ECDiffieHellman ec = ECDiffieHellmanFactory.Create()) { @@ -360,7 +338,7 @@ public static void TestNamedCurveWithExplicitKey() } [Fact] - public static void ExportIncludingPrivateOnPublicOnlyKey() + public void ExportIncludingPrivateOnPublicOnlyKey() { ECParameters iutParameters = new ECParameters { @@ -393,9 +371,11 @@ public static void ExportIncludingPrivateOnPublicOnlyKey() } } - [ConditionalFact(typeof(ECDiffieHellmanTests), nameof(CanDeriveNewPublicKey))] - public static void ImportFromPrivateOnlyKey() + [ConditionalFact] + public void ImportFromPrivateOnlyKey() { + SkipTestException.ThrowUnless(ECDiffieHellmanFactory.CanDeriveNewPublicKey); + byte[] expectedX = "00d45615ed5d37fde699610a62cd43ba76bedd8f85ed31005fe00d6450fbbd101291abd96d4945a8b57bc73b3fe9f4671105309ec9b6879d0551d930dac8ba45d255".HexToByteArray(); byte[] expectedY = "01425332844e592b440c0027972ad1526431c06732df19cd46a242172d4dd67c2c8c99dfc22e49949a56cf90c6473635ce82f25b33682fb19bc33bd910ed8ce3a7fa".HexToByteArray(); @@ -417,10 +397,13 @@ public static void ImportFromPrivateOnlyKey() } } - [Theory] + [ConditionalTheory] [MemberData(nameof(NamedCurves))] - public static void OidPresentOnCurveMiscased(ECCurve curve) + public void OidPresentOnCurveMiscased(ECCurve curve, bool checkCurveValidity) { + if (checkCurveValidity) + SkipTestException.ThrowUnless(ECDiffieHellmanFactory.IsCurveValid(curve.Oid)); + ECCurve miscasedCurve = ECCurve.CreateFromFriendlyName(InvertStringCase(curve.Oid.FriendlyName)); Assert.NotEqual(miscasedCurve.Oid.FriendlyName, curve.Oid.FriendlyName); Assert.Equal(miscasedCurve.Oid.FriendlyName, curve.Oid.FriendlyName, ignoreCase: true); @@ -442,22 +425,16 @@ public static IEnumerable NamedCurves { get { - yield return new object[] { ECCurve.NamedCurves.nistP256 }; - yield return new object[] { ECCurve.NamedCurves.nistP384 }; - yield return new object[] { ECCurve.NamedCurves.nistP521 }; - yield return new object[] { ECCurve.CreateFromFriendlyName("ECDH_P256") }; - yield return new object[] { ECCurve.CreateFromFriendlyName("ECDH_P384") }; - yield return new object[] { ECCurve.CreateFromFriendlyName("ECDH_P521") }; - - if (ECDiffieHellmanFactory.IsCurveValid(ECCurve.NamedCurves.brainpoolP160r1.Oid)) - { - yield return new object[] { ECCurve.NamedCurves.brainpoolP160r1 }; - } - - if (ECDiffieHellmanFactory.IsCurveValid(ECCurve.NamedCurves.brainpoolP160t1.Oid)) - { - yield return new object[] { ECCurve.NamedCurves.brainpoolP160t1 }; - } + yield return new object[] { ECCurve.NamedCurves.nistP256, false }; + yield return new object[] { ECCurve.NamedCurves.nistP384, false }; + yield return new object[] { ECCurve.NamedCurves.nistP521, false }; + yield return new object[] { ECCurve.CreateFromFriendlyName("ECDH_P256"), false }; + yield return new object[] { ECCurve.CreateFromFriendlyName("ECDH_P384"), false }; + yield return new object[] { ECCurve.CreateFromFriendlyName("ECDH_P521"), false }; + + // Curves may not be valid for all platforms, so validity must be checked at runtime + yield return new object[] { ECCurve.NamedCurves.brainpoolP160r1, true }; + yield return new object[] { ECCurve.NamedCurves.brainpoolP160t1, true }; } } @@ -513,7 +490,7 @@ private static void VerifyExplicitCurve(ECParameters parameters, ECDiffieHellman [Theory] [MemberData(nameof(NistEccCdhPrimeCurveVectors))] - public static void EcdhKeyAgreement_PrimeCurve_MatchesKnownSharedSecret( + public void EcdhKeyAgreement_PrimeCurve_MatchesKnownSharedSecret( string curveName, string curveOid, string qCavsXHex, string qCavsYHex, string dIutHex, string qIutXHex, string qIutYHex, @@ -577,5 +554,4 @@ public static void EcdhKeyAgreement_PrimeCurve_MatchesKnownSharedSecret( }, }; } -#endif } diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.NistValidation.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.NistValidation.cs index ce07c475bec5fd..02b0a6cbc34a86 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.NistValidation.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.NistValidation.cs @@ -16,7 +16,7 @@ namespace System.Security.Cryptography.EcDiffieHellman.Tests public partial class ECDiffieHellmanTests { [Fact] - public static void ValidateNistP256_0() + public void ValidateNistP256_0() { Verify( ECCurve.NamedCurves.nistP256, @@ -30,7 +30,7 @@ public static void ValidateNistP256_0() } [Fact] - public static void ValidateNistP256_1() + public void ValidateNistP256_1() { Verify( ECCurve.NamedCurves.nistP256, @@ -44,7 +44,7 @@ public static void ValidateNistP256_1() } [Fact] - public static void ValidateNistP384_0() + public void ValidateNistP384_0() { Verify( ECCurve.NamedCurves.nistP384, @@ -58,7 +58,7 @@ public static void ValidateNistP384_0() } [Fact] - public static void ValidateNistP384_1() + public void ValidateNistP384_1() { Verify( ECCurve.NamedCurves.nistP384, @@ -72,7 +72,7 @@ public static void ValidateNistP384_1() } [Fact] - public static void ValidateNistP521_0() + public void ValidateNistP521_0() { Verify( ECCurve.NamedCurves.nistP521, @@ -86,7 +86,7 @@ public static void ValidateNistP521_0() } [Fact] - public static void ValidateNistP521_1() + public void ValidateNistP521_1() { Verify( ECCurve.NamedCurves.nistP521, @@ -99,7 +99,7 @@ public static void ValidateNistP521_1() "000b3920ac830ade812c8f96805da2236e002acbbf13596a9ab254d44d0e91b6255ebf1229f366fb5a05c5884ef46032c26d42189273ca4efa4c3db6bd12a6853759"); } - private static void Verify( + private void Verify( ECCurve namedCurve, ECCurve explicitCurve, string cavsQx, @@ -136,7 +136,7 @@ private static void Verify( Verify(ref iutParameters, ref cavsParameters, explicitCurve, iutZ.HexToByteArray()); } - private static void Verify( + private void Verify( ref ECParameters iutParameters, ref ECParameters cavsParameters, ECCurve explicitCurve, @@ -216,7 +216,7 @@ private static void Verify( } } - private static void Verify( + private void Verify( ECDiffieHellman iut, ECDiffieHellmanPublicKey cavsPublic, HashAlgorithm zHasher, diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.Raw.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.Raw.cs index 0f69bde8a2f7d2..90297b197b869a 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.Raw.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.Raw.cs @@ -3,17 +3,19 @@ using System; using System.Security.Cryptography; +using System.Security.Cryptography.Tests; +using Microsoft.DotNet.XUnitExtensions; using Xunit; namespace System.Security.Cryptography.EcDiffieHellman.Tests { public partial class ECDiffieHellmanTests { - public static bool DoesNotSupportRawDerivation => !ECDiffieHellmanFactory.SupportsRawDerivation; - - [ConditionalFact(typeof(ECDiffieHellmanFactory), nameof(ECDiffieHellmanFactory.SupportsRawDerivation))] - public static void RawDerivation_OtherKeyRequired() + [ConditionalFact] + public void RawDerivation_OtherKeyRequired() { + SkipTestException.ThrowUnless(ECDiffieHellmanFactory.SupportsRawDerivation); + using (ECDiffieHellman ecdh = ECDiffieHellmanFactory.Create()) { AssertExtensions.Throws( @@ -22,9 +24,15 @@ public static void RawDerivation_OtherKeyRequired() } } - [ConditionalTheory(typeof(ECDiffieHellmanFactory), nameof(ECDiffieHellmanFactory.SupportsRawDerivation))] - [MemberData(nameof(MismatchedKeysizes))] - public static void RawDerivation_SameSizeOtherKeyRequired(int aliceSize, int bobSize) + [ConditionalFact] + public void RawDerivation_SameSizeOtherKeyRequired() + { + SkipTestException.ThrowUnless(ECDiffieHellmanFactory.SupportsRawDerivation); + + ForEachMismatchedKeySize(RawDerivation_SameSizeOtherKeyRequiredImpl); + } + + private void RawDerivation_SameSizeOtherKeyRequiredImpl(int aliceSize, int bobSize) { using (ECDiffieHellman alice = ECDiffieHellmanFactory.Create(aliceSize)) using (ECDiffieHellman bob = ECDiffieHellmanFactory.Create(bobSize)) @@ -36,9 +44,15 @@ public static void RawDerivation_SameSizeOtherKeyRequired(int aliceSize, int bob } } - [ConditionalTheory(typeof(ECDiffieHellmanFactory), nameof(ECDiffieHellmanFactory.SupportsRawDerivation))] - [MemberData(nameof(EveryKeysize))] - public static void RawDerivation_DeriveSharedSecret_Agree(int keySize) + [ConditionalFact] + public void RawDerivation_DeriveSharedSecret_Agree() + { + SkipTestException.ThrowUnless(ECDiffieHellmanFactory.SupportsRawDerivation); + + ForEachKeySize(RawDerivation_DeriveSharedSecret_AgreeImpl); + } + + private void RawDerivation_DeriveSharedSecret_AgreeImpl(int keySize) { using (ECDiffieHellman alice = ECDiffieHellmanFactory.Create(keySize)) using (ECDiffieHellman bob = ECDiffieHellmanFactory.Create(keySize)) @@ -51,9 +65,11 @@ public static void RawDerivation_DeriveSharedSecret_Agree(int keySize) } } - [ConditionalFact(typeof(ECDiffieHellmanFactory), nameof(ECDiffieHellmanFactory.SupportsRawDerivation))] - public static void RawDerivation_DeriveSharedSecret_Disagree() + [ConditionalFact] + public void RawDerivation_DeriveSharedSecret_Disagree() { + SkipTestException.ThrowUnless(ECDiffieHellmanFactory.SupportsRawDerivation); + using (ECDiffieHellman alice = ECDiffieHellmanFactory.Create(ECCurve.NamedCurves.nistP256)) using (ECDiffieHellman bob = ECDiffieHellmanFactory.Create(ECCurve.NamedCurves.nistP256)) using (ECDiffieHellman eve = ECDiffieHellmanFactory.Create(ECCurve.NamedCurves.nistP256)) @@ -67,9 +83,11 @@ public static void RawDerivation_DeriveSharedSecret_Disagree() } } - [ConditionalFact(typeof(ECDiffieHellmanFactory), nameof(ECDiffieHellmanFactory.SupportsRawDerivation))] - public static void RawDerivation_DeriveIsStable() + [ConditionalFact] + public void RawDerivation_DeriveIsStable() { + SkipTestException.ThrowUnless(ECDiffieHellmanFactory.SupportsRawDerivation); + using (ECDiffieHellman alice = ECDiffieHellmanFactory.Create(ECCurve.NamedCurves.nistP256)) using (ECDiffieHellman bob = ECDiffieHellmanFactory.Create(ECCurve.NamedCurves.nistP256)) using (ECDiffieHellmanPublicKey bobPublic = bob.PublicKey) @@ -80,9 +98,11 @@ public static void RawDerivation_DeriveIsStable() } } - [ConditionalFact(typeof(ECDiffieHellmanTests), nameof(DoesNotSupportRawDerivation))] - public static void RawDerivation_NotSupported() + [ConditionalFact] + public void RawDerivation_NotSupported() { + SkipTestException.ThrowWhen(ECDiffieHellmanFactory.SupportsRawDerivation); + using (ECDiffieHellman alice = ECDiffieHellmanFactory.Create(ECCurve.NamedCurves.nistP256)) using (ECDiffieHellman bob = ECDiffieHellmanFactory.Create(ECCurve.NamedCurves.nistP256)) using (ECDiffieHellmanPublicKey bobPublic = bob.PublicKey) diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.Tls.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.Tls.cs index d8c6e8f0ff0641..28c4f65168836a 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.Tls.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.Tls.cs @@ -14,7 +14,7 @@ public partial class ECDiffieHellmanTests private static readonly byte[] s_emptySeed = new byte[64]; [Fact] - public static void TlsDerivation_OtherKeyRequired() + public void TlsDerivation_OtherKeyRequired() { using (ECDiffieHellman ecdh = ECDiffieHellmanFactory.Create()) { @@ -23,9 +23,10 @@ public static void TlsDerivation_OtherKeyRequired() } } - [Theory] - [MemberData(nameof(MismatchedKeysizes))] - public static void TlsDerivation_SameSizeOtherKeyRequired(int aliceSize, int bobSize) + [Fact] + public void TlsDerivation_SameSizeOtherKeyRequired() => ForEachMismatchedKeySize(TlsDerivation_SameSizeOtherKeyRequiredImpl); + + private void TlsDerivation_SameSizeOtherKeyRequiredImpl(int aliceSize, int bobSize) { using (ECDiffieHellman alice = ECDiffieHellmanFactory.Create(aliceSize)) using (ECDiffieHellman bob = ECDiffieHellmanFactory.Create(bobSize)) @@ -37,7 +38,7 @@ public static void TlsDerivation_SameSizeOtherKeyRequired(int aliceSize, int bob } [Fact] - public static void TlsRequiresLabel() + public void TlsRequiresLabel() { using (ECDiffieHellman ecdh = ECDiffieHellmanFactory.Create()) using (ECDiffieHellmanPublicKey publicKey = ecdh.PublicKey) @@ -48,7 +49,7 @@ public static void TlsRequiresLabel() } [Fact] - public static void TlsRequiresSeed() + public void TlsRequiresSeed() { using (ECDiffieHellman ecdh = ECDiffieHellmanFactory.Create()) using (ECDiffieHellmanPublicKey publicKey = ecdh.PublicKey) @@ -62,7 +63,7 @@ public static void TlsRequiresSeed() [InlineData(0)] [InlineData(63)] [InlineData(65)] - public static void TlsRequiresSeed64(int seedSize) + public void TlsRequiresSeed64(int seedSize) { byte[] seed = new byte[seedSize]; @@ -74,9 +75,10 @@ public static void TlsRequiresSeed64(int seedSize) } } - [Theory] - [MemberData(nameof(EveryKeysize))] - public static void SymmetricDerivation_TlsPrf(int keySize) + [Fact] + public void SymmetricDerivation_TlsPrf() => ForEachKeySize(SymmetricDerivation_TlsPrfImpl); + + private void SymmetricDerivation_TlsPrfImpl(int keySize) { using (ECDiffieHellman alice = ECDiffieHellmanFactory.Create(keySize)) using (ECDiffieHellman bob = ECDiffieHellmanFactory.Create(keySize)) @@ -91,7 +93,7 @@ public static void SymmetricDerivation_TlsPrf(int keySize) } [Fact] - public static void TlsPrfDerivationIsStable() + public void TlsPrfDerivationIsStable() { using (ECDiffieHellman alice = ECDiffieHellmanFactory.Create()) using (ECDiffieHellman bob = ECDiffieHellmanFactory.Create()) @@ -104,9 +106,10 @@ public static void TlsPrfDerivationIsStable() } } - [Theory] - [MemberData(nameof(EveryKeysize))] - public static void TlsPrfOutputIs48Bytes(int keySize) + [Fact] + public void TlsPrfOutputIs48Bytes() => ForEachKeySize(TlsPrfOutputIs48BytesImpl); + + private void TlsPrfOutputIs48BytesImpl(int keySize) { using (ECDiffieHellman ecdh = ECDiffieHellmanFactory.Create(keySize)) using (ECDiffieHellmanPublicKey publicKey = ecdh.PublicKey) @@ -118,7 +121,7 @@ public static void TlsPrfOutputIs48Bytes(int keySize) } [Fact] - public static void TlsPrfVariesOnOtherKey() + public void TlsPrfVariesOnOtherKey() { using (ECDiffieHellman alice = ECDiffieHellmanFactory.Create()) using (ECDiffieHellman bob = ECDiffieHellmanFactory.Create()) @@ -135,7 +138,7 @@ public static void TlsPrfVariesOnOtherKey() } [Fact] - public static void TlsPrfVariesOnLabel() + public void TlsPrfVariesOnLabel() { byte[] aliceLabel = s_fourByteLabel; byte[] bobLabel = new byte[5]; @@ -153,7 +156,7 @@ public static void TlsPrfVariesOnLabel() } [Fact] - public static void TlsPrfVariesOnSeed() + public void TlsPrfVariesOnSeed() { byte[] aliceSeed = s_emptySeed; byte[] bobSeed = new byte[64]; @@ -189,10 +192,9 @@ public static IEnumerable TlsDerivationTestCases() }; } -#if NET [Theory] [MemberData(nameof(TlsDerivationTestCases))] - public static void TlsDerivation_KnownResults(string labelText, string answerHex) + public void TlsDerivation_KnownResults(string labelText, string answerHex) { byte[] label = Encoding.ASCII.GetBytes(labelText); byte[] output; @@ -207,6 +209,5 @@ public static void TlsDerivation_KnownResults(string labelText, string answerHex Assert.Equal(answerHex, output.ByteArrayToHex()); } -#endif } } diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.Xml.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.Xml.cs index edf63c2295265e..8089af898f812f 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.Xml.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.Xml.cs @@ -8,7 +8,7 @@ namespace System.Security.Cryptography.EcDiffieHellman.Tests public partial class ECDiffieHellmanTests { [Fact] - public static void TestNotImplementedException() + public void TestNotImplementedException() { using (ECDiffieHellman ec = ECDiffieHellmanFactory.Create()) { diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.cs index dc7a757d6e5373..abf2f3ebf2ea20 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDiffieHellman/ECDiffieHellmanTests.cs @@ -3,85 +3,110 @@ using System.Collections.Generic; using System.Security.Cryptography.Tests; +using Test.Cryptography; using Xunit; -using Test.Cryptography; namespace System.Security.Cryptography.EcDiffieHellman.Tests { [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] - public partial class ECDiffieHellmanTests : EccTestBase + public abstract partial class ECDiffieHellmanTests : EccTestBase { - private static List s_everyKeysize; - private static List s_mismatchedKeysizes; + protected abstract ECDiffieHellmanProvider ECDiffieHellmanFactory { get; } - public static IEnumerable EveryKeysize() + private static Dictionary> s_everyKeysizePerProvider = new(); + private static Dictionary> s_mismatchedKeysizesPerProvider = new(); + + public List EveryKeysize() { - if (s_everyKeysize == null) + lock (s_everyKeysizePerProvider) { - List everyKeysize = new List(); - - using (ECDiffieHellman defaultKeysize = ECDiffieHellmanFactory.Create()) + if (!s_everyKeysizePerProvider.TryGetValue(ECDiffieHellmanFactory, out List everyKeysize)) { - foreach (KeySizes keySizes in defaultKeysize.LegalKeySizes) + everyKeysize = new List(); + + using (ECDiffieHellman defaultKeysize = ECDiffieHellmanFactory.Create()) { - for (int size = keySizes.MinSize; size <= keySizes.MaxSize; size += keySizes.SkipSize) + foreach (KeySizes keySizes in defaultKeysize.LegalKeySizes) { - everyKeysize.Add(new object[] { size }); - - if (keySizes.SkipSize == 0) + for (int size = keySizes.MinSize; size <= keySizes.MaxSize; size += keySizes.SkipSize) { - break; + everyKeysize.Add(size); + + if (keySizes.SkipSize == 0) + { + break; + } } } } + + s_everyKeysizePerProvider[ECDiffieHellmanFactory] = everyKeysize; } - s_everyKeysize = everyKeysize; + return everyKeysize; } - - return s_everyKeysize; } - public static IEnumerable MismatchedKeysizes() + public List<(int, int)> MismatchedKeysizes() { - if (s_mismatchedKeysizes == null) + lock (s_mismatchedKeysizesPerProvider) { - int firstSize = -1; - List mismatchedKeysizes = new List(); - - using (ECDiffieHellman defaultKeysize = ECDiffieHellmanFactory.Create()) + if (!s_mismatchedKeysizesPerProvider.TryGetValue(ECDiffieHellmanFactory, out List<(int, int)> mismatchedKeysizes)) { - foreach (KeySizes keySizes in defaultKeysize.LegalKeySizes) + int firstSize = -1; + mismatchedKeysizes = new List<(int, int)>(); + + using (ECDiffieHellman defaultKeysize = ECDiffieHellmanFactory.Create()) { - for (int size = keySizes.MinSize; size <= keySizes.MaxSize; size += keySizes.SkipSize) + foreach (KeySizes keySizes in defaultKeysize.LegalKeySizes) { - if (firstSize == -1) - { - firstSize = size; - } - else if (size != firstSize) - { - mismatchedKeysizes.Add(new object[] { firstSize, size }); - } - - if (keySizes.SkipSize == 0) + for (int size = keySizes.MinSize; size <= keySizes.MaxSize; size += keySizes.SkipSize) { - break; + if (firstSize == -1) + { + firstSize = size; + } + else if (size != firstSize) + { + mismatchedKeysizes.Add((firstSize, size)); + } + + if (keySizes.SkipSize == 0) + { + break; + } } } } + + s_mismatchedKeysizesPerProvider[ECDiffieHellmanFactory] = mismatchedKeysizes; } - s_mismatchedKeysizes = mismatchedKeysizes; + return mismatchedKeysizes; } + } - return s_mismatchedKeysizes; + protected void ForEachKeySize(Action test) + { + foreach (int size in EveryKeysize()) + { + test(size); + } } - [Theory] - [MemberData(nameof(EveryKeysize))] - public static void SupportsKeysize(int keySize) + protected void ForEachMismatchedKeySize(Action test) + { + foreach ((int, int) pair in MismatchedKeysizes()) + { + test(pair.Item1, pair.Item2); + } + } + + [Fact] + public void SupportsKeysize() => ForEachKeySize(SupportsKeysizeImpl); + + private void SupportsKeysizeImpl(int keySize) { using (ECDiffieHellman ecdh = ECDiffieHellmanFactory.Create(keySize)) { @@ -89,9 +114,10 @@ public static void SupportsKeysize(int keySize) } } - [Theory] - [MemberData(nameof(EveryKeysize))] - public static void PublicKey_NotNull(int keySize) + [Fact] + public void PublicKey_NotNull() => ForEachKeySize(PublicKey_NotNullImpl); + + private void PublicKey_NotNullImpl(int keySize) { using (ECDiffieHellman ecdh = ECDiffieHellmanFactory.Create(keySize)) using (ECDiffieHellmanPublicKey ecdhPubKey = ecdh.PublicKey) @@ -101,7 +127,7 @@ public static void PublicKey_NotNull(int keySize) } [Fact] - public static void PublicKeyIsFactory() + public void PublicKeyIsFactory() { using (ECDiffieHellman ecdh = ECDiffieHellmanFactory.Create()) using (ECDiffieHellmanPublicKey publicKey1 = ecdh.PublicKey) @@ -112,7 +138,7 @@ public static void PublicKeyIsFactory() } [Fact] - public static void PublicKey_TryExportSubjectPublicKeyInfo_TooSmall() + public void PublicKey_TryExportSubjectPublicKeyInfo_TooSmall() { using (ECDiffieHellman ecdh = ECDiffieHellmanFactory.Create()) using (ECDiffieHellmanPublicKey publicKey = ecdh.PublicKey) @@ -126,7 +152,7 @@ public static void PublicKey_TryExportSubjectPublicKeyInfo_TooSmall() [Theory] [InlineData(false)] [InlineData(true)] - public static void UseAfterDispose(bool importKey) + public void UseAfterDispose(bool importKey) { ECDiffieHellman key = ECDiffieHellmanFactory.Create(); ECDiffieHellmanPublicKey pubKey; @@ -172,8 +198,7 @@ public static void UseAfterDispose(bool importKey) pubKey.Dispose(); } -#if NET - private static ECDiffieHellman OpenKnownKey() + private ECDiffieHellman OpenKnownKey() { ECParameters ecParams = new ECParameters { @@ -199,7 +224,6 @@ private static ECDiffieHellman OpenKnownKey() ecdh.ImportParameters(ecParams); return ecdh; } -#endif } internal static class EcdhTestExtensions diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaFactory.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaFactory.cs deleted file mode 100644 index 6a46e313741b00..00000000000000 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaFactory.cs +++ /dev/null @@ -1,47 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Security.Cryptography.EcDsa.Tests -{ - public interface IECDsaProvider - { - ECDsa Create(); - ECDsa Create(int keySize); -#if NET - ECDsa Create(ECCurve curve); -#endif - bool IsCurveValid(Oid oid); - bool ExplicitCurvesSupported { get; } - - // In OSSL 3+ we use EVP_PKEY APIs instead of EC_KEY APIs so import and export of explicit curves also fails for SymCrypt. - bool ExplicitCurvesSupportFailOnUseOnly => PlatformDetection.IsSymCryptOpenSsl && SafeEvpPKeyHandle.OpenSslVersion < 0x3_00_00_00_0; - } - - public static partial class ECDsaFactory - { - public static ECDsa Create() - { - return s_provider.Create(); - } - - public static ECDsa Create(int keySize) - { - return s_provider.Create(keySize); - } - -#if NET - public static ECDsa Create(ECCurve curve) - { - return s_provider.Create(curve); - } -#endif - - public static bool IsCurveValid(Oid oid) - { - return s_provider.IsCurveValid(oid); - } - - public static bool ExplicitCurvesSupported => s_provider.ExplicitCurvesSupported; - public static bool ExplicitCurvesSupportFailOnUseOnly => s_provider.ExplicitCurvesSupportFailOnUseOnly; - } -} diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaFactoryTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaFactoryTests.cs index 84d53afe315413..6a4f81fd64b1bb 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaFactoryTests.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaFactoryTests.cs @@ -7,24 +7,24 @@ namespace System.Security.Cryptography.EcDsa.Tests { [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] - public static class ECDsaFactoryTests + public abstract class ECDsaFactoryTests : ECDsaTestsBase { [Fact] - public static void ECDsaCreateDefault_Equals_SameInstance() + public void ECDsaCreateDefault_Equals_SameInstance() { using ECDsa ecdsa = ECDsaFactory.Create(); AssertExtensions.TrueExpression(ecdsa.Equals(ecdsa)); } [Fact] - public static void ECDsaCreateKeySize_Equals_SameInstance() + public void ECDsaCreateKeySize_Equals_SameInstance() { using ECDsa ecdsa = ECDsaFactory.Create(256); AssertExtensions.TrueExpression(ecdsa.Equals(ecdsa)); } [Fact] - public static void ECDsaCreateKeySize_Equals_DifferentInstance_FalseForSameKeyMaterial() + public void ECDsaCreateKeySize_Equals_DifferentInstance_FalseForSameKeyMaterial() { using ECDsa ecdsa1 = ECDsaFactory.Create(); using ECDsa ecdsa2 = ECDsaFactory.Create(); @@ -35,7 +35,7 @@ public static void ECDsaCreateKeySize_Equals_DifferentInstance_FalseForSameKeyMa #if NET [Fact] - public static void ECDsaCreateCurve_Equals_SameInstance() + public void ECDsaCreateCurve_Equals_SameInstance() { using ECDsa ecdsa = ECDsaFactory.Create(ECCurve.NamedCurves.nistP256); AssertExtensions.TrueExpression(ecdsa.Equals(ecdsa)); diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaImportExport.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaImportExport.cs index 08fe32b17260a6..160a38e3e8a762 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaImportExport.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaImportExport.cs @@ -3,21 +3,20 @@ using System.Collections.Generic; using System.Security.Cryptography.Tests; -using System.Security.Cryptography.EcDiffieHellman.Tests; +using Microsoft.DotNet.XUnitExtensions; using Test.Cryptography; using Xunit; namespace System.Security.Cryptography.EcDsa.Tests { [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] - public class ECDsaImportExportTests : ECDsaTestsBase + public abstract class ECDsaImportExportTests : ECDsaTestsBase { - internal static bool CanDeriveNewPublicKey { get; } - = EcDiffieHellman.Tests.ECDiffieHellmanFactory.CanDeriveNewPublicKey; + protected abstract bool CanDeriveNewPublicKey { get; } #if NET [Fact] - public static void DiminishedCoordsRoundtrip() + public void DiminishedCoordsRoundtrip() { ECParameters toImport = EccTestData.GetNistP521DiminishedCoordsParameters(); ECParameters privateParams; @@ -36,14 +35,11 @@ public static void DiminishedCoordsRoundtrip() Assert.Null(publicParams.D); } - [Fact] + [ConditionalFact] [PlatformSpecific(TestPlatforms.Windows/* "parameters.Curve.Hash doesn't round trip on Unix." */)] - public static void ImportExplicitWithHashButNoSeed() + public void ImportExplicitWithHashButNoSeed() { - if (!ECDsaFactory.ExplicitCurvesSupported) - { - return; - } + SkipTestException.ThrowUnless(ECDsaFactory.ExplicitCurvesSupported); using (ECDsa ec = ECDsaFactory.Create()) { @@ -60,12 +56,12 @@ public static void ImportExplicitWithHashButNoSeed() } } - [Theory] - [MemberData(nameof(TestCurvesFull))] - public static void TestNamedCurves(CurveDef curveDef) + [ConditionalTheory] + [MemberData(nameof(AllTestCurves))] + public void TestNamedCurves(CurveDef curveDef) { - if (!curveDef.Curve.IsNamed) - return; + SkipTestException.ThrowUnless(curveDef.Curve.IsNamed); + SkipTestException.ThrowUnless(curveDef.IsCurveValidOnPlatform(ECDsaFactory)); using (ECDsa ec1 = ECDsaFactory.Create(curveDef.Curve)) { @@ -83,23 +79,26 @@ public static void TestNamedCurves(CurveDef curveDef) } } - [Theory, MemberData(nameof(TestInvalidCurves))] - public static void TestNamedCurvesNegative(CurveDef curveDef) + [ConditionalTheory, MemberData(nameof(PublicTestCurves))] + public void TestNamedCurvesNegative(CurveDef curveDef) { - if (!curveDef.Curve.IsNamed) - return; + SkipTestException.ThrowUnless(curveDef.Curve.IsNamed); + SkipTestException.ThrowWhen(curveDef.IsCurveValidOnPlatform(ECDsaFactory)); // An exception may be thrown during Create() if the Oid is bad, or later during native calls Assert.Throws(() => { - using ECDiffieHellman ecdh = ECDiffieHellmanFactory.Create(curveDef.Curve); - ecdh.ExportParameters(false); + using ECDsa ecdsa = ECDsaFactory.Create(curveDef.Curve); + ecdsa.ExportParameters(false); }); } - [ConditionalTheory(typeof(ECDsaImportExportTests), nameof(ECExplicitCurvesSupported)), MemberData(nameof(TestCurvesFull))] - public static void TestExplicitCurves(CurveDef curveDef) + [ConditionalTheory, MemberData(nameof(AllTestCurves))] + public void TestExplicitCurves(CurveDef curveDef) { + SkipTestException.ThrowUnless(ECExplicitCurvesSupported); + SkipTestException.ThrowUnless(curveDef.IsCurveValidOnPlatform(ECDsaFactory)); + using (ECDsa ec1 = ECDsaFactory.Create(curveDef.Curve)) { ECParameters param1 = ec1.ExportExplicitParameters(curveDef.IncludePrivate); @@ -116,9 +115,12 @@ public static void TestExplicitCurves(CurveDef curveDef) } } - [ConditionalTheory(typeof(ECDsaImportExportTests), nameof(ECExplicitCurvesSupported)), MemberData(nameof(TestCurves))] - public static void TestExplicitCurvesSignVerify(CurveDef curveDef) + [ConditionalTheory, MemberData(nameof(PublicTestCurves))] + public void TestExplicitCurvesSignVerify(CurveDef curveDef) { + SkipTestException.ThrowUnless(ECExplicitCurvesSupported); + SkipTestException.ThrowUnless(curveDef.IsCurveValidOnPlatform(ECDsaFactory)); + using (ECDsa ec1 = ECDsaFactory.Create(curveDef.Curve)) { byte[] data = new byte[0x10]; @@ -164,7 +166,7 @@ public static void TestExplicitCurvesSignVerify(CurveDef curveDef) } [Fact] - public static void TestNamedCurveNegative() + public void TestNamedCurveNegative() { Assert.Throws(() => ECCurve.CreateFromFriendlyName(null)); Assert.Throws(() => ECCurve.CreateFromValue(null)); @@ -177,7 +179,7 @@ public static void TestNamedCurveNegative() } [Fact] - public static void TestKeySizeCreateKey() + public void TestKeySizeCreateKey() { using (ECDsa ec = ECDsaFactory.Create(ECCurve.NamedCurves.nistP256)) { @@ -193,10 +195,12 @@ public static void TestKeySizeCreateKey() } } - [ConditionalFact(typeof(ECDsaImportExportTests), nameof(ECExplicitCurvesSupported))] + [ConditionalFact] [SkipOnPlatform(TestPlatforms.Android, "Android does not validate curve parameters")] - public static void TestExplicitImportValidationNegative() + public void TestExplicitImportValidationNegative() { + SkipTestException.ThrowUnless(ECExplicitCurvesSupported); + unchecked { using (ECDsa ec = ECDsaFactory.Create()) @@ -242,9 +246,11 @@ public static void TestExplicitImportValidationNegative() } } - [ConditionalFact(typeof(ECDsaImportExportTests), nameof(ECDsa224Available))] - public static void TestNamedImportValidationNegative() + [ConditionalFact] + public void TestNamedImportValidationNegative() { + SkipTestException.ThrowUnless(ECDsa224Available); + unchecked { using(ECDsa ec = ECDsaFactory.Create()) @@ -272,9 +278,11 @@ public static void TestNamedImportValidationNegative() } } - [ConditionalFact(typeof(ECDsaImportExportTests), nameof(ECExplicitCurvesSupported))] - public static void TestGeneralExportWithExplicitParameters() + [ConditionalFact] + public void TestGeneralExportWithExplicitParameters() { + SkipTestException.ThrowUnless(ECExplicitCurvesSupported); + using (ECDsa ecdsa = ECDsaFactory.Create()) { ECParameters param = EccTestData.GetNistP256ExplicitTestData(); @@ -290,9 +298,11 @@ public static void TestGeneralExportWithExplicitParameters() } } - [ConditionalFact(typeof(ECDsaImportExportTests), nameof(ECDsa224Available))] - public static void TestNamedCurveWithExplicitKey() + [ConditionalFact] + public void TestNamedCurveWithExplicitKey() { + SkipTestException.ThrowUnless(ECDsa224Available); + using (ECDsa ec = ECDsaFactory.Create()) { ECParameters parameters = EccTestData.GetNistP224KeyTestData(); @@ -302,7 +312,7 @@ public static void TestNamedCurveWithExplicitKey() } [Fact] - public static void ExportIncludingPrivateOnPublicOnlyKey() + public void ExportIncludingPrivateOnPublicOnlyKey() { ECParameters iutParameters = new ECParameters { @@ -330,9 +340,11 @@ public static void ExportIncludingPrivateOnPublicOnlyKey() } } - [ConditionalFact(typeof(ECDsaImportExportTests), nameof(CanDeriveNewPublicKey))] - public static void ImportFromPrivateOnlyKey() + [ConditionalFact] + public void ImportFromPrivateOnlyKey() { + SkipTestException.ThrowUnless(CanDeriveNewPublicKey); + byte[] expectedX = "00d45615ed5d37fde699610a62cd43ba76bedd8f85ed31005fe00d6450fbbd101291abd96d4945a8b57bc73b3fe9f4671105309ec9b6879d0551d930dac8ba45d255".HexToByteArray(); byte[] expectedY = "01425332844e592b440c0027972ad1526431c06732df19cd46a242172d4dd67c2c8c99dfc22e49949a56cf90c6473635ce82f25b33682fb19bc33bd910ed8ce3a7fa".HexToByteArray(); @@ -354,69 +366,81 @@ public static void ImportFromPrivateOnlyKey() } } - [ConditionalFact(typeof(ECDsaImportExportTests), nameof(CanDeriveNewPublicKey))] - public static void DerivePublicKey_Named_P256() + [ConditionalFact] + public void DerivePublicKey_Named_P256() { + SkipTestException.ThrowUnless(CanDeriveNewPublicKey); + VerifyPrivateKeyDerivesPublicKey(EccTestData.GetNistP256ReferenceKey(), explicitCurve: false); } - [ConditionalFact(typeof(ECDsaImportExportTests), nameof(CanDeriveNewPublicKey))] - public static void DerivePublicKey_Named_P521_DiminishedCoords() + [ConditionalFact] + public void DerivePublicKey_Named_P521_DiminishedCoords() { + SkipTestException.ThrowUnless(CanDeriveNewPublicKey); + VerifyPrivateKeyDerivesPublicKey(EccTestData.GetNistP521DiminishedCoordsParameters(), explicitCurve: false); } - [ConditionalFact(typeof(ECDsaImportExportTests), nameof(CanDeriveNewPublicKey))] - public static void DerivePublicKey_Named_Sect163k1() + [ConditionalFact] + public void DerivePublicKey_Named_Sect163k1() { - if (!ECDsaFactory.IsCurveValid(EccTestData.Sect163k1Key1.Curve.Oid)) - return; + SkipTestException.ThrowUnless(CanDeriveNewPublicKey); + SkipTestException.ThrowUnless(ECDsaFactory.IsCurveValid(EccTestData.Sect163k1Key1.Curve.Oid)); VerifyPrivateKeyDerivesPublicKey(EccTestData.Sect163k1Key1, explicitCurve: false); } - [ConditionalFact(typeof(ECDsaImportExportTests), nameof(CanDeriveNewPublicKey))] - public static void DerivePublicKey_Named_C2pnb163v1() + [ConditionalFact] + public void DerivePublicKey_Named_C2pnb163v1() { - if (!ECDsaFactory.IsCurveValid(EccTestData.C2pnb163v1Key1.Curve.Oid)) - return; + SkipTestException.ThrowUnless(CanDeriveNewPublicKey); + SkipTestException.ThrowUnless(ECDsaFactory.IsCurveValid(EccTestData.C2pnb163v1Key1.Curve.Oid)); VerifyPrivateKeyDerivesPublicKey(EccTestData.C2pnb163v1Key1, explicitCurve: false); } - [ConditionalFact(typeof(ECDsaImportExportTests), nameof(ECExplicitCurvesSupported), nameof(CanDeriveNewPublicKey))] - public static void DerivePublicKey_Explicit_P256() + [ConditionalFact] + public void DerivePublicKey_Explicit_P256() { + SkipTestException.ThrowUnless(ECExplicitCurvesSupported); + SkipTestException.ThrowUnless(CanDeriveNewPublicKey); + VerifyPrivateKeyDerivesPublicKey(EccTestData.GetNistP256ReferenceKeyExplicit(), explicitCurve: true); } - [ConditionalFact(typeof(ECDsaImportExportTests), nameof(ECExplicitCurvesSupported), nameof(CanDeriveNewPublicKey))] - public static void DerivePublicKey_Explicit_P521_DiminishedCoords() + [ConditionalFact] + public void DerivePublicKey_Explicit_P521_DiminishedCoords() { + SkipTestException.ThrowUnless(ECExplicitCurvesSupported); + SkipTestException.ThrowUnless(CanDeriveNewPublicKey); + ECParameters p521 = EccTestData.GetNistP521DiminishedCoordsParameters(); p521.Curve = EccTestData.GetNistP521ExplicitCurve(); VerifyPrivateKeyDerivesPublicKey(p521, explicitCurve: true); } - [ConditionalFact(typeof(ECDsaImportExportTests), nameof(ECExplicitCurvesSupported), nameof(CanDeriveNewPublicKey))] - public static void DerivePublicKey_Explicit_Sect163k1() + [ConditionalFact] + public void DerivePublicKey_Explicit_Sect163k1() { - if (!ECDsaFactory.IsCurveValid(EccTestData.Sect163k1Key1.Curve.Oid)) - return; + SkipTestException.ThrowUnless(ECExplicitCurvesSupported); + SkipTestException.ThrowUnless(CanDeriveNewPublicKey); + SkipTestException.ThrowUnless(ECDsaFactory.IsCurveValid(EccTestData.Sect163k1Key1.Curve.Oid)); VerifyPrivateKeyDerivesPublicKey(EccTestData.Sect163k1Key1Explicit, explicitCurve: true); } - [ConditionalFact(typeof(ECDsaImportExportTests), nameof(ECExplicitCurvesSupported), nameof(CanDeriveNewPublicKey))] - public static void DerivePublicKey_Explicit_C2pnb163v1() + [ConditionalFact] + public void DerivePublicKey_Explicit_C2pnb163v1() { - if (!ECDsaFactory.IsCurveValid(EccTestData.C2pnb163v1Key1.Curve.Oid)) - return; + SkipTestException.ThrowUnless(ECExplicitCurvesSupported); + SkipTestException.ThrowUnless(CanDeriveNewPublicKey); + SkipTestException.ThrowUnless(ECDsaFactory.IsCurveValid(EccTestData.C2pnb163v1Key1.Curve.Oid)); VerifyPrivateKeyDerivesPublicKey(EccTestData.C2pnb163v1Key1Explicit, explicitCurve: true); } - private static void VerifyPrivateKeyDerivesPublicKey(ECParameters knownKey, bool explicitCurve) + private void VerifyPrivateKeyDerivesPublicKey(ECParameters knownKey, bool explicitCurve) { ECParameters importParams = new ECParameters { @@ -438,10 +462,15 @@ private static void VerifyPrivateKeyDerivesPublicKey(ECParameters knownKey, bool } } - [Theory] + [ConditionalTheory] [MemberData(nameof(NamedCurves))] - public static void OidPresentOnCurveMiscased(ECCurve curve) + public void OidPresentOnCurveMiscased(ECCurve curve, bool checkCurveValidity) { + if (checkCurveValidity) + { + SkipTestException.ThrowUnless(ECDsaFactory.IsCurveValid(curve.Oid)); + } + ECCurve miscasedCurve = ECCurve.CreateFromFriendlyName(InvertStringCase(curve.Oid.FriendlyName)); Assert.NotEqual(miscasedCurve.Oid.FriendlyName, curve.Oid.FriendlyName); Assert.Equal(miscasedCurve.Oid.FriendlyName, curve.Oid.FriendlyName, ignoreCase: true); @@ -463,22 +492,16 @@ public static IEnumerable NamedCurves { get { - yield return new object[] { ECCurve.NamedCurves.nistP256 }; - yield return new object[] { ECCurve.NamedCurves.nistP384 }; - yield return new object[] { ECCurve.NamedCurves.nistP521 }; - yield return new object[] { ECCurve.CreateFromFriendlyName("ECDSA_P256") }; - yield return new object[] { ECCurve.CreateFromFriendlyName("ECDSA_P384") }; - yield return new object[] { ECCurve.CreateFromFriendlyName("ECDSA_P521") }; - - if (ECDsaFactory.IsCurveValid(ECCurve.NamedCurves.brainpoolP160r1.Oid)) - { - yield return new object[] { ECCurve.NamedCurves.brainpoolP160r1 }; - } - - if (ECDsaFactory.IsCurveValid(ECCurve.NamedCurves.brainpoolP160t1.Oid)) - { - yield return new object[] { ECCurve.NamedCurves.brainpoolP160t1 }; - } + yield return new object[] { ECCurve.NamedCurves.nistP256, false }; + yield return new object[] { ECCurve.NamedCurves.nistP384, false }; + yield return new object[] { ECCurve.NamedCurves.nistP521, false }; + yield return new object[] { ECCurve.CreateFromFriendlyName("ECDSA_P256"), false }; + yield return new object[] { ECCurve.CreateFromFriendlyName("ECDSA_P384"), false }; + yield return new object[] { ECCurve.CreateFromFriendlyName("ECDSA_P521"), false }; + + // Curves may not be valid for all platforms, so validity must be checked at runtime + yield return new object[] { ECCurve.NamedCurves.brainpoolP160r1, true }; + yield return new object[] { ECCurve.NamedCurves.brainpoolP160t1, true }; } } diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaKeyFileTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaKeyFileTests.cs index 51bb3d34182aa4..3fa986e56e646a 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaKeyFileTests.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaKeyFileTests.cs @@ -8,9 +8,14 @@ namespace System.Security.Cryptography.EcDsa.Tests { [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] [ActiveIssue("https://github.com/dotnet/runtime/issues/64389", TestPlatforms.Windows)] - public class ECDsaKeyFileTests : ECKeyFileTests + public abstract class ECDsaKeyFileTests : ECKeyFileTests { + protected abstract ECDsaProvider ECDsaFactory { get; } + protected override ECDsa CreateKey() => ECDsaFactory.Create(); protected override void Exercise(ECDsa key) => key.Exercise(); + protected override bool SupportsExplicitCurves => + ECDsaFactory.ExplicitCurvesSupported || ECDsaFactory.ExplicitCurvesSupportFailOnUseOnly; + protected override bool IsCurveSupported(Oid oid) => ECDsaFactory.IsCurveValid(oid); } } diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaProvider.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaProvider.cs new file mode 100644 index 00000000000000..99c145d0be05ce --- /dev/null +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaProvider.cs @@ -0,0 +1,19 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.Win32.SafeHandles; + +namespace System.Security.Cryptography.EcDsa.Tests +{ + public abstract class ECDsaProvider + { + public abstract ECDsa Create(); + public abstract ECDsa Create(int keySize); + public abstract ECDsa Create(ECCurve curve); + public abstract bool IsCurveValid(Oid oid); + public abstract bool ExplicitCurvesSupported { get; } + + // In OSSL 3+ we use EVP_PKEY APIs instead of EC_KEY APIs so import and export of explicit curves also fails for SymCrypt. + public bool ExplicitCurvesSupportFailOnUseOnly => PlatformDetection.IsSymCryptOpenSsl && SafeEvpPKeyHandle.OpenSslVersion < 0x3_00_00_00_0; + } +} diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaSignatureFormatTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaSignatureFormatTests.cs index 621f5a6ee67308..2abd6ea67c2c3f 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaSignatureFormatTests.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaSignatureFormatTests.cs @@ -12,9 +12,27 @@ namespace System.Security.Cryptography.EcDsa.Tests [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] public abstract class ECDsaSignatureFormatTests : DsaFamilySignatureFormatTests { + private static readonly Dictionary s_keyCache = new(); + + protected abstract ECDsaProvider ECDsaFactory { get; } + protected override bool SupportsSha2 => true; - private static KeyDescription CreateKey(ECCurve curve) + protected override KeyDescription[] GenerateTestKeys() + { + lock (s_keyCache) + { + if (!s_keyCache.TryGetValue(ECDsaFactory, out KeyDescription[] keys)) + { + keys = LocalGenerateTestKeys().ToArray(); + s_keyCache.Add(ECDsaFactory, keys); + } + + return keys; + } + } + + private KeyDescription CreateKey(ECCurve curve) { ECDsa dsa = ECDsaFactory.Create(curve); @@ -24,7 +42,7 @@ private static KeyDescription CreateKey(ECCurve curve) dsa.KeySize); } - private static KeyDescription OpenKey(in ECParameters ecParameters) + private KeyDescription OpenKey(in ECParameters ecParameters) { ECDsa dsa = ECDsaFactory.Create(); dsa.ImportParameters(ecParameters); @@ -35,7 +53,7 @@ private static KeyDescription OpenKey(in ECParameters ecParameters) dsa.KeySize); } - protected static IEnumerable LocalGenerateTestKeys() + protected IEnumerable LocalGenerateTestKeys() { if (ECDsaFactory.IsCurveValid(EccTestData.BrainpoolP160r1Key1.Curve.Oid)) { @@ -56,11 +74,8 @@ protected static IEnumerable LocalGenerateTestKeys() } } - public sealed class ECDsaArraySignatureFormatTests : ECDsaSignatureFormatTests + public abstract class ECDsaArraySignatureFormatTests : ECDsaSignatureFormatTests { - private static readonly KeyDescription[] s_keys = LocalGenerateTestKeys().ToArray(); - - protected override KeyDescription[] GenerateTestKeys() => s_keys; protected override bool IsArrayBased => true; protected override byte[] SignHash( @@ -100,11 +115,8 @@ protected override bool VerifyData( } } - public sealed class ECDsaArrayOffsetSignatureFormatTests : ECDsaSignatureFormatTests + public abstract class ECDsaArrayOffsetSignatureFormatTests : ECDsaSignatureFormatTests { - private static readonly KeyDescription[] s_keys = LocalGenerateTestKeys().ToArray(); - - protected override KeyDescription[] GenerateTestKeys() => s_keys; protected override bool IsArrayBased => true; protected override byte[] SignHash( @@ -221,11 +233,8 @@ public void OffsetAndCountOutOfRange() } } - public sealed class ECDsaSpanSignatureFormatTests : ECDsaSignatureFormatTests + public abstract class ECDsaSpanSignatureFormatTests : ECDsaSignatureFormatTests { - private static readonly KeyDescription[] s_keys = LocalGenerateTestKeys().ToArray(); - - protected override KeyDescription[] GenerateTestKeys() => s_keys; protected override bool IsArrayBased => false; protected override byte[] SignHash( diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaStub.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaStub.cs deleted file mode 100644 index 43c44b71a2a288..00000000000000 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaStub.cs +++ /dev/null @@ -1,55 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.IO; -using System.Security.Cryptography; - -namespace System.Security.Cryptography.EcDsa.Tests -{ - // Stub out the last remaining abstract members to throw NotImplementedException - internal class ECDsaStub : ECDsa - { - public override byte[] SignHash(byte[] hash) - { - return Array.Empty(); - } - - public override bool VerifyHash(byte[] hash, byte[] signature) - { - return false; - } - - protected override byte[] HashData(byte[] data, int offset, int count, HashAlgorithmName hashAlgorithm) - { - throw new NotImplementedException(); - } - - protected override byte[] HashData(Stream data, HashAlgorithmName hashAlgorithm) - { - throw new NotImplementedException(); - } - -#if NET - public override void ImportParameters(ECParameters parameters) - { - throw new NotImplementedException(); - } - - public override ECParameters ExportParameters(bool includePrivateParameters) - { - throw new NotImplementedException(); - } - - public override ECParameters ExportExplicitParameters(bool includePrivateParameters) - { - throw new NotImplementedException(); - } - - public override void GenerateKey(ECCurve curve) - { - throw new NotImplementedException(); - } -#endif - } -} diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaTests.NistValidation.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaTests.NistValidation.cs index e0da3f3e75a811..feb5433874fba3 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaTests.NistValidation.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaTests.NistValidation.cs @@ -352,7 +352,7 @@ public void ValidateNistP521Sha3_512() HashAlgorithmName.SHA3_512); } - private static void Validate( + private void Validate( ECParameters parameters, ECCurve explicitCurve, byte[] msg, diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaTests.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaTests.cs index da6b507994cd2b..fae6e5f35c1b2f 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaTests.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaTests.cs @@ -13,7 +13,7 @@ namespace System.Security.Cryptography.EcDsa.Tests { [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] - public sealed class ECDsaTests_Array : ECDsaTests + public abstract class ECDsaTests_Array : ECDsaTests { protected override bool VerifyData(ECDsa ecdsa, byte[] data, int offset, int count, byte[] signature, HashAlgorithmName hashAlgorithm) => ecdsa.VerifyData(data, offset, count, signature, hashAlgorithm); @@ -29,93 +29,109 @@ protected override void UseAfterDispose(ECDsa ecdsa, byte[] data, byte[] sig) Assert.Throws(() => ecdsa.SignHash(hash)); } - [Theory, MemberData(nameof(RealImplementations))] - public void SignData_InvalidArguments_Throws(ECDsa ecdsa) + [Fact] + public void SignData_InvalidArguments_Throws() { - AssertExtensions.Throws("data", () => ecdsa.SignData((byte[])null, default(HashAlgorithmName))); - AssertExtensions.Throws("data", () => ecdsa.SignData(null, -1, -1, default(HashAlgorithmName))); + using (ECDsa ecdsa = ECDsaFactory.Create()) + { + AssertExtensions.Throws("data", () => ecdsa.SignData((byte[])null, default(HashAlgorithmName))); + AssertExtensions.Throws("data", () => ecdsa.SignData(null, -1, -1, default(HashAlgorithmName))); - AssertExtensions.Throws("offset", () => ecdsa.SignData(new byte[0], -1, -1, default(HashAlgorithmName))); - AssertExtensions.Throws("offset", () => ecdsa.SignData(new byte[0], 2, 1, default(HashAlgorithmName))); + AssertExtensions.Throws("offset", () => ecdsa.SignData(new byte[0], -1, -1, default(HashAlgorithmName))); + AssertExtensions.Throws("offset", () => ecdsa.SignData(new byte[0], 2, 1, default(HashAlgorithmName))); - AssertExtensions.Throws("count", () => ecdsa.SignData(new byte[0], 0, -1, default(HashAlgorithmName))); - AssertExtensions.Throws("count", () => ecdsa.SignData(new byte[0], 0, 1, default(HashAlgorithmName))); + AssertExtensions.Throws("count", () => ecdsa.SignData(new byte[0], 0, -1, default(HashAlgorithmName))); + AssertExtensions.Throws("count", () => ecdsa.SignData(new byte[0], 0, 1, default(HashAlgorithmName))); - AssertExtensions.Throws("hashAlgorithm", () => ecdsa.SignData(new byte[0], default(HashAlgorithmName))); - AssertExtensions.Throws("hashAlgorithm", () => ecdsa.SignData(new byte[0], 0, 0, default(HashAlgorithmName))); - AssertExtensions.Throws("hashAlgorithm", () => ecdsa.SignData(new byte[0], 0, 0, default(HashAlgorithmName))); - AssertExtensions.Throws("hashAlgorithm", () => ecdsa.SignData(new byte[10], 0, 10, new HashAlgorithmName(""))); + AssertExtensions.Throws("hashAlgorithm", () => ecdsa.SignData(new byte[0], default(HashAlgorithmName))); + AssertExtensions.Throws("hashAlgorithm", () => ecdsa.SignData(new byte[0], 0, 0, default(HashAlgorithmName))); + AssertExtensions.Throws("hashAlgorithm", () => ecdsa.SignData(new byte[0], 0, 0, default(HashAlgorithmName))); + AssertExtensions.Throws("hashAlgorithm", () => ecdsa.SignData(new byte[10], 0, 10, new HashAlgorithmName(""))); - Assert.ThrowsAny(() => ecdsa.SignData(new byte[0], new HashAlgorithmName(Guid.NewGuid().ToString("N")))); - Assert.ThrowsAny(() => ecdsa.SignData(new byte[0], 0, 0, new HashAlgorithmName(Guid.NewGuid().ToString("N")))); + Assert.ThrowsAny(() => ecdsa.SignData(new byte[0], new HashAlgorithmName(Guid.NewGuid().ToString("N")))); + Assert.ThrowsAny(() => ecdsa.SignData(new byte[0], 0, 0, new HashAlgorithmName(Guid.NewGuid().ToString("N")))); + } } - [Theory, MemberData(nameof(RealImplementations))] - public void VerifyData_InvalidArguments_Throws(ECDsa ecdsa) + [Fact] + public void VerifyData_InvalidArguments_Throws() { - AssertExtensions.Throws("data", () => ecdsa.VerifyData((byte[])null, null, default(HashAlgorithmName))); - AssertExtensions.Throws("data", () => ecdsa.VerifyData(null, -1, -1, null, default(HashAlgorithmName))); + using (ECDsa ecdsa = ECDsaFactory.Create()) + { + AssertExtensions.Throws("data", () => ecdsa.VerifyData((byte[])null, null, default(HashAlgorithmName))); + AssertExtensions.Throws("data", () => ecdsa.VerifyData(null, -1, -1, null, default(HashAlgorithmName))); - AssertExtensions.Throws("signature", () => ecdsa.VerifyData(new byte[0], null, default(HashAlgorithmName))); - AssertExtensions.Throws("signature", () => ecdsa.VerifyData(new byte[0], 0, 0, null, default(HashAlgorithmName))); + AssertExtensions.Throws("signature", () => ecdsa.VerifyData(new byte[0], null, default(HashAlgorithmName))); + AssertExtensions.Throws("signature", () => ecdsa.VerifyData(new byte[0], 0, 0, null, default(HashAlgorithmName))); - AssertExtensions.Throws("offset", () => ecdsa.VerifyData(new byte[0], -1, -1, null, default(HashAlgorithmName))); - AssertExtensions.Throws("offset", () => ecdsa.VerifyData(new byte[0], 2, 1, null, default(HashAlgorithmName))); + AssertExtensions.Throws("offset", () => ecdsa.VerifyData(new byte[0], -1, -1, null, default(HashAlgorithmName))); + AssertExtensions.Throws("offset", () => ecdsa.VerifyData(new byte[0], 2, 1, null, default(HashAlgorithmName))); - AssertExtensions.Throws("count", () => ecdsa.VerifyData(new byte[0], 0, -1, null, default(HashAlgorithmName))); - AssertExtensions.Throws("count", () => ecdsa.VerifyData(new byte[0], 0, 1, null, default(HashAlgorithmName))); + AssertExtensions.Throws("count", () => ecdsa.VerifyData(new byte[0], 0, -1, null, default(HashAlgorithmName))); + AssertExtensions.Throws("count", () => ecdsa.VerifyData(new byte[0], 0, 1, null, default(HashAlgorithmName))); - AssertExtensions.Throws("hashAlgorithm", () => ecdsa.VerifyData(new byte[0], new byte[0], default(HashAlgorithmName))); - AssertExtensions.Throws("hashAlgorithm", () => ecdsa.VerifyData(new byte[0], 0, 0, new byte[0], default(HashAlgorithmName))); - AssertExtensions.Throws("hashAlgorithm", () => ecdsa.VerifyData(new byte[10], new byte[0], new HashAlgorithmName(""))); - AssertExtensions.Throws("hashAlgorithm", () => ecdsa.VerifyData(new byte[10], 0, 10, new byte[0], new HashAlgorithmName(""))); + AssertExtensions.Throws("hashAlgorithm", () => ecdsa.VerifyData(new byte[0], new byte[0], default(HashAlgorithmName))); + AssertExtensions.Throws("hashAlgorithm", () => ecdsa.VerifyData(new byte[0], 0, 0, new byte[0], default(HashAlgorithmName))); + AssertExtensions.Throws("hashAlgorithm", () => ecdsa.VerifyData(new byte[10], new byte[0], new HashAlgorithmName(""))); + AssertExtensions.Throws("hashAlgorithm", () => ecdsa.VerifyData(new byte[10], 0, 10, new byte[0], new HashAlgorithmName(""))); - Assert.ThrowsAny(() => ecdsa.VerifyData(new byte[0], new byte[0], new HashAlgorithmName(Guid.NewGuid().ToString("N")))); - Assert.ThrowsAny(() => ecdsa.VerifyData(new byte[0], 0, 0, new byte[0], new HashAlgorithmName(Guid.NewGuid().ToString("N")))); + Assert.ThrowsAny(() => ecdsa.VerifyData(new byte[0], new byte[0], new HashAlgorithmName(Guid.NewGuid().ToString("N")))); + Assert.ThrowsAny(() => ecdsa.VerifyData(new byte[0], 0, 0, new byte[0], new HashAlgorithmName(Guid.NewGuid().ToString("N")))); + } } - [Theory, MemberData(nameof(RealImplementations))] - public void SignHash_InvalidArguments_Throws(ECDsa ecdsa) + [Fact] + public void SignHash_InvalidArguments_Throws() { - AssertExtensions.Throws("hash", () => ecdsa.SignHash(null)); + using (ECDsa ecdsa = ECDsaFactory.Create()) + { + AssertExtensions.Throws("hash", () => ecdsa.SignHash(null)); + } } - [Theory, MemberData(nameof(RealImplementations))] - public void VerifyHash_InvalidArguments_Throws(ECDsa ecdsa) + [Fact] + public void VerifyHash_InvalidArguments_Throws() { - AssertExtensions.Throws("hash", () => ecdsa.VerifyHash(null, null)); - AssertExtensions.Throws("signature", () => ecdsa.VerifyHash(new byte[0], null)); + using (ECDsa ecdsa = ECDsaFactory.Create()) + { + AssertExtensions.Throws("hash", () => ecdsa.VerifyHash(null, null)); + AssertExtensions.Throws("signature", () => ecdsa.VerifyHash(new byte[0], null)); + } } - [Theory] - [MemberData(nameof(RealImplementations))] - public void SignHash_NullSignature_Fails(ECDsa ecdsa) + [Fact] + public void SignHash_NullSignature_Fails() { - byte[] hash = RandomNumberGenerator.GetBytes(SHA256.HashSizeInBytes); + using (ECDsa ecdsa = ECDsaFactory.Create()) + { + byte[] hash = RandomNumberGenerator.GetBytes(SHA256.HashSizeInBytes); - AssertExtensions.Throws("destination", () => - ecdsa.SignHash(hash, (Span)null, DSASignatureFormat.IeeeP1363FixedFieldConcatenation)); + AssertExtensions.Throws("destination", () => + ecdsa.SignHash(hash, (Span)null, DSASignatureFormat.IeeeP1363FixedFieldConcatenation)); - bool result = ecdsa.TrySignHash(hash, (Span)null, DSASignatureFormat.IeeeP1363FixedFieldConcatenation, out int bytesWritten); - Assert.False(result); - Assert.Equal(0, bytesWritten); + bool result = ecdsa.TrySignHash(hash, (Span)null, DSASignatureFormat.IeeeP1363FixedFieldConcatenation, out int bytesWritten); + Assert.False(result); + Assert.Equal(0, bytesWritten); + } } - [Theory] - [MemberData(nameof(RealImplementations))] - public void SignData_NullSignature_Fails(ECDsa ecdsa) + [Fact] + public void SignData_NullSignature_Fails() { - AssertExtensions.Throws("destination", () => - ecdsa.SignData("hello"u8, (Span)null, HashAlgorithmName.SHA256, DSASignatureFormat.IeeeP1363FixedFieldConcatenation)); + using (ECDsa ecdsa = ECDsaFactory.Create()) + { + AssertExtensions.Throws("destination", () => + ecdsa.SignData("hello"u8, (Span)null, HashAlgorithmName.SHA256, DSASignatureFormat.IeeeP1363FixedFieldConcatenation)); - bool result = ecdsa.TrySignData("hello"u8, (Span)null, HashAlgorithmName.SHA256, DSASignatureFormat.IeeeP1363FixedFieldConcatenation, out int bytesWritten); - Assert.False(result); - Assert.Equal(0, bytesWritten); + bool result = ecdsa.TrySignData("hello"u8, (Span)null, HashAlgorithmName.SHA256, DSASignatureFormat.IeeeP1363FixedFieldConcatenation, out int bytesWritten); + Assert.False(result); + Assert.Equal(0, bytesWritten); + } } } [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] - public sealed class ECDsaTests_Stream : ECDsaTests + public abstract class ECDsaTests_Stream : ECDsaTests { protected override bool VerifyData(ECDsa ecdsa, byte[] data, int offset, int count, byte[] signature, HashAlgorithmName hashAlgorithm) { @@ -133,23 +149,29 @@ protected override byte[] SignData(ECDsa ecdsa, byte[] data, int offset, int cou return result; } - [Theory, MemberData(nameof(RealImplementations))] - public void SignData_InvalidArguments_Throws(ECDsa ecdsa) + [Fact] + public void SignData_InvalidArguments_Throws() { - AssertExtensions.Throws("data", () => ecdsa.SignData((Stream)null, default(HashAlgorithmName))); - AssertExtensions.Throws("hashAlgorithm", () => ecdsa.SignData(new MemoryStream(), default(HashAlgorithmName))); - AssertExtensions.Throws("hashAlgorithm", () => ecdsa.SignData(new MemoryStream(), new HashAlgorithmName(""))); - Assert.ThrowsAny(() => ecdsa.SignData(new MemoryStream(), new HashAlgorithmName(Guid.NewGuid().ToString("N")))); + using (ECDsa ecdsa = ECDsaFactory.Create()) + { + AssertExtensions.Throws("data", () => ecdsa.SignData((Stream)null, default(HashAlgorithmName))); + AssertExtensions.Throws("hashAlgorithm", () => ecdsa.SignData(new MemoryStream(), default(HashAlgorithmName))); + AssertExtensions.Throws("hashAlgorithm", () => ecdsa.SignData(new MemoryStream(), new HashAlgorithmName(""))); + Assert.ThrowsAny(() => ecdsa.SignData(new MemoryStream(), new HashAlgorithmName(Guid.NewGuid().ToString("N")))); + } } - [Theory, MemberData(nameof(RealImplementations))] - public void VerifyData_InvalidArguments_Throws(ECDsa ecdsa) + [Fact] + public void VerifyData_InvalidArguments_Throws() { - AssertExtensions.Throws("data", () => ecdsa.VerifyData((Stream)null, null, default(HashAlgorithmName))); - AssertExtensions.Throws("signature", () => ecdsa.VerifyData(new MemoryStream(), null, default(HashAlgorithmName))); - AssertExtensions.Throws("hashAlgorithm", () => ecdsa.VerifyData(new MemoryStream(), new byte[0], default(HashAlgorithmName))); - AssertExtensions.Throws("hashAlgorithm", () => ecdsa.VerifyData(new MemoryStream(), new byte[0], new HashAlgorithmName(""))); - Assert.ThrowsAny(() => ecdsa.VerifyData(new MemoryStream(), new byte[0], new HashAlgorithmName(Guid.NewGuid().ToString("N")))); + using (ECDsa ecdsa = ECDsaFactory.Create()) + { + AssertExtensions.Throws("data", () => ecdsa.VerifyData((Stream)null, null, default(HashAlgorithmName))); + AssertExtensions.Throws("signature", () => ecdsa.VerifyData(new MemoryStream(), null, default(HashAlgorithmName))); + AssertExtensions.Throws("hashAlgorithm", () => ecdsa.VerifyData(new MemoryStream(), new byte[0], default(HashAlgorithmName))); + AssertExtensions.Throws("hashAlgorithm", () => ecdsa.VerifyData(new MemoryStream(), new byte[0], new HashAlgorithmName(""))); + Assert.ThrowsAny(() => ecdsa.VerifyData(new MemoryStream(), new byte[0], new HashAlgorithmName(Guid.NewGuid().ToString("N")))); + } } } @@ -172,25 +194,20 @@ protected virtual byte[] SignHash(ECDsa ecdsa, byte[] hash, int offset, int coun protected virtual bool VerifyHash(ECDsa ecdsa, byte[] hash, int offset, int count, byte[] signature) => throw new SkipTestException("VerifyHash not implemented."); - public static IEnumerable RealImplementations() => - new[] { - new ECDsa[] { ECDsaFactory.Create() }, - }; - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - [Theory] - [MemberData(nameof(RealImplementations))] - public void UseAfterDispose_Import(ECDsa ecdsa) + [Fact] + public void UseAfterDispose_Import() { + ECDsa ecdsa = ECDsaFactory.Create(); ecdsa.ImportParameters(EccTestData.GetNistP256ReferenceKey()); UseAfterDispose(ecdsa); } - [Theory] - [MemberData(nameof(RealImplementations))] - public void UseAfterDispose_NewKey(ECDsa ecdsa) + [Fact] + public void UseAfterDispose_NewKey() { + ECDsa ecdsa = ECDsaFactory.Create(); UseAfterDispose(ecdsa); } @@ -235,75 +252,87 @@ protected virtual void UseAfterDispose(ECDsa ecdsa, byte[] data, byte[] sig) () => VerifyData(ecdsa, data, sig, HashAlgorithmName.SHA256)); } - [ConditionalTheory] - [MemberData(nameof(RealImplementations))] - public void SignHash_Roundtrip(ECDsa ecdsa) + [ConditionalFact] + public void SignHash_Roundtrip() { - byte[] hash = RandomNumberGenerator.GetBytes(32); - byte[] signature = SignHash(ecdsa, hash, 0, hash.Length); + using (ECDsa ecdsa = ECDsaFactory.Create()) + { + byte[] hash = RandomNumberGenerator.GetBytes(32); + byte[] signature = SignHash(ecdsa, hash, 0, hash.Length); - Assert.True(VerifyHash(ecdsa, hash, 0, hash.Length, signature), nameof(VerifyHash)); + Assert.True(VerifyHash(ecdsa, hash, 0, hash.Length, signature), nameof(VerifyHash)); + } } - [ConditionalTheory] - [MemberData(nameof(RealImplementations))] - public void SignHash_TamperedSignature(ECDsa ecdsa) + [ConditionalFact] + public void SignHash_TamperedSignature() { - byte[] hash = RandomNumberGenerator.GetBytes(32); - byte[] signature = SignHash(ecdsa, hash, 0, hash.Length); + using (ECDsa ecdsa = ECDsaFactory.Create()) + { + byte[] hash = RandomNumberGenerator.GetBytes(32); + byte[] signature = SignHash(ecdsa, hash, 0, hash.Length); - signature[0] ^= 0xFF; + signature[0] ^= 0xFF; - Assert.False(VerifyHash(ecdsa, hash, 0, hash.Length, signature), nameof(VerifyHash)); + Assert.False(VerifyHash(ecdsa, hash, 0, hash.Length, signature), nameof(VerifyHash)); + } } - [ConditionalTheory] - [MemberData(nameof(RealImplementations))] - public void SignHash_DifferentHashes(ECDsa ecdsa) + [ConditionalFact] + public void SignHash_DifferentHashes() { - byte[] hash = RandomNumberGenerator.GetBytes(32); - byte[] signature = SignHash(ecdsa, hash, 0, hash.Length); + using (ECDsa ecdsa = ECDsaFactory.Create()) + { + byte[] hash = RandomNumberGenerator.GetBytes(32); + byte[] signature = SignHash(ecdsa, hash, 0, hash.Length); - hash[0] ^= 0xFF; + hash[0] ^= 0xFF; - Assert.False(VerifyHash(ecdsa, hash, 0, hash.Length, signature), nameof(VerifyHash)); + Assert.False(VerifyHash(ecdsa, hash, 0, hash.Length, signature), nameof(VerifyHash)); + } } - [Theory] - [MemberData(nameof(RealImplementations))] - public void SignData_MaxOffset_ZeroLength_NoThrow(ECDsa ecdsa) + [Fact] + public void SignData_MaxOffset_ZeroLength_NoThrow() { - // Explicitly larger than Array.Empty - byte[] data = new byte[10]; - byte[] signature = SignData(ecdsa, data, data.Length, 0, HashAlgorithmName.SHA256); + using (ECDsa ecdsa = ECDsaFactory.Create()) + { + // Explicitly larger than Array.Empty + byte[] data = new byte[10]; + byte[] signature = SignData(ecdsa, data, data.Length, 0, HashAlgorithmName.SHA256); - Assert.True(VerifyData(ecdsa, Array.Empty(), signature, HashAlgorithmName.SHA256)); + Assert.True(VerifyData(ecdsa, Array.Empty(), signature, HashAlgorithmName.SHA256)); + } } - [Theory] - [MemberData(nameof(RealImplementations))] - public void VerifyData_MaxOffset_ZeroLength_NoThrow(ECDsa ecdsa) + [Fact] + public void VerifyData_MaxOffset_ZeroLength_NoThrow() { - // Explicitly larger than Array.Empty - byte[] data = new byte[10]; - byte[] signature = SignData(ecdsa, Array.Empty(), HashAlgorithmName.SHA256); + using (ECDsa ecdsa = ECDsaFactory.Create()) + { + // Explicitly larger than Array.Empty + byte[] data = new byte[10]; + byte[] signature = SignData(ecdsa, Array.Empty(), HashAlgorithmName.SHA256); - Assert.True(VerifyData(ecdsa, data, data.Length, 0, signature, HashAlgorithmName.SHA256)); + Assert.True(VerifyData(ecdsa, data, data.Length, 0, signature, HashAlgorithmName.SHA256)); + } } - [Theory] - [MemberData(nameof(RealImplementations))] - public void Roundtrip_WithOffset(ECDsa ecdsa) + [Fact] + public void Roundtrip_WithOffset() { - byte[] data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - byte[] halfData = { 5, 6, 7, 8, 9 }; + using (ECDsa ecdsa = ECDsaFactory.Create()) + { + byte[] data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + byte[] halfData = { 5, 6, 7, 8, 9 }; - byte[] dataSignature = SignData(ecdsa, data, 5, data.Length - 5, HashAlgorithmName.SHA256); - byte[] halfDataSignature = SignData(ecdsa, halfData, HashAlgorithmName.SHA256); + byte[] dataSignature = SignData(ecdsa, data, 5, data.Length - 5, HashAlgorithmName.SHA256); + byte[] halfDataSignature = SignData(ecdsa, halfData, HashAlgorithmName.SHA256); - // Cross-feed the VerifyData calls to prove that both offsets work - Assert.True(VerifyData(ecdsa, data, 5, data.Length - 5, halfDataSignature, HashAlgorithmName.SHA256)); - Assert.True(VerifyData(ecdsa, halfData, dataSignature, HashAlgorithmName.SHA256)); + // Cross-feed the VerifyData calls to prove that both offsets work + Assert.True(VerifyData(ecdsa, data, 5, data.Length - 5, halfDataSignature, HashAlgorithmName.SHA256)); + Assert.True(VerifyData(ecdsa, halfData, dataSignature, HashAlgorithmName.SHA256)); + } } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -328,67 +357,66 @@ public void CreateKey(int keySize) public static IEnumerable InteroperableSignatureConfigurations() { - foreach (HashAlgorithmName hashAlgorithm in new[] { - HashAlgorithmName.MD5, - HashAlgorithmName.SHA1, - HashAlgorithmName.SHA256, - HashAlgorithmName.SHA384, - HashAlgorithmName.SHA512 }) - { - yield return new object[] { ECDsaFactory.Create(), hashAlgorithm }; - } + yield return new object[] { HashAlgorithmName.MD5 }; + yield return new object[] { HashAlgorithmName.SHA1 }; + yield return new object[] { HashAlgorithmName.SHA256 }; + yield return new object[] { HashAlgorithmName.SHA384 }; + yield return new object[] { HashAlgorithmName.SHA512 }; } - + [Theory] [MemberData(nameof(InteroperableSignatureConfigurations))] - public void SignVerify_InteroperableSameKeys_RoundTripsUnlessTampered(ECDsa ecdsa, HashAlgorithmName hashAlgorithm) + public void SignVerify_InteroperableSameKeys_RoundTripsUnlessTampered(HashAlgorithmName hashAlgorithm) { - // large enough to make hashing work though multiple iterations and not a multiple of 4KB it uses. - byte[] dataArray = new byte[33333]; - - byte[] dataArray2 = new byte[dataArray.Length + 2]; - dataArray.CopyTo(dataArray2, 1); + using (ECDsa ecdsa = ECDsaFactory.Create()) + { + // large enough to make hashing work though multiple iterations and not a multiple of 4KB it uses. + byte[] dataArray = new byte[33333]; - using HashAlgorithm halg = - hashAlgorithm == HashAlgorithmName.MD5 ? MD5.Create() : - hashAlgorithm == HashAlgorithmName.SHA1 ? SHA1.Create() : - hashAlgorithm == HashAlgorithmName.SHA256 ? SHA256.Create() : - hashAlgorithm == HashAlgorithmName.SHA384 ? SHA384.Create() : - hashAlgorithm == HashAlgorithmName.SHA512 ? SHA512.Create() : - throw new Exception("Hash algorithm not supported."); + byte[] dataArray2 = new byte[dataArray.Length + 2]; + dataArray.CopyTo(dataArray2, 1); - List signatures = new List(6); + using HashAlgorithm halg = + hashAlgorithm == HashAlgorithmName.MD5 ? MD5.Create() : + hashAlgorithm == HashAlgorithmName.SHA1 ? SHA1.Create() : + hashAlgorithm == HashAlgorithmName.SHA256 ? SHA256.Create() : + hashAlgorithm == HashAlgorithmName.SHA384 ? SHA384.Create() : + hashAlgorithm == HashAlgorithmName.SHA512 ? SHA512.Create() : + throw new Exception("Hash algorithm not supported."); - // Compute a signature using each of the SignData overloads. Then, verify it using each - // of the VerifyData overloads, and VerifyHash overloads. - // - // Then, verify that VerifyHash fails if the data is tampered with. + List signatures = new List(6); - signatures.Add(SignData(ecdsa, dataArray, hashAlgorithm)); + // Compute a signature using each of the SignData overloads. Then, verify it using each + // of the VerifyData overloads, and VerifyHash overloads. + // + // Then, verify that VerifyHash fails if the data is tampered with. - signatures.Add(ecdsa.SignHash(halg.ComputeHash(dataArray))); + signatures.Add(SignData(ecdsa, dataArray, hashAlgorithm)); - foreach (byte[] signature in signatures) - { - Assert.True(VerifyData(ecdsa, dataArray, signature, hashAlgorithm), "Verify 1"); - Assert.True(ecdsa.VerifyHash(halg.ComputeHash(dataArray), signature), "Verify 4"); - } + signatures.Add(ecdsa.SignHash(halg.ComputeHash(dataArray))); - int distinctSignatures = signatures.Distinct(EqualityComparer.Create( - (x, y) => x.SequenceEqual(y), - x => + foreach (byte[] signature in signatures) { - HashCode hc = default; - hc.AddBytes(x); - return hc.ToHashCode(); - })).Count(); - Assert.True(distinctSignatures == signatures.Count, "Signing should be randomized"); - - foreach (byte[] signature in signatures) - { - signature[signature.Length - 1] ^= 0xFF; // flip some bits - Assert.False(VerifyData(ecdsa, dataArray, signature, hashAlgorithm), "Verify Tampered 1"); - Assert.False(ecdsa.VerifyHash(halg.ComputeHash(dataArray), signature), "Verify Tampered 4"); + Assert.True(VerifyData(ecdsa, dataArray, signature, hashAlgorithm), "Verify 1"); + Assert.True(ecdsa.VerifyHash(halg.ComputeHash(dataArray), signature), "Verify 4"); + } + + int distinctSignatures = signatures.Distinct(EqualityComparer.Create( + (x, y) => x.SequenceEqual(y), + x => + { + HashCode hc = default; + hc.AddBytes(x); + return hc.ToHashCode(); + })).Count(); + Assert.True(distinctSignatures == signatures.Count, "Signing should be randomized"); + + foreach (byte[] signature in signatures) + { + signature[signature.Length - 1] ^= 0xFF; // flip some bits + Assert.False(VerifyData(ecdsa, dataArray, signature, hashAlgorithm), "Verify Tampered 1"); + Assert.False(ecdsa.VerifyHash(halg.ComputeHash(dataArray), signature), "Verify Tampered 4"); + } } } } diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaTests.netcoreapp.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaTests.netcoreapp.cs index 6c53a870aae00e..1c3205de45067b 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaTests.netcoreapp.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaTests.netcoreapp.cs @@ -2,13 +2,14 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Security.Cryptography.Tests; +using Microsoft.DotNet.XUnitExtensions; using Xunit; namespace System.Security.Cryptography.EcDsa.Tests { [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] [ActiveIssue("https://github.com/dotnet/runtime/issues/62547", TestPlatforms.Android)] - public sealed class ECDsaTests_Span : ECDsaTests + public abstract class ECDsaTests_Span : ECDsaTests { protected override bool VerifyData(ECDsa ecdsa, byte[] data, int offset, int count, byte[] signature, HashAlgorithmName hashAlgorithm) => ecdsa.VerifyData(new ReadOnlySpan(data, offset, count), signature, hashAlgorithm); @@ -33,21 +34,23 @@ protected override void UseAfterDispose(ECDsa ecdsa, byte[] data, byte[] sig) Assert.Throws(() => ecdsa.SignHash(hash.AsSpan(), Span.Empty)); } - [Theory] - [MemberData(nameof(RealImplementations))] - public void SignData_InvalidArguments_Throws(ECDsa ecdsa) + [Fact] + public void SignData_InvalidArguments_Throws() { - Assert.Throws("hashAlgorithm", () => - ecdsa.SignData(ReadOnlySpan.Empty, Span.Empty, new HashAlgorithmName(null))); + using (ECDsa ecdsa = ECDsaFactory.Create()) + { + Assert.Throws("hashAlgorithm", () => + ecdsa.SignData(ReadOnlySpan.Empty, Span.Empty, new HashAlgorithmName(null))); - Assert.Throws("hashAlgorithm", () => - ecdsa.SignData(ReadOnlySpan.Empty, Span.Empty, new HashAlgorithmName(""))); + Assert.Throws("hashAlgorithm", () => + ecdsa.SignData(ReadOnlySpan.Empty, Span.Empty, new HashAlgorithmName(""))); - Assert.Throws("signatureFormat", - () => ecdsa.SignData(ReadOnlySpan.Empty, Span.Empty, HashAlgorithmName.SHA256, (DSASignatureFormat)42)); + Assert.Throws("signatureFormat", + () => ecdsa.SignData(ReadOnlySpan.Empty, Span.Empty, HashAlgorithmName.SHA256, (DSASignatureFormat)42)); - Assert.ThrowsAny(() => - ecdsa.SignData(ReadOnlySpan.Empty, Span.Empty, new HashAlgorithmName(Guid.NewGuid().ToString("N")))); + Assert.ThrowsAny(() => + ecdsa.SignData(ReadOnlySpan.Empty, Span.Empty, new HashAlgorithmName(Guid.NewGuid().ToString("N")))); + } } private static byte[] WithOutputArray(Func func) @@ -72,7 +75,7 @@ private static byte[] WithOutputArray(Func func) [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] [ActiveIssue("https://github.com/dotnet/runtime/issues/62547", TestPlatforms.Android)] - public sealed class ECDsaTests_AllocatingSpan : ECDsaTests + public abstract class ECDsaTests_AllocatingSpan : ECDsaTests { protected override bool VerifyData(ECDsa ecdsa, byte[] data, int offset, int count, byte[] signature, HashAlgorithmName hashAlgorithm) => ecdsa.VerifyData(new ReadOnlySpan(data, offset, count), signature, hashAlgorithm); @@ -96,20 +99,22 @@ protected override void UseAfterDispose(ECDsa ecdsa, byte[] data, byte[] sig) Assert.Throws(() => ecdsa.SignHash(hash.AsSpan())); } - [Theory] - [MemberData(nameof(RealImplementations))] - public void SignData_InvalidArguments_Throws(ECDsa ecdsa) + [Fact] + public void SignData_InvalidArguments_Throws() { - AssertExtensions.Throws("hashAlgorithm", () => ecdsa.SignData(ReadOnlySpan.Empty, new HashAlgorithmName(null))); - AssertExtensions.Throws("hashAlgorithm", () => ecdsa.SignData(ReadOnlySpan.Empty, new HashAlgorithmName(""))); - Assert.Throws("signatureFormat", () => ecdsa.SignData(ReadOnlySpan.Empty, HashAlgorithmName.SHA256, (DSASignatureFormat)42)); - Assert.ThrowsAny(() => ecdsa.SignData(ReadOnlySpan.Empty, new HashAlgorithmName(Guid.NewGuid().ToString("N")))); + using (ECDsa ecdsa = ECDsaFactory.Create()) + { + AssertExtensions.Throws("hashAlgorithm", () => ecdsa.SignData(ReadOnlySpan.Empty, new HashAlgorithmName(null))); + AssertExtensions.Throws("hashAlgorithm", () => ecdsa.SignData(ReadOnlySpan.Empty, new HashAlgorithmName(""))); + Assert.Throws("signatureFormat", () => ecdsa.SignData(ReadOnlySpan.Empty, HashAlgorithmName.SHA256, (DSASignatureFormat)42)); + Assert.ThrowsAny(() => ecdsa.SignData(ReadOnlySpan.Empty, new HashAlgorithmName(Guid.NewGuid().ToString("N")))); + } } } [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] [ActiveIssue("https://github.com/dotnet/runtime/issues/62547", TestPlatforms.Android)] - public sealed class ECDsaTests_TrySpan : ECDsaTests + public abstract class ECDsaTests_TrySpan : ECDsaTests { protected override bool VerifyData(ECDsa ecdsa, byte[] data, int offset, int count, byte[] signature, HashAlgorithmName hashAlgorithm) => ecdsa.VerifyData(new ReadOnlySpan(data, offset, count), signature, hashAlgorithm); @@ -132,20 +137,26 @@ protected override void UseAfterDispose(ECDsa ecdsa, byte[] data, byte[] sig) Assert.Throws(() => ecdsa.TrySignHash(hash, sig, out _)); } - [Theory, MemberData(nameof(RealImplementations))] - public void SignData_InvalidArguments_Throws(ECDsa ecdsa) + [Fact] + public void SignData_InvalidArguments_Throws() { - AssertExtensions.Throws("hashAlgorithm", () => ecdsa.TrySignData(ReadOnlySpan.Empty, Span.Empty, new HashAlgorithmName(null), out int bytesWritten)); - AssertExtensions.Throws("hashAlgorithm", () => ecdsa.TrySignData(ReadOnlySpan.Empty, Span.Empty, new HashAlgorithmName(""), out int bytesWritten)); - Assert.ThrowsAny(() => ecdsa.TrySignData(ReadOnlySpan.Empty, Span.Empty, new HashAlgorithmName(Guid.NewGuid().ToString("N")), out int bytesWritten)); + using (ECDsa ecdsa = ECDsaFactory.Create()) + { + AssertExtensions.Throws("hashAlgorithm", () => ecdsa.TrySignData(ReadOnlySpan.Empty, Span.Empty, new HashAlgorithmName(null), out int bytesWritten)); + AssertExtensions.Throws("hashAlgorithm", () => ecdsa.TrySignData(ReadOnlySpan.Empty, Span.Empty, new HashAlgorithmName(""), out int bytesWritten)); + Assert.ThrowsAny(() => ecdsa.TrySignData(ReadOnlySpan.Empty, Span.Empty, new HashAlgorithmName(Guid.NewGuid().ToString("N")), out int bytesWritten)); + } } - [Theory, MemberData(nameof(RealImplementations))] - public void VerifyData_InvalidArguments_Throws(ECDsa ecdsa) + [Fact] + public void VerifyData_InvalidArguments_Throws() { - AssertExtensions.Throws("hashAlgorithm", () => ecdsa.VerifyData(ReadOnlySpan.Empty, ReadOnlySpan.Empty, new HashAlgorithmName(null))); - AssertExtensions.Throws("hashAlgorithm", () => ecdsa.VerifyData(ReadOnlySpan.Empty, ReadOnlySpan.Empty, new HashAlgorithmName(""))); - Assert.ThrowsAny(() => ecdsa.VerifyData(ReadOnlySpan.Empty, Span.Empty, new HashAlgorithmName(Guid.NewGuid().ToString("N")))); + using (ECDsa ecdsa = ECDsaFactory.Create()) + { + AssertExtensions.Throws("hashAlgorithm", () => ecdsa.VerifyData(ReadOnlySpan.Empty, ReadOnlySpan.Empty, new HashAlgorithmName(null))); + AssertExtensions.Throws("hashAlgorithm", () => ecdsa.VerifyData(ReadOnlySpan.Empty, ReadOnlySpan.Empty, new HashAlgorithmName(""))); + Assert.ThrowsAny(() => ecdsa.VerifyData(ReadOnlySpan.Empty, Span.Empty, new HashAlgorithmName(Guid.NewGuid().ToString("N")))); + } } private static byte[] TryWithOutputArray(Func func) @@ -187,9 +198,12 @@ public void KeySizeProp() } } - [Theory, MemberData(nameof(TestNewCurves))] + [ConditionalTheory, MemberData(nameof(PublicTestCurves))] public void TestRegenKeyExplicit(CurveDef curveDef) { + SkipTestException.ThrowUnless(curveDef.IsCurveValidOnPlatform(ECDsaFactory)); + SkipTestException.ThrowWhen(curveDef.RequiredOnPlatform); + ECParameters param, param2; ECDsa ec, newEc; @@ -288,10 +302,12 @@ public void TestRegenKeyExplicit(CurveDef curveDef) } } - [Theory] - [MemberData(nameof(TestCurves))] + [ConditionalTheory] + [MemberData(nameof(PublicTestCurves))] public void TestRegenKeyNamed(CurveDef curveDef) { + SkipTestException.ThrowUnless(curveDef.IsCurveValidOnPlatform(ECDsaFactory)); + ECParameters param, param2; ECDsa ec; @@ -312,9 +328,11 @@ public void TestRegenKeyNamed(CurveDef curveDef) } } - [ConditionalFact(typeof(ECDsaTests), nameof(ECExplicitCurvesSupported))] + [ConditionalFact] public void TestRegenKeyNistP256() { + SkipTestException.ThrowUnless(ECExplicitCurvesSupported); + ECParameters param, param2; ECDsa ec; @@ -333,12 +351,12 @@ public void TestRegenKeyNistP256() } } - [Theory] - [MemberData(nameof(TestCurves))] + [ConditionalTheory] + [MemberData(nameof(PublicTestCurves))] public void TestChangeFromNamedCurveToKeySize(CurveDef curveDef) { - if (!curveDef.Curve.IsNamed) - return; + SkipTestException.ThrowUnless(curveDef.Curve.IsNamed); + SkipTestException.ThrowUnless(curveDef.IsCurveValidOnPlatform(ECDsaFactory)); using (ECDsa ec = ECDsaFactory.Create(curveDef.Curve)) { @@ -360,9 +378,10 @@ public void TestChangeFromNamedCurveToKeySize(CurveDef curveDef) } } - [ConditionalFact(typeof(ECDsaTests), nameof(ECExplicitCurvesSupported))] + [ConditionalFact] public void TestPositive256WithExplicitParameters() { + SkipTestException.ThrowUnless(ECExplicitCurvesSupported); using (ECDsa ecdsa = ECDsaFactory.Create()) { ecdsa.ImportParameters(EccTestData.GetNistP256ExplicitTestData()); @@ -393,10 +412,12 @@ public void PublicKey_CannotSign() } } - [Theory] - [MemberData(nameof(TestCurves))] + [ConditionalTheory] + [MemberData(nameof(PublicTestCurves))] public void SignaturesAtZeroDoNotVerify_IEEEP1363(CurveDef curveDef) { + SkipTestException.ThrowUnless(curveDef.IsCurveValidOnPlatform(ECDsaFactory)); + using (ECDsa ec = ECDsaFactory.Create(curveDef.Curve)) { byte[] data = new byte[] { 1, 2, 3, 4 }; @@ -423,10 +444,12 @@ public void SignaturesAtZeroDoNotVerify_IEEEP1363(CurveDef curveDef) } } - [Theory] - [MemberData(nameof(TestCurves))] + [ConditionalTheory] + [MemberData(nameof(PublicTestCurves))] public void SignaturesAtZeroDoNotVerify_DER(CurveDef curveDef) { + SkipTestException.ThrowUnless(curveDef.IsCurveValidOnPlatform(ECDsaFactory)); + using (ECDsa ec = ECDsaFactory.Create(curveDef.Curve)) { byte[] data = new byte[] { 1, 2, 3, 4 }; diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaTestsBase.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaTestsBase.cs index 9c2e3fc0b44abd..09ef73f5c6c8db 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaTestsBase.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaTestsBase.cs @@ -15,6 +15,8 @@ namespace System.Security.Cryptography.EcDsa.Tests [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] public abstract class ECDsaTestsBase : EccTestBase { + protected abstract ECDsaProvider ECDsaFactory { get; } + #if NET internal static void Verify256(ECDsa e, bool expected) { @@ -26,7 +28,7 @@ internal static void Verify256(ECDsa e, bool expected) // On CentOS, secp224r1 (also called nistP224) appears to be disabled. To prevent test failures on that platform, // probe for this capability before depending on it. - internal static bool ECDsa224Available + internal bool ECDsa224Available { get { @@ -34,7 +36,7 @@ internal static bool ECDsa224Available } } - internal static bool ECExplicitCurvesSupported + internal bool ECExplicitCurvesSupported { get { diff --git a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaXml.cs b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaXml.cs index 6ac3ed634e5683..8e12f55526c8dc 100644 --- a/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaXml.cs +++ b/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/ECDsa/ECDsaXml.cs @@ -6,10 +6,10 @@ namespace System.Security.Cryptography.EcDsa.Tests { [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] - public partial class ECDsaXml : ECDsaTestsBase + public abstract partial class ECDsaXml : ECDsaTestsBase { [Fact] - public static void TestNotImplementedException() + public void TestNotImplementedException() { using (ECDsa ec = ECDsaFactory.Create()) { diff --git a/src/libraries/Common/tests/System/Security/Cryptography/ExceptionHelpers.cs b/src/libraries/Common/tests/System/Security/Cryptography/ExceptionHelpers.cs new file mode 100644 index 00000000000000..11f8a73944d41b --- /dev/null +++ b/src/libraries/Common/tests/System/Security/Cryptography/ExceptionHelpers.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.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; +using Microsoft.DotNet.XUnitExtensions; + +namespace System.Security.Cryptography.Tests +{ + public static class ExceptionHelpers + { + extension (SkipTestException) + { + public static void ThrowWhen([DoesNotReturnIf(true)] bool condition, [CallerArgumentExpression(nameof(condition))] string? conditionText = null) + { + if (condition) + { + throw new SkipTestException($"Skipping because condition is true: {conditionText ?? ""}"); + } + } + + public static void ThrowUnless([DoesNotReturnIf(false)] bool condition, [CallerArgumentExpression(nameof(condition))] string? conditionText = null) + { + if (!condition) + { + throw new SkipTestException($"Skipping because condition is false: {conditionText ?? ""}"); + } + } + } + } +} diff --git a/src/libraries/System.Security.Cryptography.Cng/tests/OpenTests.cs b/src/libraries/System.Security.Cryptography.Cng/tests/OpenTests.cs index 2fabdee919033e..ad3355920ab649 100644 --- a/src/libraries/System.Security.Cryptography.Cng/tests/OpenTests.cs +++ b/src/libraries/System.Security.Cryptography.Cng/tests/OpenTests.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.Win32.SafeHandles; -using System.Security.Cryptography.EcDsa.Tests; using Xunit; namespace System.Security.Cryptography.Cng.Tests diff --git a/src/libraries/System.Security.Cryptography.Cng/tests/PropertyTests.cs b/src/libraries/System.Security.Cryptography.Cng/tests/PropertyTests.cs index fc2486ca0d092c..d5d28d4eecda17 100644 --- a/src/libraries/System.Security.Cryptography.Cng/tests/PropertyTests.cs +++ b/src/libraries/System.Security.Cryptography.Cng/tests/PropertyTests.cs @@ -1,7 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Security.Cryptography.EcDsa.Tests; using Test.Cryptography; using Xunit; diff --git a/src/libraries/System.Security.Cryptography.Cng/tests/System.Security.Cryptography.Cng.Tests.csproj b/src/libraries/System.Security.Cryptography.Cng/tests/System.Security.Cryptography.Cng.Tests.csproj index eb6e27daeea24c..eadc4248aeec39 100644 --- a/src/libraries/System.Security.Cryptography.Cng/tests/System.Security.Cryptography.Cng.Tests.csproj +++ b/src/libraries/System.Security.Cryptography.Cng/tests/System.Security.Cryptography.Cng.Tests.csproj @@ -9,12 +9,9 @@ - - - - - - + - - - - - - - - - - - @@ -99,26 +72,6 @@ Link="CommonTest\System\Security\Cryptography\AsymmetricSignatureFormatter.cs" /> - - - - - - - - - - - - - - - - - - - diff --git a/src/libraries/System.Security.Cryptography.OpenSsl/tests/EcDiffieHellmanOpenSslProvider.cs b/src/libraries/System.Security.Cryptography.OpenSsl/tests/EcDiffieHellmanOpenSslProvider.cs deleted file mode 100644 index 0a7390c5b250ec..00000000000000 --- a/src/libraries/System.Security.Cryptography.OpenSsl/tests/EcDiffieHellmanOpenSslProvider.cs +++ /dev/null @@ -1,38 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Security.Cryptography.EcDiffieHellman.Tests -{ - public partial class ECDiffieHellmanProvider : IECDiffieHellmanProvider - { - private EcDsa.Tests.ECDsaProvider _ecdsaProvider = new EcDsa.Tests.ECDsaProvider(); - - public ECDiffieHellman Create() - { - return new ECDiffieHellmanOpenSsl(); - } - - public ECDiffieHellman Create(int keySize) - { - return new ECDiffieHellmanOpenSsl(keySize); - } - - public ECDiffieHellman Create(ECCurve curve) - { - return new ECDiffieHellmanOpenSsl(curve); - } - - public bool IsCurveValid(Oid oid) => _ecdsaProvider.IsCurveValid(oid); - - public bool ExplicitCurvesSupported => _ecdsaProvider.ExplicitCurvesSupported; - - public bool CanDeriveNewPublicKey => true; - public bool SupportsRawDerivation => true; - public bool SupportsSha3 => PlatformDetection.SupportsSha3; - } - - public partial class ECDiffieHellmanFactory - { - private static readonly IECDiffieHellmanProvider s_provider = new ECDiffieHellmanProvider(); - } -} diff --git a/src/libraries/System.Security.Cryptography.OpenSsl/tests/System.Security.Cryptography.OpenSsl.Tests.csproj b/src/libraries/System.Security.Cryptography.OpenSsl/tests/System.Security.Cryptography.OpenSsl.Tests.csproj index 4dd2cd02e2dadc..c9c4f20f33186b 100644 --- a/src/libraries/System.Security.Cryptography.OpenSsl/tests/System.Security.Cryptography.OpenSsl.Tests.csproj +++ b/src/libraries/System.Security.Cryptography.OpenSsl/tests/System.Security.Cryptography.OpenSsl.Tests.csproj @@ -10,7 +10,6 @@ - @@ -24,48 +23,6 @@ Link="CommonTest\System\Security\Cryptography\SignatureSupport.cs" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true; + public override bool ExplicitCurvesSupported => true; - public bool CanDeriveNewPublicKey => false; + public override bool CanDeriveNewPublicKey => false; - public bool SupportsRawDerivation => true; + public override bool SupportsRawDerivation => true; - public bool SupportsSha3 => false; + public override bool SupportsSha3 => false; private static bool IsValueOrFriendlyNameValid(string friendlyNameOrValue) { diff --git a/src/libraries/System.Security.Cryptography/tests/DefaultECDiffieHellmanProvider.Browser.cs b/src/libraries/System.Security.Cryptography/tests/DefaultECDiffieHellmanProvider.Browser.cs index 310e5bb56a1988..7e2f9f391d2170 100644 --- a/src/libraries/System.Security.Cryptography/tests/DefaultECDiffieHellmanProvider.Browser.cs +++ b/src/libraries/System.Security.Cryptography/tests/DefaultECDiffieHellmanProvider.Browser.cs @@ -1,16 +1,14 @@ // 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; - namespace System.Security.Cryptography.EcDiffieHellman.Tests { - public partial class ECDiffieHellmanProvider : IECDiffieHellmanProvider + public partial class DefaultECDiffieHellmanProvider : ECDiffieHellmanProvider { - public bool IsCurveValid(Oid oid) => false; - public bool ExplicitCurvesSupported => false; - public bool CanDeriveNewPublicKey => false; - public bool SupportsRawDerivation => false; - public bool SupportsSha3 => false; + public override bool IsCurveValid(Oid oid) => false; + public override bool ExplicitCurvesSupported => false; + public override bool CanDeriveNewPublicKey => false; + public override bool SupportsRawDerivation => false; + public override bool SupportsSha3 => false; } } diff --git a/src/libraries/System.Security.Cryptography/tests/DefaultECDiffieHellmanProvider.Unix.cs b/src/libraries/System.Security.Cryptography/tests/DefaultECDiffieHellmanProvider.Unix.cs index c6fe568486c0bf..7a79ec911cf1b4 100644 --- a/src/libraries/System.Security.Cryptography/tests/DefaultECDiffieHellmanProvider.Unix.cs +++ b/src/libraries/System.Security.Cryptography/tests/DefaultECDiffieHellmanProvider.Unix.cs @@ -1,13 +1,11 @@ // 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; - namespace System.Security.Cryptography.EcDiffieHellman.Tests { - public partial class ECDiffieHellmanProvider : IECDiffieHellmanProvider + public partial class DefaultECDiffieHellmanProvider : ECDiffieHellmanProvider { - public bool IsCurveValid(Oid oid) + public override bool IsCurveValid(Oid oid) { if (PlatformDetection.IsApplePlatform) { @@ -21,7 +19,7 @@ public bool IsCurveValid(Oid oid) return IsValueOrFriendlyNameValid(oid.FriendlyName); } - public bool ExplicitCurvesSupported + public override bool ExplicitCurvesSupported { get { @@ -34,9 +32,9 @@ public bool ExplicitCurvesSupported } } - public bool CanDeriveNewPublicKey { get; } = !PlatformDetection.IsiOS && !PlatformDetection.IstvOS && !PlatformDetection.IsMacCatalyst; - public bool SupportsRawDerivation => true; - public bool SupportsSha3 => PlatformDetection.SupportsSha3; + public override bool CanDeriveNewPublicKey => !PlatformDetection.IsiOS && !PlatformDetection.IstvOS && !PlatformDetection.IsMacCatalyst; + public override bool SupportsRawDerivation => true; + public override bool SupportsSha3 => PlatformDetection.SupportsSha3; private static bool IsValueOrFriendlyNameValid(string friendlyNameOrValue) { diff --git a/src/libraries/System.Security.Cryptography/tests/DefaultECDiffieHellmanProvider.Windows.cs b/src/libraries/System.Security.Cryptography/tests/DefaultECDiffieHellmanProvider.Windows.cs index 71471a532acdb3..5b69a5e5ffc4a3 100644 --- a/src/libraries/System.Security.Cryptography/tests/DefaultECDiffieHellmanProvider.Windows.cs +++ b/src/libraries/System.Security.Cryptography/tests/DefaultECDiffieHellmanProvider.Windows.cs @@ -1,20 +1,17 @@ // 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; -using Test.Cryptography; - namespace System.Security.Cryptography.EcDiffieHellman.Tests { - public partial class ECDiffieHellmanProvider : IECDiffieHellmanProvider + public partial class DefaultECDiffieHellmanProvider : ECDiffieHellmanProvider { - public bool IsCurveValid(Oid oid) + public override bool IsCurveValid(Oid oid) { // Friendly name required for windows return NativeOidFriendlyNameExists(oid.FriendlyName); } - public bool ExplicitCurvesSupported + public override bool ExplicitCurvesSupported { get { @@ -22,9 +19,9 @@ public bool ExplicitCurvesSupported } } - public bool CanDeriveNewPublicKey => true; - public bool SupportsRawDerivation => PlatformDetection.IsWindows10OrLater; - public bool SupportsSha3 => PlatformDetection.SupportsSha3; + public override bool CanDeriveNewPublicKey => true; + public override bool SupportsRawDerivation => PlatformDetection.IsWindows10OrLater; + public override bool SupportsSha3 => PlatformDetection.SupportsSha3; private static bool NativeOidFriendlyNameExists(string oidFriendlyName) { diff --git a/src/libraries/System.Security.Cryptography/tests/DefaultECDiffieHellmanProvider.cs b/src/libraries/System.Security.Cryptography/tests/DefaultECDiffieHellmanProvider.cs index f823bf5e35a3fb..322a7ee1c4ba86 100644 --- a/src/libraries/System.Security.Cryptography/tests/DefaultECDiffieHellmanProvider.cs +++ b/src/libraries/System.Security.Cryptography/tests/DefaultECDiffieHellmanProvider.cs @@ -3,28 +3,27 @@ namespace System.Security.Cryptography.EcDiffieHellman.Tests { - public partial class ECDiffieHellmanProvider : IECDiffieHellmanProvider + public sealed partial class DefaultECDiffieHellmanProvider : ECDiffieHellmanProvider { - public ECDiffieHellman Create() + public static readonly DefaultECDiffieHellmanProvider Instance = new DefaultECDiffieHellmanProvider(); + + private DefaultECDiffieHellmanProvider() { } + + public override ECDiffieHellman Create() { return ECDiffieHellman.Create(); } - public ECDiffieHellman Create(int keySize) + public override ECDiffieHellman Create(int keySize) { ECDiffieHellman ec = Create(); ec.KeySize = keySize; return ec; } - public ECDiffieHellman Create(ECCurve curve) + public override ECDiffieHellman Create(ECCurve curve) { return ECDiffieHellman.Create(curve); } } - - public partial class ECDiffieHellmanFactory - { - private static readonly IECDiffieHellmanProvider s_provider = new ECDiffieHellmanProvider(); - } } diff --git a/src/libraries/System.Security.Cryptography/tests/ECDiffieHellmanTests.cs b/src/libraries/System.Security.Cryptography/tests/DefaultECDiffieHellmanTests.cs similarity index 72% rename from src/libraries/System.Security.Cryptography/tests/ECDiffieHellmanTests.cs rename to src/libraries/System.Security.Cryptography/tests/DefaultECDiffieHellmanTests.cs index 809930bc68d89e..43feab3173bb47 100644 --- a/src/libraries/System.Security.Cryptography/tests/ECDiffieHellmanTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/DefaultECDiffieHellmanTests.cs @@ -7,24 +7,24 @@ namespace System.Security.Cryptography.Tests { [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] - public partial class ECDiffieHellmanTests + public sealed class DefaultECDiffieHellmanTests { [Fact] - public static void ECCurve_ctor() + public void ECCurve_ctor() { - using (ECDiffieHellman ecdh = ECDiffieHellmanFactory.Create(ECCurve.NamedCurves.nistP256)) + using (ECDiffieHellman ecdh = ECDiffieHellman.Create(ECCurve.NamedCurves.nistP256)) { Assert.Equal(256, ecdh.KeySize); ecdh.Exercise(); } - using (ECDiffieHellman ecdh = ECDiffieHellmanFactory.Create(ECCurve.NamedCurves.nistP384)) + using (ECDiffieHellman ecdh = ECDiffieHellman.Create(ECCurve.NamedCurves.nistP384)) { Assert.Equal(384, ecdh.KeySize); ecdh.Exercise(); } - using (ECDiffieHellman ecdh = ECDiffieHellmanFactory.Create(ECCurve.NamedCurves.nistP521)) + using (ECDiffieHellman ecdh = ECDiffieHellman.Create(ECCurve.NamedCurves.nistP521)) { Assert.Equal(521, ecdh.KeySize); ecdh.Exercise(); @@ -35,10 +35,10 @@ public static void ECCurve_ctor() [InlineData("1.3.132.0.35", 521)] //secp521r1 [InlineData("1.3.132.0.34", 384)] //secp384r1 [InlineData("1.2.840.10045.3.1.7", 256)] //secp256v1 - public static void ECCurve_ctor_SEC2_OID_From_Value(string oidValue, int expectedKeySize) + public void ECCurve_ctor_SEC2_OID_From_Value(string oidValue, int expectedKeySize) { ECCurve ecCurve = ECCurve.CreateFromValue(oidValue); - using (ECDiffieHellman ecdh = ECDiffieHellmanFactory.Create(ecCurve)) + using (ECDiffieHellman ecdh = ECDiffieHellman.Create(ecCurve)) { Assert.Equal(expectedKeySize, ecdh.KeySize); ecdh.Exercise(); @@ -54,9 +54,9 @@ public void Create_InvalidECCurveFriendlyName_ThrowsPlatformNotSupportedExceptio } [Fact] - public static void Equivalence_Hash() + public void Equivalence_Hash() { - using (ECDiffieHellman ecdh = ECDiffieHellmanFactory.Create()) + using (ECDiffieHellman ecdh = ECDiffieHellman.Create()) using (ECDiffieHellmanPublicKey publicKey = ecdh.PublicKey) { byte[] newWay = ecdh.DeriveKeyFromHash(publicKey, HashAlgorithmName.SHA256, null, null); diff --git a/src/libraries/System.Security.Cryptography/tests/DefaultECDsaProvider.Android.cs b/src/libraries/System.Security.Cryptography/tests/DefaultECDsaProvider.Android.cs index 17e0574ceee9b5..cf3ba23d51a39d 100644 --- a/src/libraries/System.Security.Cryptography/tests/DefaultECDsaProvider.Android.cs +++ b/src/libraries/System.Security.Cryptography/tests/DefaultECDsaProvider.Android.cs @@ -5,9 +5,9 @@ namespace System.Security.Cryptography.EcDsa.Tests { - public partial class ECDsaProvider : IECDsaProvider + public partial class DefaultECDsaProvider : ECDsaProvider { - public bool IsCurveValid(Oid oid) + public override bool IsCurveValid(Oid oid) { if (!string.IsNullOrEmpty(oid.Value)) { @@ -17,7 +17,7 @@ public bool IsCurveValid(Oid oid) return IsValueOrFriendlyNameValid(oid.FriendlyName); } - public bool ExplicitCurvesSupported + public override bool ExplicitCurvesSupported { get { diff --git a/src/libraries/System.Security.Cryptography/tests/DefaultECDsaProvider.Browser.cs b/src/libraries/System.Security.Cryptography/tests/DefaultECDsaProvider.Browser.cs index 4278df1bd01071..7c66854bb9a7a7 100644 --- a/src/libraries/System.Security.Cryptography/tests/DefaultECDsaProvider.Browser.cs +++ b/src/libraries/System.Security.Cryptography/tests/DefaultECDsaProvider.Browser.cs @@ -1,14 +1,11 @@ // 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; - namespace System.Security.Cryptography.EcDsa.Tests { - public partial class ECDsaProvider : IECDsaProvider + public partial class DefaultECDsaProvider : ECDsaProvider { - public bool IsCurveValid(Oid oid) => false; - public bool ExplicitCurvesSupported => false; - private static bool IsValueOrFriendlyNameValid(string friendlyNameOrValue) => false; + public override bool IsCurveValid(Oid oid) => false; + public override bool ExplicitCurvesSupported => false; } } diff --git a/src/libraries/System.Security.Cryptography/tests/DefaultECDsaProvider.Unix.cs b/src/libraries/System.Security.Cryptography/tests/DefaultECDsaProvider.Unix.cs index 11ea1c6d2d84fc..908e54ccd47563 100644 --- a/src/libraries/System.Security.Cryptography/tests/DefaultECDsaProvider.Unix.cs +++ b/src/libraries/System.Security.Cryptography/tests/DefaultECDsaProvider.Unix.cs @@ -5,9 +5,9 @@ namespace System.Security.Cryptography.EcDsa.Tests { - public partial class ECDsaProvider : IECDsaProvider + public partial class DefaultECDsaProvider : ECDsaProvider { - public bool IsCurveValid(Oid oid) + public override bool IsCurveValid(Oid oid) { if (PlatformDetection.IsApplePlatform) { @@ -21,7 +21,7 @@ public bool IsCurveValid(Oid oid) return IsValueOrFriendlyNameValid(oid.FriendlyName); } - public bool ExplicitCurvesSupported + public override bool ExplicitCurvesSupported { get { diff --git a/src/libraries/System.Security.Cryptography/tests/DefaultECDsaProvider.Windows.cs b/src/libraries/System.Security.Cryptography/tests/DefaultECDsaProvider.Windows.cs index 32e5422d0f7d9e..a8a0bd93147403 100644 --- a/src/libraries/System.Security.Cryptography/tests/DefaultECDsaProvider.Windows.cs +++ b/src/libraries/System.Security.Cryptography/tests/DefaultECDsaProvider.Windows.cs @@ -1,19 +1,17 @@ // 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; - namespace System.Security.Cryptography.EcDsa.Tests { - public partial class ECDsaProvider : IECDsaProvider + public partial class DefaultECDsaProvider : ECDsaProvider { - public bool IsCurveValid(Oid oid) + public override bool IsCurveValid(Oid oid) { // Friendly name required for windows return NativeOidFriendlyNameExists(oid.FriendlyName); } - public bool ExplicitCurvesSupported + public override bool ExplicitCurvesSupported { get { diff --git a/src/libraries/System.Security.Cryptography/tests/DefaultECDsaProvider.cs b/src/libraries/System.Security.Cryptography/tests/DefaultECDsaProvider.cs index 91015c49a39f4e..e3e1d5bb3f6069 100644 --- a/src/libraries/System.Security.Cryptography/tests/DefaultECDsaProvider.cs +++ b/src/libraries/System.Security.Cryptography/tests/DefaultECDsaProvider.cs @@ -1,35 +1,29 @@ // 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; - namespace System.Security.Cryptography.EcDsa.Tests { - public partial class ECDsaProvider : IECDsaProvider + public partial class DefaultECDsaProvider : ECDsaProvider { - public ECDsa Create() + public static readonly DefaultECDsaProvider Instance = new DefaultECDsaProvider(); + + private DefaultECDsaProvider() { } + + public override ECDsa Create() { return ECDsa.Create(); } - public ECDsa Create(int keySize) + public override ECDsa Create(int keySize) { ECDsa ec = Create(); ec.KeySize = keySize; return ec; } -#if NET - public ECDsa Create(ECCurve curve) + public override ECDsa Create(ECCurve curve) { return ECDsa.Create(curve); } -#endif } - - public partial class ECDsaFactory - { - private static readonly IECDsaProvider s_provider = new ECDsaProvider(); - } - } diff --git a/src/libraries/System.Security.Cryptography/tests/ECDsaTests.cs b/src/libraries/System.Security.Cryptography/tests/DefaultECDsaTests.cs similarity index 95% rename from src/libraries/System.Security.Cryptography/tests/ECDsaTests.cs rename to src/libraries/System.Security.Cryptography/tests/DefaultECDsaTests.cs index c858fd0866213d..552de9e3988c22 100644 --- a/src/libraries/System.Security.Cryptography/tests/ECDsaTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/DefaultECDsaTests.cs @@ -3,13 +3,12 @@ using System.IO; using System.Reflection; -using System.Security.Cryptography.EcDsa.Tests; using Xunit; namespace System.Security.Cryptography.Tests { [SkipOnPlatform(TestPlatforms.Browser, "Not supported on Browser")] - public class ECDsaTests + public sealed class DefaultECDsaTests { [Fact] public void Create_InvalidArgument_Throws() @@ -31,7 +30,7 @@ public void Create_InvalidECCurveFriendlyName_ThrowsPlatformNotSupportedExceptio [Fact] public void NotSupportedBaseMethods_Throw() { - using (var ecdsa = new OverrideAbstractECDsa(ECDsaFactory.Create())) + using (var ecdsa = new OverrideAbstractECDsa(ECDsa.Create())) { Assert.Throws(() => ecdsa.ExportParameters(false)); Assert.Throws(() => ecdsa.ExportExplicitParameters(false)); @@ -46,7 +45,7 @@ public void NotSupportedBaseMethods_Throw() [Fact] public void BaseProperties_ExpectedValues() { - using (var ecdsa = new OverrideAbstractECDsa(ECDsaFactory.Create())) + using (var ecdsa = new OverrideAbstractECDsa(ECDsa.Create())) { Assert.Null(ecdsa.KeyExchangeAlgorithm); Assert.Equal("ECDsa", ecdsa.SignatureAlgorithm); @@ -56,7 +55,7 @@ public void BaseProperties_ExpectedValues() [Fact] public void Array_SignData_VerifyData_UsesHashDataAndSignHashAndVerifyHash() { - using (var ecdsa = new OverrideAbstractECDsa(ECDsaFactory.Create())) + using (var ecdsa = new OverrideAbstractECDsa(ECDsa.Create())) { AssertExtensions.Throws("data", () => ecdsa.SignData((byte[])null, HashAlgorithmName.SHA1)); AssertExtensions.Throws("data", () => ecdsa.SignData(null, 0, 0, HashAlgorithmName.SHA1)); @@ -92,7 +91,7 @@ public void Array_SignData_VerifyData_UsesHashDataAndSignHashAndVerifyHash() [Fact] public void Stream_SignData_VerifyData_UsesHashDataAndSignHashAndVerifyHash() { - using (var ecdsa = new OverrideAbstractECDsa(ECDsaFactory.Create())) + using (var ecdsa = new OverrideAbstractECDsa(ECDsa.Create())) { AssertExtensions.Throws("data", () => ecdsa.SignData((Stream)null, HashAlgorithmName.SHA1)); AssertExtensions.Throws("hashAlgorithm", () => ecdsa.SignData(new MemoryStream(new byte[1]), new HashAlgorithmName(null))); @@ -118,7 +117,7 @@ public void Stream_SignData_VerifyData_UsesHashDataAndSignHashAndVerifyHash() [Fact] public void Span_TrySignData_VerifyData_UsesTryHashDataAndTrySignHashAndTryVerifyHash() { - using (var ecdsa = new OverrideAbstractECDsa(ECDsaFactory.Create())) + using (var ecdsa = new OverrideAbstractECDsa(ECDsa.Create())) { AssertExtensions.Throws("hashAlgorithm", () => ecdsa.TrySignData(new byte[1], new byte[1], new HashAlgorithmName(null), out int bytesWritten)); AssertExtensions.Throws("hashAlgorithm", () => ecdsa.TrySignData(new byte[1], new byte[1], new HashAlgorithmName(""), out int bytesWritten)); diff --git a/src/libraries/System.Security.Cryptography.Cng/tests/ECDiffieHellmanCngProvider.cs b/src/libraries/System.Security.Cryptography/tests/ECDiffieHellmanCngProvider.cs similarity index 65% rename from src/libraries/System.Security.Cryptography.Cng/tests/ECDiffieHellmanCngProvider.cs rename to src/libraries/System.Security.Cryptography/tests/ECDiffieHellmanCngProvider.cs index 1dc38e42bccce8..3aaaa18685c467 100644 --- a/src/libraries/System.Security.Cryptography.Cng/tests/ECDiffieHellmanCngProvider.cs +++ b/src/libraries/System.Security.Cryptography/tests/ECDiffieHellmanCngProvider.cs @@ -3,30 +3,34 @@ namespace System.Security.Cryptography.EcDiffieHellman.Tests { - public class ECDiffieHellmanProvider : IECDiffieHellmanProvider + public sealed class ECDiffieHellmanCngProvider : ECDiffieHellmanProvider { - public ECDiffieHellman Create() + public static readonly ECDiffieHellmanCngProvider Instance = new ECDiffieHellmanCngProvider(); + + private ECDiffieHellmanCngProvider() { } + + public override ECDiffieHellman Create() { return new ECDiffieHellmanCng(); } - public ECDiffieHellman Create(int keySize) + public override ECDiffieHellman Create(int keySize) { return new ECDiffieHellmanCng(keySize); } - public ECDiffieHellman Create(ECCurve curve) + public override ECDiffieHellman Create(ECCurve curve) { return new ECDiffieHellmanCng(curve); } - public bool IsCurveValid(Oid oid) + public override bool IsCurveValid(Oid oid) { // Friendly name required for windows return NativeOidFriendlyNameExists(oid.FriendlyName); } - public bool ExplicitCurvesSupported + public override bool ExplicitCurvesSupported { get { @@ -34,9 +38,9 @@ public bool ExplicitCurvesSupported } } - public bool CanDeriveNewPublicKey => true; - public bool SupportsRawDerivation => PlatformDetection.IsWindows10OrLater; - public bool SupportsSha3 => PlatformDetection.SupportsSha3; + public override bool CanDeriveNewPublicKey => true; + public override bool SupportsRawDerivation => PlatformDetection.IsWindows10OrLater; + public override bool SupportsSha3 => PlatformDetection.SupportsSha3; private static bool NativeOidFriendlyNameExists(string oidFriendlyName) { @@ -57,8 +61,4 @@ private static bool NativeOidFriendlyNameExists(string oidFriendlyName) } } - public partial class ECDiffieHellmanFactory - { - private static readonly IECDiffieHellmanProvider s_provider = new ECDiffieHellmanProvider(); - } } diff --git a/src/libraries/System.Security.Cryptography.Cng/tests/ECDiffieHellmanCngTests.cs b/src/libraries/System.Security.Cryptography/tests/ECDiffieHellmanCngTests.cs similarity index 99% rename from src/libraries/System.Security.Cryptography.Cng/tests/ECDiffieHellmanCngTests.cs rename to src/libraries/System.Security.Cryptography/tests/ECDiffieHellmanCngTests.cs index 3ca8e6d9912ddf..db91cf1748c8b9 100644 --- a/src/libraries/System.Security.Cryptography.Cng/tests/ECDiffieHellmanCngTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/ECDiffieHellmanCngTests.cs @@ -7,7 +7,7 @@ namespace System.Security.Cryptography.EcDiffieHellman.Tests { - public partial class ECDiffieHellmanTests + public static class ECDiffieHellmanCngTests { private static ECDiffieHellmanCng NewDefaultECDHCng() { diff --git a/src/libraries/System.Security.Cryptography/tests/ECDiffieHellmanTestRegistration.Cng.cs b/src/libraries/System.Security.Cryptography/tests/ECDiffieHellmanTestRegistration.Cng.cs new file mode 100644 index 00000000000000..428c0525ed3d84 --- /dev/null +++ b/src/libraries/System.Security.Cryptography/tests/ECDiffieHellmanTestRegistration.Cng.cs @@ -0,0 +1,25 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Security.Cryptography.EcDiffieHellman.Tests +{ + public sealed class ECDiffieHellmanTests_Cng : ECDiffieHellmanTests + { + protected override ECDiffieHellmanProvider ECDiffieHellmanFactory { get; } = ECDiffieHellmanCngProvider.Instance; + } + + public sealed class ECDiffieHellmanFactoryTests_Cng : ECDiffieHellmanFactoryTests + { + protected override ECDiffieHellmanProvider ECDiffieHellmanFactory { get; } = ECDiffieHellmanCngProvider.Instance; + } + + public sealed class ECDhKeyFileTests_Cng : ECDhKeyFileTests + { + protected override ECDiffieHellmanProvider ECDiffieHellmanFactory { get; } = ECDiffieHellmanCngProvider.Instance; + } + + public sealed class ECDiffieHellmanKeyPemTests_Cng : ECDiffieHellmanKeyPemTests + { + protected override ECDiffieHellmanProvider ECDiffieHellmanFactory { get; } = ECDiffieHellmanCngProvider.Instance; + } +} diff --git a/src/libraries/System.Security.Cryptography/tests/ECDiffieHellmanTestRegistration.Default.cs b/src/libraries/System.Security.Cryptography/tests/ECDiffieHellmanTestRegistration.Default.cs new file mode 100644 index 00000000000000..d057025cd29470 --- /dev/null +++ b/src/libraries/System.Security.Cryptography/tests/ECDiffieHellmanTestRegistration.Default.cs @@ -0,0 +1,25 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Security.Cryptography.EcDiffieHellman.Tests +{ + public sealed class ECDiffieHellmanTests_Default : ECDiffieHellmanTests + { + protected override ECDiffieHellmanProvider ECDiffieHellmanFactory { get; } = DefaultECDiffieHellmanProvider.Instance; + } + + public sealed class ECDiffieHellmanFactoryTests_Default : ECDiffieHellmanFactoryTests + { + protected override ECDiffieHellmanProvider ECDiffieHellmanFactory { get; } = DefaultECDiffieHellmanProvider.Instance; + } + + public sealed class ECDhKeyFileTests_Default : ECDhKeyFileTests + { + protected override ECDiffieHellmanProvider ECDiffieHellmanFactory { get; } = DefaultECDiffieHellmanProvider.Instance; + } + + public sealed class ECDiffieHellmanKeyPemTests_Default : ECDiffieHellmanKeyPemTests + { + protected override ECDiffieHellmanProvider ECDiffieHellmanFactory { get; } = DefaultECDiffieHellmanProvider.Instance; + } +} diff --git a/src/libraries/System.Security.Cryptography/tests/ECDiffieHellmanTestRegistration.OpenSsl.cs b/src/libraries/System.Security.Cryptography/tests/ECDiffieHellmanTestRegistration.OpenSsl.cs new file mode 100644 index 00000000000000..7e87f7538cd989 --- /dev/null +++ b/src/libraries/System.Security.Cryptography/tests/ECDiffieHellmanTestRegistration.OpenSsl.cs @@ -0,0 +1,25 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Security.Cryptography.EcDiffieHellman.Tests +{ + public sealed class ECDiffieHellmanTests_OpenSsl : ECDiffieHellmanTests + { + protected override ECDiffieHellmanProvider ECDiffieHellmanFactory { get; } = ECDiffieHellmanOpenSslProvider.Instance; + } + + public sealed class ECDiffieHellmanFactoryTests_OpenSsl : ECDiffieHellmanFactoryTests + { + protected override ECDiffieHellmanProvider ECDiffieHellmanFactory { get; } = ECDiffieHellmanOpenSslProvider.Instance; + } + + public sealed class ECDhKeyFileTests_OpenSsl : ECDhKeyFileTests + { + protected override ECDiffieHellmanProvider ECDiffieHellmanFactory { get; } = ECDiffieHellmanOpenSslProvider.Instance; + } + + public sealed class ECDiffieHellmanKeyPemTests_OpenSsl : ECDiffieHellmanKeyPemTests + { + protected override ECDiffieHellmanProvider ECDiffieHellmanFactory { get; } = ECDiffieHellmanOpenSslProvider.Instance; + } +} diff --git a/src/libraries/System.Security.Cryptography.Cng/tests/ECDsaCngImportExportTests.cs b/src/libraries/System.Security.Cryptography/tests/ECDsaCngImportExportTests.cs similarity index 86% rename from src/libraries/System.Security.Cryptography.Cng/tests/ECDsaCngImportExportTests.cs rename to src/libraries/System.Security.Cryptography/tests/ECDsaCngImportExportTests.cs index 790b76868dbce7..b8309fb0c61f04 100644 --- a/src/libraries/System.Security.Cryptography.Cng/tests/ECDsaCngImportExportTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/ECDsaCngImportExportTests.cs @@ -1,14 +1,17 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using Xunit; +using Microsoft.DotNet.XUnitExtensions; using System.Security.Cryptography.EcDsa.Tests; using System.Security.Cryptography.Tests; +using Xunit; namespace System.Security.Cryptography.Cng.Tests { - public class ECDsaCngImportExportTests : ECDsaTestsBase + public sealed class ECDsaCngImportExportTests : ECDsaTestsBase { + protected override ECDsaProvider ECDsaFactory { get; } = ECDsaCngProvider.Instance; + [Fact] public static void TestImportKey() { @@ -46,9 +49,12 @@ public static void TestImportExportRoundTrip() } } - [ConditionalTheory(typeof(ECDsaCngImportExportTests), nameof(ECExplicitCurvesSupported)), MemberData(nameof(TestCurves))] + [ConditionalTheory, MemberData(nameof(PublicTestCurves))] public static void TestHashRoundTrip(CurveDef curveDef) { + SkipTestException.ThrowUnless(ECDsaCngProvider.Instance.ExplicitCurvesSupported); + SkipTestException.ThrowUnless(curveDef.IsCurveValidOnPlatform(ECDsaCngProvider.Instance)); + // This test is in the cng only tests because OpenSsl does not provide the hash algorithm using (var cng = new ECDsaCng(curveDef.Curve)) { diff --git a/src/libraries/System.Security.Cryptography.Cng/tests/ECDsaCngProvider.cs b/src/libraries/System.Security.Cryptography/tests/ECDsaCngProvider.cs similarity index 76% rename from src/libraries/System.Security.Cryptography.Cng/tests/ECDsaCngProvider.cs rename to src/libraries/System.Security.Cryptography/tests/ECDsaCngProvider.cs index b6d68a288a4a4a..fefb799f1132f4 100644 --- a/src/libraries/System.Security.Cryptography.Cng/tests/ECDsaCngProvider.cs +++ b/src/libraries/System.Security.Cryptography/tests/ECDsaCngProvider.cs @@ -3,30 +3,34 @@ namespace System.Security.Cryptography.EcDsa.Tests { - public class ECDsaProvider : IECDsaProvider + public class ECDsaCngProvider : ECDsaProvider { - public ECDsa Create() + public static readonly ECDsaCngProvider Instance = new ECDsaCngProvider(); + + private ECDsaCngProvider() { } + + public override ECDsa Create() { return new ECDsaCng(); } - public ECDsa Create(int keySize) + public override ECDsa Create(int keySize) { return new ECDsaCng(keySize); } - public ECDsa Create(ECCurve curve) + public override ECDsa Create(ECCurve curve) { return new ECDsaCng(curve); } - public bool IsCurveValid(Oid oid) + public override bool IsCurveValid(Oid oid) { // Friendly name required for windows return NativeOidFriendlyNameExists(oid.FriendlyName); } - public bool ExplicitCurvesSupported + public override bool ExplicitCurvesSupported { get { @@ -52,9 +56,4 @@ private static bool NativeOidFriendlyNameExists(string oidFriendlyName) } } } - - public partial class ECDsaFactory - { - private static readonly IECDsaProvider s_provider = new ECDsaProvider(); - } } diff --git a/src/libraries/System.Security.Cryptography.Cng/tests/ECDsaCngTests.cs b/src/libraries/System.Security.Cryptography/tests/ECDsaCngTests.cs similarity index 95% rename from src/libraries/System.Security.Cryptography.Cng/tests/ECDsaCngTests.cs rename to src/libraries/System.Security.Cryptography/tests/ECDsaCngTests.cs index c7ff78e8d02bd5..8266e080bc1a3b 100644 --- a/src/libraries/System.Security.Cryptography.Cng/tests/ECDsaCngTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/ECDsaCngTests.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Security.Cryptography.EcDsa.Tests; using System.Security.Cryptography.Tests; +using Microsoft.DotNet.XUnitExtensions; using Test.Cryptography; using Xunit; @@ -11,6 +12,8 @@ namespace System.Security.Cryptography.Cng.Tests { public class ECDsaCngTests : ECDsaTestsBase { + protected override ECDsaProvider ECDsaFactory { get; } = ECDsaCngProvider.Instance; + [Fact] public static void TestNegativeVerify256() { @@ -164,9 +167,11 @@ public static void TestPositive256WithBlob() Verify256(e, true); } - [Theory, MemberData(nameof(TestCurves))] + [ConditionalTheory, MemberData(nameof(PublicTestCurves))] public static void TestKeyPropertyFromNamedCurve(CurveDef curveDef) { + SkipTestException.ThrowUnless(curveDef.IsCurveValidOnPlatform(ECDsaCngProvider.Instance)); + ECDsaCng e = new ECDsaCng(curveDef.Curve); CngKey key1 = e.Key; VerifyKey(key1); @@ -200,7 +205,7 @@ public static void TestCreateKeyFromCngAlgorithmNegative() } [Theory, MemberData(nameof(SpecialNistKeys))] - public static void TestSpecialNistKeys(int keySize, string curveName, CngAlgorithm algorithm) + public void TestSpecialNistKeys(int keySize, string curveName, CngAlgorithm algorithm) { using (ECDsaCng cng = (ECDsaCng)ECDsaFactory.Create(keySize)) { diff --git a/src/libraries/System.Security.Cryptography/tests/ECDsaTestRegistration.Cng.cs b/src/libraries/System.Security.Cryptography/tests/ECDsaTestRegistration.Cng.cs new file mode 100644 index 00000000000000..9b57d734dc9ecf --- /dev/null +++ b/src/libraries/System.Security.Cryptography/tests/ECDsaTestRegistration.Cng.cs @@ -0,0 +1,67 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Security.Cryptography.EcDsa.Tests +{ + public sealed class ECDsaTests_Array_Cng : ECDsaTests_Array + { + protected override ECDsaProvider ECDsaFactory { get; } = ECDsaCngProvider.Instance; + } + + public sealed class ECDsaTests_Stream_Cng : ECDsaTests_Stream + { + protected override ECDsaProvider ECDsaFactory { get; } = ECDsaCngProvider.Instance; + } + + public sealed class ECDsaTests_Span_Cng : ECDsaTests_Span + { + protected override ECDsaProvider ECDsaFactory { get; } = ECDsaCngProvider.Instance; + } + + public sealed class ECDsaTests_AllocatingSpan_Cng : ECDsaTests_AllocatingSpan + { + protected override ECDsaProvider ECDsaFactory { get; } = ECDsaCngProvider.Instance; + } + + public sealed class ECDsaTests_TrySpan_Cng : ECDsaTests_TrySpan + { + protected override ECDsaProvider ECDsaFactory { get; } = ECDsaCngProvider.Instance; + } + + public sealed class ECDsaFactoryTests_Cng : ECDsaFactoryTests + { + protected override ECDsaProvider ECDsaFactory { get; } = ECDsaCngProvider.Instance; + } + + public sealed class ECDsaImportExportTests_Cng : ECDsaImportExportTests + { + protected override ECDsaProvider ECDsaFactory { get; } = ECDsaCngProvider.Instance; + protected override bool CanDeriveNewPublicKey { get; } = EcDiffieHellman.Tests.ECDiffieHellmanCngProvider.Instance.CanDeriveNewPublicKey; + } + + public sealed class ECDsaKeyFileTests_Cng : ECDsaKeyFileTests + { + protected override ECDsaProvider ECDsaFactory { get; } = ECDsaCngProvider.Instance; + protected override bool CanDeriveNewPublicKey { get; } = EcDiffieHellman.Tests.ECDiffieHellmanCngProvider.Instance.CanDeriveNewPublicKey; + } + + public sealed class ECDsaXml_Cng : ECDsaXml + { + protected override ECDsaProvider ECDsaFactory { get; } = ECDsaCngProvider.Instance; + } + + public sealed class ECDsaArraySignatureFormatTests_Cng : ECDsaArraySignatureFormatTests + { + protected override ECDsaProvider ECDsaFactory { get; } = ECDsaCngProvider.Instance; + } + + public sealed class ECDsaArrayOffsetSignatureFormatTests_Cng : ECDsaArrayOffsetSignatureFormatTests + { + protected override ECDsaProvider ECDsaFactory { get; } = ECDsaCngProvider.Instance; + } + + public sealed class ECDsaSpanSignatureFormatTests_Cng : ECDsaSpanSignatureFormatTests + { + protected override ECDsaProvider ECDsaFactory { get; } = ECDsaCngProvider.Instance; + } +} diff --git a/src/libraries/System.Security.Cryptography/tests/ECDsaTestRegistration.Default.cs b/src/libraries/System.Security.Cryptography/tests/ECDsaTestRegistration.Default.cs new file mode 100644 index 00000000000000..d9f5980e9ed516 --- /dev/null +++ b/src/libraries/System.Security.Cryptography/tests/ECDsaTestRegistration.Default.cs @@ -0,0 +1,67 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Security.Cryptography.EcDsa.Tests +{ + public sealed class ECDsaTests_Array_Default : ECDsaTests_Array + { + protected override ECDsaProvider ECDsaFactory { get; } = DefaultECDsaProvider.Instance; + } + + public sealed class ECDsaTests_Stream_Default : ECDsaTests_Stream + { + protected override ECDsaProvider ECDsaFactory { get; } = DefaultECDsaProvider.Instance; + } + + public sealed class ECDsaTests_Span_Default : ECDsaTests_Span + { + protected override ECDsaProvider ECDsaFactory { get; } = DefaultECDsaProvider.Instance; + } + + public sealed class ECDsaTests_AllocatingSpan_Default : ECDsaTests_AllocatingSpan + { + protected override ECDsaProvider ECDsaFactory { get; } = DefaultECDsaProvider.Instance; + } + + public sealed class ECDsaTests_TrySpan_Default : ECDsaTests_TrySpan + { + protected override ECDsaProvider ECDsaFactory { get; } = DefaultECDsaProvider.Instance; + } + + public sealed class ECDsaFactoryTests_Default : ECDsaFactoryTests + { + protected override ECDsaProvider ECDsaFactory { get; } = DefaultECDsaProvider.Instance; + } + + public sealed class ECDsaImportExportTests_Default : ECDsaImportExportTests + { + protected override ECDsaProvider ECDsaFactory { get; } = DefaultECDsaProvider.Instance; + protected override bool CanDeriveNewPublicKey { get; } = EcDiffieHellman.Tests.DefaultECDiffieHellmanProvider.Instance.CanDeriveNewPublicKey; + } + + public sealed class ECDsaKeyFileTests_Default : ECDsaKeyFileTests + { + protected override ECDsaProvider ECDsaFactory { get; } = DefaultECDsaProvider.Instance; + protected override bool CanDeriveNewPublicKey { get; } = EcDiffieHellman.Tests.DefaultECDiffieHellmanProvider.Instance.CanDeriveNewPublicKey; + } + + public sealed class ECDsaXml_Default : ECDsaXml + { + protected override ECDsaProvider ECDsaFactory { get; } = DefaultECDsaProvider.Instance; + } + + public sealed class ECDsaArraySignatureFormatTests_Default : ECDsaArraySignatureFormatTests + { + protected override ECDsaProvider ECDsaFactory { get; } = DefaultECDsaProvider.Instance; + } + + public sealed class ECDsaArrayOffsetSignatureFormatTests_Default : ECDsaArrayOffsetSignatureFormatTests + { + protected override ECDsaProvider ECDsaFactory { get; } = DefaultECDsaProvider.Instance; + } + + public sealed class ECDsaSpanSignatureFormatTests_Default : ECDsaSpanSignatureFormatTests + { + protected override ECDsaProvider ECDsaFactory { get; } = DefaultECDsaProvider.Instance; + } +} diff --git a/src/libraries/System.Security.Cryptography/tests/ECDsaTestRegistration.OpenSsl.cs b/src/libraries/System.Security.Cryptography/tests/ECDsaTestRegistration.OpenSsl.cs new file mode 100644 index 00000000000000..909f2641032c03 --- /dev/null +++ b/src/libraries/System.Security.Cryptography/tests/ECDsaTestRegistration.OpenSsl.cs @@ -0,0 +1,67 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Security.Cryptography.EcDsa.Tests +{ + public sealed class ECDsaTests_Array_OpenSsl : ECDsaTests_Array + { + protected override ECDsaProvider ECDsaFactory { get; } = ECDsaOpenSslProvider.Instance; + } + + public sealed class ECDsaTests_Stream_OpenSsl : ECDsaTests_Stream + { + protected override ECDsaProvider ECDsaFactory { get; } = ECDsaOpenSslProvider.Instance; + } + + public sealed class ECDsaTests_Span_OpenSsl : ECDsaTests_Span + { + protected override ECDsaProvider ECDsaFactory { get; } = ECDsaOpenSslProvider.Instance; + } + + public sealed class ECDsaTests_AllocatingSpan_OpenSsl : ECDsaTests_AllocatingSpan + { + protected override ECDsaProvider ECDsaFactory { get; } = ECDsaOpenSslProvider.Instance; + } + + public sealed class ECDsaTests_TrySpan_OpenSsl : ECDsaTests_TrySpan + { + protected override ECDsaProvider ECDsaFactory { get; } = ECDsaOpenSslProvider.Instance; + } + + public sealed class ECDsaFactoryTests_OpenSsl : ECDsaFactoryTests + { + protected override ECDsaProvider ECDsaFactory { get; } = ECDsaOpenSslProvider.Instance; + } + + public sealed class ECDsaImportExportTests_OpenSsl : ECDsaImportExportTests + { + protected override ECDsaProvider ECDsaFactory { get; } = ECDsaOpenSslProvider.Instance; + protected override bool CanDeriveNewPublicKey { get; } = EcDiffieHellman.Tests.ECDiffieHellmanOpenSslProvider.Instance.CanDeriveNewPublicKey; + } + + public sealed class ECDsaKeyFileTests_OpenSsl : ECDsaKeyFileTests + { + protected override ECDsaProvider ECDsaFactory { get; } = ECDsaOpenSslProvider.Instance; + protected override bool CanDeriveNewPublicKey { get; } = EcDiffieHellman.Tests.ECDiffieHellmanOpenSslProvider.Instance.CanDeriveNewPublicKey; + } + + public sealed class ECDsaXml_OpenSsl : ECDsaXml + { + protected override ECDsaProvider ECDsaFactory { get; } = ECDsaOpenSslProvider.Instance; + } + + public sealed class ECDsaArraySignatureFormatTests_OpenSsl : ECDsaArraySignatureFormatTests + { + protected override ECDsaProvider ECDsaFactory { get; } = ECDsaOpenSslProvider.Instance; + } + + public sealed class ECDsaArrayOffsetSignatureFormatTests_OpenSsl : ECDsaArrayOffsetSignatureFormatTests + { + protected override ECDsaProvider ECDsaFactory { get; } = ECDsaOpenSslProvider.Instance; + } + + public sealed class ECDsaSpanSignatureFormatTests_OpenSsl : ECDsaSpanSignatureFormatTests + { + protected override ECDsaProvider ECDsaFactory { get; } = ECDsaOpenSslProvider.Instance; + } +} diff --git a/src/libraries/System.Security.Cryptography/tests/EcDiffieHellmanOpenSslProvider.cs b/src/libraries/System.Security.Cryptography/tests/EcDiffieHellmanOpenSslProvider.cs new file mode 100644 index 00000000000000..b26c2d1a1cacfa --- /dev/null +++ b/src/libraries/System.Security.Cryptography/tests/EcDiffieHellmanOpenSslProvider.cs @@ -0,0 +1,35 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Security.Cryptography.EcDiffieHellman.Tests +{ + public sealed class ECDiffieHellmanOpenSslProvider : ECDiffieHellmanProvider + { + public static readonly ECDiffieHellmanOpenSslProvider Instance = new ECDiffieHellmanOpenSslProvider(); + + private ECDiffieHellmanOpenSslProvider() { } + + public override ECDiffieHellman Create() + { + return new ECDiffieHellmanOpenSsl(); + } + + public override ECDiffieHellman Create(int keySize) + { + return new ECDiffieHellmanOpenSsl(keySize); + } + + public override ECDiffieHellman Create(ECCurve curve) + { + return new ECDiffieHellmanOpenSsl(curve); + } + + public override bool IsCurveValid(Oid oid) => EcDsa.Tests.ECDsaOpenSslProvider.Instance.IsCurveValid(oid); + + public override bool ExplicitCurvesSupported => EcDsa.Tests.ECDsaOpenSslProvider.Instance.ExplicitCurvesSupported; + + public override bool CanDeriveNewPublicKey => true; + public override bool SupportsRawDerivation => true; + public override bool SupportsSha3 => PlatformDetection.SupportsSha3; + } +} diff --git a/src/libraries/System.Security.Cryptography.OpenSsl/tests/EcDiffieHellmanOpenSslTests.cs b/src/libraries/System.Security.Cryptography/tests/EcDiffieHellmanOpenSslTests.cs similarity index 81% rename from src/libraries/System.Security.Cryptography.OpenSsl/tests/EcDiffieHellmanOpenSslTests.cs rename to src/libraries/System.Security.Cryptography/tests/EcDiffieHellmanOpenSslTests.cs index a9c120cca8d47a..32cc5b4b990edb 100644 --- a/src/libraries/System.Security.Cryptography.OpenSsl/tests/EcDiffieHellmanOpenSslTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/EcDiffieHellmanOpenSslTests.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.DotNet.XUnitExtensions; using System.Security.Cryptography.EcDiffieHellman.Tests; using System.Security.Cryptography.Tests; using Test.Cryptography; @@ -8,13 +9,13 @@ namespace System.Security.Cryptography.EcDiffieHellman.OpenSsl.Tests { - public class EcDiffieHellmanOpenSslTests : ECDiffieHellmanTests + public static class EcDiffieHellmanOpenSslTests { - public static bool ECExplicitCurvesSupported => ECDiffieHellmanFactory.ExplicitCurvesSupported; - public static bool SupportsExplicitCurves => ECDiffieHellmanFactory.ExplicitCurvesSupported || ECDiffieHellmanFactory.ExplicitCurvesSupportFailOnUseOnly; + public static bool ECExplicitCurvesSupported => ECDiffieHellmanOpenSslProvider.Instance.ExplicitCurvesSupported; + public static bool SupportsExplicitCurves => ECDiffieHellmanOpenSslProvider.Instance.ExplicitCurvesSupported || ECDiffieHellmanOpenSslProvider.Instance.ExplicitCurvesSupportFailOnUseOnly; [Fact] - public void DefaultCtor() + public static void DefaultCtor() { using (var e = new ECDiffieHellmanOpenSsl()) { @@ -25,7 +26,7 @@ public void DefaultCtor() } [Fact] - public void Ctor256() + public static void Ctor256() { int expectedKeySize = 256; using (var e = new ECDiffieHellmanOpenSsl(expectedKeySize)) @@ -37,7 +38,7 @@ public void Ctor256() } [Fact] - public void Ctor384() + public static void Ctor384() { int expectedKeySize = 384; using (var e = new ECDiffieHellmanOpenSsl(expectedKeySize)) @@ -49,7 +50,7 @@ public void Ctor384() } [Fact] - public void Ctor521() + public static void Ctor521() { int expectedKeySize = 521; using (var e = new ECDiffieHellmanOpenSsl(expectedKeySize)) @@ -60,10 +61,12 @@ public void Ctor521() } } - [ConditionalFact(typeof(EcDiffieHellmanOpenSslTests), nameof(ECDsa224Available))] - public void CtorHandle224() + [ConditionalFact] + public static void CtorHandle224() { - IntPtr ecKey = Interop.Crypto.EcKeyCreateByOid(ECDSA_P224_OID_VALUE); + SkipTestException.ThrowUnless(ECDiffieHellmanOpenSslProvider.Instance.IsCurveValid(new Oid(EccTestBase.ECDSA_P224_OID_VALUE))); + + IntPtr ecKey = Interop.Crypto.EcKeyCreateByOid(EccTestBase.ECDSA_P224_OID_VALUE); Assert.NotEqual(IntPtr.Zero, ecKey); int success = Interop.Crypto.EcKeyGenerateKey(ecKey); Assert.NotEqual(0, success); @@ -79,9 +82,9 @@ public void CtorHandle224() } [Fact] - public void CtorHandle384() + public static void CtorHandle384() { - IntPtr ecKey = Interop.Crypto.EcKeyCreateByOid(ECDSA_P384_OID_VALUE); + IntPtr ecKey = Interop.Crypto.EcKeyCreateByOid(EccTestBase.ECDSA_P384_OID_VALUE); Assert.NotEqual(IntPtr.Zero, ecKey); int success = Interop.Crypto.EcKeyGenerateKey(ecKey); Assert.NotEqual(0, success); @@ -97,9 +100,9 @@ public void CtorHandle384() } [Fact] - public void CtorHandle521() + public static void CtorHandle521() { - IntPtr ecKey = Interop.Crypto.EcKeyCreateByOid(ECDSA_P521_OID_VALUE); + IntPtr ecKey = Interop.Crypto.EcKeyCreateByOid(EccTestBase.ECDSA_P521_OID_VALUE); Assert.NotEqual(IntPtr.Zero, ecKey); int success = Interop.Crypto.EcKeyGenerateKey(ecKey); Assert.NotEqual(0, success); @@ -115,9 +118,9 @@ public void CtorHandle521() } [Fact] - public void CtorHandleDuplicate() + public static void CtorHandleDuplicate() { - IntPtr ecKey = Interop.Crypto.EcKeyCreateByOid(ECDSA_P521_OID_VALUE); + IntPtr ecKey = Interop.Crypto.EcKeyCreateByOid(EccTestBase.ECDSA_P521_OID_VALUE); Assert.NotEqual(IntPtr.Zero, ecKey); int success = Interop.Crypto.EcKeyGenerateKey(ecKey); Assert.NotEqual(0, success); @@ -134,10 +137,10 @@ public void CtorHandleDuplicate() } [Theory] - [InlineData(ECDSA_P256_OID_VALUE, 256)] - [InlineData(ECDSA_P384_OID_VALUE, 384)] - [InlineData(ECDSA_P521_OID_VALUE, 521)] - public void CtorEvpPKeyHandle(string oid, int expectedKeySize) + [InlineData(EccTestBase.ECDSA_P256_OID_VALUE, 256)] + [InlineData(EccTestBase.ECDSA_P384_OID_VALUE, 384)] + [InlineData(EccTestBase.ECDSA_P521_OID_VALUE, 521)] + public static void CtorEvpPKeyHandle(string oid, int expectedKeySize) { int rc = Interop.Crypto.EvpPKeyGenerateByEcCurveOid(out SafeEvpPKeyHandle pkey, oid, out int keySize); @@ -154,7 +157,7 @@ public void CtorEvpPKeyHandle(string oid, int expectedKeySize) } [Fact] - public void KeySizePropWithExercise() + public static void KeySizePropWithExercise() { using (var e = new ECDiffieHellmanOpenSsl()) { @@ -176,7 +179,7 @@ public void KeySizePropWithExercise() } [Fact] - public void VerifyDuplicateKey_ValidHandle() + public static void VerifyDuplicateKey_ValidHandle() { using (var first = new ECDiffieHellmanOpenSsl()) using (SafeEvpPKeyHandle firstHandle = first.DuplicateKeyHandle()) @@ -194,7 +197,7 @@ public void VerifyDuplicateKey_ValidHandle() } [Fact] - public void VerifyDuplicateKey_DistinctHandles() + public static void VerifyDuplicateKey_DistinctHandles() { using (var first = new ECDiffieHellmanOpenSsl()) using (SafeEvpPKeyHandle firstHandle = first.DuplicateKeyHandle()) @@ -205,7 +208,7 @@ public void VerifyDuplicateKey_DistinctHandles() } [Fact] - public void VerifyDuplicateKey_RefCounts() + public static void VerifyDuplicateKey_RefCounts() { byte[] derived; ECDiffieHellman second; @@ -228,14 +231,14 @@ public void VerifyDuplicateKey_RefCounts() } [Fact] - public void VerifyDuplicateKey_NullHandle() + public static void VerifyDuplicateKey_NullHandle() { SafeEvpPKeyHandle pkey = null; Assert.Throws(() => new ECDiffieHellmanOpenSsl(pkey)); } [Fact] - public void VerifyDuplicateKey_InvalidHandle() + public static void VerifyDuplicateKey_InvalidHandle() { using (var ecdsa = new ECDiffieHellmanOpenSsl()) { @@ -250,7 +253,7 @@ public void VerifyDuplicateKey_InvalidHandle() } [Fact] - public void VerifyDuplicateKey_NeverValidHandle() + public static void VerifyDuplicateKey_NeverValidHandle() { using (SafeEvpPKeyHandle pkey = new SafeEvpPKeyHandle(IntPtr.Zero, false)) { @@ -259,7 +262,7 @@ public void VerifyDuplicateKey_NeverValidHandle() } [Fact] - public void VerifyDuplicateKey_RsaHandle() + public static void VerifyDuplicateKey_RsaHandle() { using (RSAOpenSsl rsa = new RSAOpenSsl()) using (SafeEvpPKeyHandle pkey = rsa.DuplicateKeyHandle()) @@ -269,19 +272,19 @@ public void VerifyDuplicateKey_RsaHandle() } [Fact] - public void LookupCurveByOidValue() + public static void LookupCurveByOidValue() { - var ec = new ECDiffieHellmanOpenSsl(ECCurve.CreateFromValue(ECDSA_P256_OID_VALUE)); // Same as nistP256 + var ec = new ECDiffieHellmanOpenSsl(ECCurve.CreateFromValue(EccTestBase.ECDSA_P256_OID_VALUE)); // Same as nistP256 ECParameters param = ec.ExportParameters(false); param.Validate(); Assert.Equal(256, ec.KeySize); Assert.True(param.Curve.IsNamed); Assert.Equal("ECDSA_P256", param.Curve.Oid.FriendlyName); - Assert.Equal(ECDSA_P256_OID_VALUE, param.Curve.Oid.Value); + Assert.Equal(EccTestBase.ECDSA_P256_OID_VALUE, param.Curve.Oid.Value); } [Fact] - public void LookupCurveByOidFriendlyName() + public static void LookupCurveByOidFriendlyName() { // prime256v1 is alias for nistP256 for OpenSsl var ec = new ECDiffieHellmanOpenSsl(ECCurve.CreateFromFriendlyName("prime256v1")); @@ -291,7 +294,7 @@ public void LookupCurveByOidFriendlyName() Assert.Equal(256, ec.KeySize); Assert.True(param.Curve.IsNamed); Assert.Equal("ECDSA_P256", param.Curve.Oid.FriendlyName); // OpenSsl maps prime256v1 to ECDSA_P256 - Assert.Equal(ECDSA_P256_OID_VALUE, param.Curve.Oid.Value); + Assert.Equal(EccTestBase.ECDSA_P256_OID_VALUE, param.Curve.Oid.Value); // secp521r1 is same as nistP521; note Windows uses secP521r1 (uppercase P) ec = new ECDiffieHellmanOpenSsl(ECCurve.CreateFromFriendlyName("secp521r1")); @@ -300,14 +303,14 @@ public void LookupCurveByOidFriendlyName() Assert.Equal(521, ec.KeySize); Assert.True(param.Curve.IsNamed); Assert.Equal("ECDSA_P521", param.Curve.Oid.FriendlyName); // OpenSsl maps secp521r1 to ECDSA_P521 - Assert.Equal(ECDSA_P521_OID_VALUE, param.Curve.Oid.Value); + Assert.Equal(EccTestBase.ECDSA_P521_OID_VALUE, param.Curve.Oid.Value); } [Theory] - [InlineData(ECDSA_P256_OID_VALUE, 256)] - [InlineData(ECDSA_P384_OID_VALUE, 384)] - [InlineData(ECDSA_P521_OID_VALUE, 521)] - public void CtorEcKeyExportMatchesReimport(string oid, int expectedKeySize) + [InlineData(EccTestBase.ECDSA_P256_OID_VALUE, 256)] + [InlineData(EccTestBase.ECDSA_P384_OID_VALUE, 384)] + [InlineData(EccTestBase.ECDSA_P521_OID_VALUE, 521)] + public static void CtorEcKeyExportMatchesReimport(string oid, int expectedKeySize) { IntPtr ecKey = Interop.Crypto.EcKeyCreateByOid(oid); Assert.NotEqual(IntPtr.Zero, ecKey); @@ -328,8 +331,8 @@ public void CtorEcKeyExportMatchesReimport(string oid, int expectedKeySize) ECParameters evpPrivateParams = evpBacked.ExportParameters(true); - ComparePublicKey(privateParams.Q, evpPrivateParams.Q); - ComparePrivateKey(privateParams, evpPrivateParams); + EccTestBase.ComparePublicKey(privateParams.Q, evpPrivateParams.Q); + EccTestBase.ComparePrivateKey(privateParams, evpPrivateParams); } } } @@ -340,10 +343,10 @@ public void CtorEcKeyExportMatchesReimport(string oid, int expectedKeySize) } [Theory] - [InlineData(ECDSA_P256_OID_VALUE)] - [InlineData(ECDSA_P384_OID_VALUE)] - [InlineData(ECDSA_P521_OID_VALUE)] - public void CtorEcKeyDeriveCrossCompatibleWithReimport(string oid) + [InlineData(EccTestBase.ECDSA_P256_OID_VALUE)] + [InlineData(EccTestBase.ECDSA_P384_OID_VALUE)] + [InlineData(EccTestBase.ECDSA_P521_OID_VALUE)] + public static void CtorEcKeyDeriveCrossCompatibleWithReimport(string oid) { IntPtr rawKey1 = Interop.Crypto.EcKeyCreateByOid(oid); Assert.NotEqual(IntPtr.Zero, rawKey1); @@ -380,7 +383,7 @@ public void CtorEcKeyDeriveCrossCompatibleWithReimport(string oid) } [Fact] - public void CtorEcKeyDeriveLeftAndRightSide() + public static void CtorEcKeyDeriveLeftAndRightSide() { ECParameters testData = EccTestData.GetNistP256ReferenceKey(); @@ -415,7 +418,7 @@ public void CtorEcKeyDeriveLeftAndRightSide() } [Fact] - public void CtorEcKeyPublicOnlyFailsDerive() + public static void CtorEcKeyPublicOnlyFailsDerive() { ECParameters testData = EccTestData.GetNistP256ReferenceKey(); @@ -446,9 +449,11 @@ public void CtorEcKeyPublicOnlyFailsDerive() } } - [ConditionalFact(nameof(SupportsExplicitCurves))] - public void ExplicitCurveImportExportProducesSameExplicitParams() + [ConditionalFact] + public static void ExplicitCurveImportExportProducesSameExplicitParams() { + SkipTestException.ThrowUnless(SupportsExplicitCurves); + ECCurve explicitCurve = EccTestData.GetNistP256ExplicitCurve(); using (ECDiffieHellman original = ECDiffieHellman.Create(explicitCurve)) @@ -459,15 +464,17 @@ public void ExplicitCurveImportExportProducesSameExplicitParams() { ECParameters reimportedParams = reimported.ExportExplicitParameters(true); - ComparePublicKey(explicitParams.Q, reimportedParams.Q); - ComparePrivateKey(explicitParams, reimportedParams); + EccTestBase.ComparePublicKey(explicitParams.Q, reimportedParams.Q); + EccTestBase.ComparePrivateKey(explicitParams, reimportedParams); } } } - [ConditionalFact(nameof(ECExplicitCurvesSupported))] - public void ExplicitCurveImportAndOriginalDeriveCrossCompatible() + [ConditionalFact] + public static void ExplicitCurveImportAndOriginalDeriveCrossCompatible() { + SkipTestException.ThrowUnless(ECExplicitCurvesSupported); + ECCurve explicitCurve = EccTestData.GetNistP256ExplicitCurve(); using (ECDiffieHellman key1 = ECDiffieHellman.Create(explicitCurve)) @@ -494,7 +501,7 @@ public void ExplicitCurveImportAndOriginalDeriveCrossCompatible() } [Fact] - public void GenerateKeyImplicitCurveThrows() + public static void GenerateKeyImplicitCurveThrows() { ECCurve implicitCurve = default; @@ -505,7 +512,7 @@ public void GenerateKeyImplicitCurveThrows() } [Fact] - public void ImportParametersImplicitCurveThrows() + public static void ImportParametersImplicitCurveThrows() { ECParameters parameters = new ECParameters { diff --git a/src/libraries/System.Security.Cryptography.OpenSsl/tests/EcDsaOpenSslProvider.cs b/src/libraries/System.Security.Cryptography/tests/EcDsaOpenSslProvider.cs similarity index 70% rename from src/libraries/System.Security.Cryptography.OpenSsl/tests/EcDsaOpenSslProvider.cs rename to src/libraries/System.Security.Cryptography/tests/EcDsaOpenSslProvider.cs index 82607d480b5353..654bf08775274f 100644 --- a/src/libraries/System.Security.Cryptography.OpenSsl/tests/EcDsaOpenSslProvider.cs +++ b/src/libraries/System.Security.Cryptography/tests/EcDsaOpenSslProvider.cs @@ -3,24 +3,28 @@ namespace System.Security.Cryptography.EcDsa.Tests { - public class ECDsaProvider : IECDsaProvider + public class ECDsaOpenSslProvider : ECDsaProvider { - public ECDsa Create() + public static readonly ECDsaOpenSslProvider Instance = new ECDsaOpenSslProvider(); + + private ECDsaOpenSslProvider() { } + + public override ECDsa Create() { return new ECDsaOpenSsl(); } - public ECDsa Create(int keySize) + public override ECDsa Create(int keySize) { return new ECDsaOpenSsl(keySize); } - public ECDsa Create(ECCurve curve) + public override ECDsa Create(ECCurve curve) { return new ECDsaOpenSsl(curve); } - public bool IsCurveValid(Oid oid) + public override bool IsCurveValid(Oid oid) { if (!string.IsNullOrEmpty(oid.Value)) { @@ -46,11 +50,7 @@ private static bool IsValueOrFriendlyNameValid(string friendlyNameOrValue) return false; } - public bool ExplicitCurvesSupported => PlatformDetection.IsNotSymCryptOpenSsl; - } + public override bool ExplicitCurvesSupported => PlatformDetection.IsNotSymCryptOpenSsl; - public partial class ECDsaFactory - { - private static readonly IECDsaProvider s_provider = new ECDsaProvider(); } } diff --git a/src/libraries/System.Security.Cryptography.OpenSsl/tests/EcDsaOpenSslTests.cs b/src/libraries/System.Security.Cryptography/tests/EcDsaOpenSslTests.cs similarity index 96% rename from src/libraries/System.Security.Cryptography.OpenSsl/tests/EcDsaOpenSslTests.cs rename to src/libraries/System.Security.Cryptography/tests/EcDsaOpenSslTests.cs index 91eadd045a9f89..c103d943ac3cf1 100644 --- a/src/libraries/System.Security.Cryptography.OpenSsl/tests/EcDsaOpenSslTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/EcDsaOpenSslTests.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.DotNet.XUnitExtensions; using System; using System.Runtime.InteropServices; using System.Security.Cryptography; @@ -13,7 +14,9 @@ namespace System.Security.Cryptography.EcDsa.OpenSsl.Tests { public class EcDsaOpenSslTests : ECDsaTestsBase { - public static bool SupportsExplicitCurves => ECDsaFactory.ExplicitCurvesSupported || ECDsaFactory.ExplicitCurvesSupportFailOnUseOnly; + protected override ECDsaProvider ECDsaFactory { get; } = ECDsaOpenSslProvider.Instance; + + public bool SupportsExplicitCurves => ECDsaFactory.ExplicitCurvesSupported || ECDsaFactory.ExplicitCurvesSupportFailOnUseOnly; [Fact] public void DefaultCtor() @@ -62,9 +65,11 @@ public void Ctor521() } } - [ConditionalFact(typeof(EcDsaOpenSslTests), nameof(ECDsa224Available))] + [ConditionalFact] public void CtorHandle224() { + SkipTestException.ThrowUnless(ECDsa224Available); + IntPtr ecKey = Interop.Crypto.EcKeyCreateByOid(ECDSA_P224_OID_VALUE); Assert.NotEqual(IntPtr.Zero, ecKey); int success = Interop.Crypto.EcKeyGenerateKey(ecKey); @@ -391,7 +396,7 @@ public void CtorEcKeySignVerifyCrossCompatible(string oid) private const string ECDSA_WTLS7_OID_VALUE = "2.23.43.1.4.7"; - private static bool IsWtls7Available => ECDsaFactory.IsCurveValid(new Oid(ECDSA_WTLS7_OID_VALUE)); + private bool IsWtls7Available => ECDsaFactory.IsCurveValid(new Oid(ECDSA_WTLS7_OID_VALUE)); [Theory] [InlineData(ECDSA_P256_OID_VALUE, 256)] @@ -402,9 +407,11 @@ public void CtorEcKeyNamedCurveExportIsCorrect(string oid, int expectedKeySize) VerifyCtorEcKeyNamedCurveExport(oid, expectedKeySize); } - [ConditionalFact(nameof(IsWtls7Available))] + [ConditionalFact] public void CtorEcKeyFieldDegreeNotEqualOrderBits() { + SkipTestException.ThrowUnless(IsWtls7Available); + // wap-wsg-idm-ecid-wtls7 has field=160 bits but order=161 bits. // Verify KeySize uses field degree (160), not EVP_PKEY_bits (161). VerifyCtorEcKeyNamedCurveExport(ECDSA_WTLS7_OID_VALUE, 160); @@ -476,9 +483,11 @@ public void CtorEcKeyNamedCurveImportExportIsCorrect() } } - [ConditionalFact(nameof(ECExplicitCurvesSupported))] + [ConditionalFact] public void CtorEcKeyExplicitPrimeCurveExportIsCorrect() { + SkipTestException.ThrowUnless(ECExplicitCurvesSupported); + ECParameters testData = EccTestData.GetNistP256ReferenceKeyExplicit(); ECCurve curve = testData.Curve; @@ -525,9 +534,11 @@ public void CtorEcKeyExplicitPrimeCurveExportIsCorrect() } } - [ConditionalFact(nameof(ECExplicitCurvesSupported))] + [ConditionalFact] public void CtorEcKeyExplicitChar2CurveExportIsCorrect() { + SkipTestException.ThrowUnless(ECExplicitCurvesSupported); + ECParameters testData = EccTestData.Sect163k1Key1Explicit; if (!ECDsaFactory.IsCurveValid(EccTestData.Sect163k1Key1.Curve.Oid)) @@ -697,9 +708,11 @@ public void CtorEcKeyPublicOnlyExportPrivateThrows() } } - [ConditionalFact(nameof(SupportsExplicitCurves))] + [ConditionalFact] public void ExplicitCurveImportExportProducesSameExplicitParams() { + SkipTestException.ThrowUnless(SupportsExplicitCurves); + ECCurve explicitCurve = EccTestData.GetNistP256ExplicitCurve(); using (ECDsa original = ECDsa.Create(explicitCurve)) @@ -716,9 +729,11 @@ public void ExplicitCurveImportExportProducesSameExplicitParams() } } - [ConditionalFact(nameof(ECExplicitCurvesSupported))] + [ConditionalFact] public void ExplicitCurveImportAndOriginalSignVerifyCrossCompatible() { + SkipTestException.ThrowUnless(ECExplicitCurvesSupported); + byte[] data = ByteUtils.RepeatByte(0x42, 64); ECCurve explicitCurve = EccTestData.GetNistP256ExplicitCurve(); @@ -769,9 +784,6 @@ internal static partial class Interop { internal static partial class Crypto { - [DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EcKeyCreateByOid")] - internal static extern IntPtr EcKeyCreateByOid(string oid); - [DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EcKeyCreateByKeyParameters")] internal static extern int EcKeyCreateByKeyParameters( out IntPtr key, @@ -783,9 +795,6 @@ internal static extern int EcKeyCreateByKeyParameters( [DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EcKeyGenerateKey")] internal static extern int EcKeyGenerateKey(IntPtr ecKey); - [DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_EcKeyDestroy")] - internal static extern void EcKeyDestroy(IntPtr r); - [DllImport(Libraries.CryptoNative, EntryPoint = "CryptoNative_OpenSslVersionNumber")] internal static extern uint OpenSslVersionNumber(); diff --git a/src/libraries/System.Security.Cryptography/tests/System.Security.Cryptography.Tests.csproj b/src/libraries/System.Security.Cryptography/tests/System.Security.Cryptography.Tests.csproj index 56ed338c3f9b1a..e91c70ef291071 100644 --- a/src/libraries/System.Security.Cryptography/tests/System.Security.Cryptography.Tests.csproj +++ b/src/libraries/System.Security.Cryptography/tests/System.Security.Cryptography.Tests.csproj @@ -234,6 +234,8 @@ Link="CommonTest\System\Security\Cryptography\MLKemAlgorithmTests.cs" /> + - + - + - + + @@ -545,9 +547,9 @@ - + - + @@ -703,7 +705,15 @@ + + + + + + + + + + + + + + diff --git a/src/libraries/System.Security.Cryptography.Cng/tests/TestData.cs b/src/libraries/System.Security.Cryptography/tests/TestData.Cng.cs similarity index 100% rename from src/libraries/System.Security.Cryptography.Cng/tests/TestData.cs rename to src/libraries/System.Security.Cryptography/tests/TestData.Cng.cs diff --git a/src/libraries/System.Security.Cryptography/tests/X509Certificates/ExportTests.cs b/src/libraries/System.Security.Cryptography/tests/X509Certificates/ExportTests.cs index 649ab7697747d7..61333bec6f04fc 100644 --- a/src/libraries/System.Security.Cryptography/tests/X509Certificates/ExportTests.cs +++ b/src/libraries/System.Security.Cryptography/tests/X509Certificates/ExportTests.cs @@ -5,6 +5,7 @@ using System.Security.Cryptography.Tests; using System.Security.Cryptography.Dsa.Tests; using System.Security.Cryptography.EcDsa.Tests; +using System.Security.Cryptography.EcDiffieHellman.Tests; using System.Security.Cryptography.SLHDsa.Tests; using System.Security.Cryptography.Asn1; using System.Security.Cryptography.Asn1.Pkcs7; @@ -729,7 +730,7 @@ public static void ECDsa_Export_DefaultKeyStorePermitsUnencryptedExports_Pkcs8Pr [SkipOnPlatform(TestPlatforms.iOS | TestPlatforms.MacCatalyst | TestPlatforms.tvOS, "The PKCS#12 Exportable flag is not supported on iOS/MacCatalyst/tvOS")] public static void ECDsa_Export_DefaultKeyStorePermitsUnencryptedExports_ExportParameters(bool explicitParameters) { - if (explicitParameters && !ECDsaFactory.ExplicitCurvesSupported) + if (explicitParameters && !DefaultECDsaProvider.Instance.ExplicitCurvesSupported) { return; } @@ -756,7 +757,7 @@ public static void ECDsa_Export_DefaultKeyStorePermitsUnencryptedExports_ExportP [SkipOnPlatform(TestPlatforms.iOS | TestPlatforms.MacCatalyst | TestPlatforms.tvOS, "The PKCS#12 Exportable flag is not supported on iOS/MacCatalyst/tvOS")] public static void ECDH_Export_DefaultKeyStorePermitsUnencryptedExports_ExportParameters(bool explicitParameters) { - if (explicitParameters && !ECDsaFactory.ExplicitCurvesSupported) + if (explicitParameters && !DefaultECDiffieHellmanProvider.Instance.ExplicitCurvesSupported) { return; }