diff --git a/CoseHandler.Tests/CoseHandler.Tests.csproj b/CoseHandler.Tests/CoseHandler.Tests.csproj index eb19bd54..9efff1a6 100644 --- a/CoseHandler.Tests/CoseHandler.Tests.csproj +++ b/CoseHandler.Tests/CoseHandler.Tests.csproj @@ -2,7 +2,7 @@ Exe - net8.0 + net10.0 enable enable latest diff --git a/CoseHandler.Tests/SignWithKeyProviderTests.cs b/CoseHandler.Tests/SignWithKeyProviderTests.cs index 94066d43..f1b1fb20 100644 --- a/CoseHandler.Tests/SignWithKeyProviderTests.cs +++ b/CoseHandler.Tests/SignWithKeyProviderTests.cs @@ -37,13 +37,7 @@ public void TestSignWithNoSigningKey() Mock mockedSignerKeyProvider = new(MockBehavior.Strict); mockedSignerKeyProvider.Setup(x => x.GetProtectedHeaders()).Returns(null); mockedSignerKeyProvider.Setup(x => x.GetUnProtectedHeaders()).Returns(null); - mockedSignerKeyProvider.Setup(x => x.HashAlgorithm).Returns(HashAlgorithmName.SHA256); - mockedSignerKeyProvider.Setup(x => x.GetECDsaKey(It.IsAny())).Returns(null); - mockedSignerKeyProvider.Setup(x => x.GetRSAKey(It.IsAny())).Returns(null); - mockedSignerKeyProvider.Setup(x => x.IsRSA).Returns(false); - - // Setup KeyChain property to return empty list since no keys are available - mockedSignerKeyProvider.Setup(x => x.KeyChain).Returns(new List().AsReadOnly()); + mockedSignerKeyProvider.Setup(x => x.GetCoseKey()).Returns(null); CoseSigningException exceptionText = Assert.ThrowsException(() => CoseHandler.Sign(testPayload.ToArray(), mockedSignerKeyProvider.Object, false, new FileInfo(signedFile))); exceptionText.Message.Should().Be("Unsupported certificate type for COSE signing."); @@ -55,30 +49,13 @@ public void TestSignWithNoSigningKey() [TestMethod] public void TestSignWithEmptyPayload() { - Mock mockedSignerKeyProvider = new(MockBehavior.Strict); + ICoseSigningKeyProvider mockedSigningKeyProvider = TestCertificateUtils.SetupMockSigningKeyProvider(); CoseSign1MessageFactory coseSign1MessageFactory = new(); - X509Certificate2 selfSignedCertwithRSA = TestCertificateUtils.CreateCertificate(); ReadOnlyMemory testPayload = ReadOnlyMemory.Empty; string signedFile = Path.GetTempFileName(); - mockedSignerKeyProvider.Setup(x => x.GetProtectedHeaders()).Returns(null); - mockedSignerKeyProvider.Setup(x => x.GetUnProtectedHeaders()).Returns(null); - mockedSignerKeyProvider.Setup(x => x.HashAlgorithm).Returns(HashAlgorithmName.SHA256); - mockedSignerKeyProvider.Setup(x => x.GetECDsaKey(It.IsAny())).Returns(null); - mockedSignerKeyProvider.Setup(x => x.GetRSAKey(It.IsAny())).Returns(selfSignedCertwithRSA.GetRSAPrivateKey()); - mockedSignerKeyProvider.Setup(x => x.IsRSA).Returns(true); - - // Setup KeyChain property - RSA? publicKey = selfSignedCertwithRSA.GetRSAPublicKey(); - System.Collections.ObjectModel.ReadOnlyCollection keyChain = publicKey != null ? new List { publicKey }.AsReadOnly() : new List().AsReadOnly(); - mockedSignerKeyProvider.Setup(x => x.KeyChain).Returns(keyChain); - - bool isRSA = mockedSignerKeyProvider.Object.IsRSA; - - mockedSignerKeyProvider.Object.IsRSA.Should().BeTrue(); - - ArgumentException exceptionText = Assert.ThrowsException(() => CoseHandler.Sign(testPayload.ToArray(), mockedSignerKeyProvider.Object, false, new FileInfo(signedFile))); + ArgumentException exceptionText = Assert.ThrowsException(() => CoseHandler.Sign(testPayload.ToArray(), mockedSigningKeyProvider, false, new FileInfo(signedFile))); exceptionText.Message.Should().Be("Payload not provided."); } diff --git a/CoseIndirectSignature.Tests/CoseHashEnvelopeTests.cs b/CoseIndirectSignature.Tests/CoseHashEnvelopeTests.cs index 11a92b6a..6433cf5a 100644 --- a/CoseIndirectSignature.Tests/CoseHashEnvelopeTests.cs +++ b/CoseIndirectSignature.Tests/CoseHashEnvelopeTests.cs @@ -18,7 +18,7 @@ public void Setup() [Test] public void TestFactoryDefaultCreatesCoseHashEnvelop() { - ICoseSigningKeyProvider coseSigningKeyProvider = TestUtils.SetupMockSigningKeyProvider(); + ICoseSigningKeyProvider coseSigningKeyProvider = TestCertificateUtils.SetupMockSigningKeyProvider(); using IndirectSignatureFactory factory = new(); byte[] randomBytes = new byte[50]; new Random().NextBytes(randomBytes); @@ -58,7 +58,7 @@ public void TestFactoryDefaultCreatesCoseHashEnvelop() [Test] public void TestFactoryExplicitCreatesCoseHashEnvelop() { - ICoseSigningKeyProvider coseSigningKeyProvider = TestUtils.SetupMockSigningKeyProvider(); + ICoseSigningKeyProvider coseSigningKeyProvider = TestCertificateUtils.SetupMockSigningKeyProvider(); using IndirectSignatureFactory factory = new(); byte[] randomBytes = new byte[50]; new Random().NextBytes(randomBytes); @@ -125,7 +125,7 @@ public void TestExtensionMethodNullHandling(int testCase) [Test] public void ValidCoseHashEnvelopeMinusContentShouldInvalidate() { - ICoseSigningKeyProvider coseSigningKeyProvider = TestUtils.SetupMockSigningKeyProvider(); + ICoseSigningKeyProvider coseSigningKeyProvider = TestCertificateUtils.SetupMockSigningKeyProvider(); CoseSign1MessageFactory factory = new(); byte[] randomBytes = new byte[50]; @@ -147,7 +147,7 @@ public void ValidCoseHashEnvelopeMinusContentShouldInvalidate() [Test] public void ValidCoseHashEnvelopePayloadHashAlgorithmUnprotectedHeaderShouldInvalidate() { - ICoseSigningKeyProvider coseSigningKeyProvider = TestUtils.SetupMockSigningKeyProvider(); + ICoseSigningKeyProvider coseSigningKeyProvider = TestCertificateUtils.SetupMockSigningKeyProvider(); CoseSign1MessageFactory factory = new(); byte[] randomBytes = new byte[50]; @@ -182,7 +182,7 @@ public void ValidCoseHashEnvelopePayloadHashAlgorithmUnprotectedHeaderShouldInva [Test] public void ValidCoseHashEnvelopeInvalidPayloadHashAlgorithmShouldInvalidate() { - ICoseSigningKeyProvider coseSigningKeyProvider = TestUtils.SetupMockSigningKeyProvider(); + ICoseSigningKeyProvider coseSigningKeyProvider = TestCertificateUtils.SetupMockSigningKeyProvider(); CoseSign1MessageFactory factory = new(); byte[] randomBytes = new byte[50]; @@ -215,7 +215,7 @@ public void ValidCoseHashEnvelopeInvalidPayloadHashAlgorithmShouldInvalidate() [Test] public void ValidCoseHashEnvelopePayloadPreImageContentTypeUnprotectedHeaderShouldValidate() { - ICoseSigningKeyProvider coseSigningKeyProvider = TestUtils.SetupMockSigningKeyProvider(); + ICoseSigningKeyProvider coseSigningKeyProvider = TestCertificateUtils.SetupMockSigningKeyProvider(); CoseSign1MessageFactory factory = new(); byte[] randomBytes = new byte[50]; @@ -250,7 +250,7 @@ public void ValidCoseHashEnvelopePayloadPreImageContentTypeUnprotectedHeaderShou [Test] public void ValidCoseHashEnvelopePayloadNoPreImageContentShouldValidate() { - ICoseSigningKeyProvider coseSigningKeyProvider = TestUtils.SetupMockSigningKeyProvider(); + ICoseSigningKeyProvider coseSigningKeyProvider = TestCertificateUtils.SetupMockSigningKeyProvider(); CoseSign1MessageFactory factory = new(); byte[] randomBytes = new byte[50]; @@ -282,7 +282,7 @@ public void ValidCoseHashEnvelopePayloadNoPreImageContentShouldValidate() [Test] public void ValidCoseHashEnvelopePayloadNoPreImageContentCoaPShouldValidate() { - ICoseSigningKeyProvider coseSigningKeyProvider = TestUtils.SetupMockSigningKeyProvider(); + ICoseSigningKeyProvider coseSigningKeyProvider = TestCertificateUtils.SetupMockSigningKeyProvider(); CoseSign1MessageFactory factory = new(); byte[] randomBytes = new byte[50]; @@ -318,7 +318,7 @@ public void ValidCoseHashEnvelopePayloadNoPreImageContentCoaPShouldValidate() [Test] public void ValidCoseHashEnvelopePayloadNoPreImageContentCoaPUnprotectedShouldValidate() { - ICoseSigningKeyProvider coseSigningKeyProvider = TestUtils.SetupMockSigningKeyProvider(); + ICoseSigningKeyProvider coseSigningKeyProvider = TestCertificateUtils.SetupMockSigningKeyProvider(); CoseSign1MessageFactory factory = new(); byte[] randomBytes = new byte[50]; @@ -354,7 +354,7 @@ public void ValidCoseHashEnvelopePayloadNoPreImageContentCoaPUnprotectedShouldVa [Test] public void ValidCoseHashEnvelopePayloadLocationProtectedHeaderShouldValidate() { - ICoseSigningKeyProvider coseSigningKeyProvider = TestUtils.SetupMockSigningKeyProvider(); + ICoseSigningKeyProvider coseSigningKeyProvider = TestCertificateUtils.SetupMockSigningKeyProvider(); CoseSign1MessageFactory factory = new(); byte[] randomBytes = new byte[50]; @@ -379,7 +379,7 @@ public void ValidCoseHashEnvelopePayloadLocationProtectedHeaderShouldValidate() [Test] public void ValidCoseHashEnvelopePayloadLocationUnProtectedHeaderShouldInvalidate() { - ICoseSigningKeyProvider coseSigningKeyProvider = TestUtils.SetupMockSigningKeyProvider(); + ICoseSigningKeyProvider coseSigningKeyProvider = TestCertificateUtils.SetupMockSigningKeyProvider(); CoseSign1MessageFactory factory = new(); byte[] randomBytes = new byte[50]; @@ -416,7 +416,7 @@ public void ValidCoseHashEnvelopePayloadLocationUnProtectedHeaderShouldInvalidat [Test] public void CoseMessage1MinusContentShouldNotHashMatch() { - ICoseSigningKeyProvider coseSigningKeyProvider = TestUtils.SetupMockSigningKeyProvider(); + ICoseSigningKeyProvider coseSigningKeyProvider = TestCertificateUtils.SetupMockSigningKeyProvider(); CoseSign1MessageFactory factory = new(); byte[] randomBytes = new byte[50]; @@ -434,7 +434,7 @@ public void CoseMessage1MinusContentShouldNotHashMatch() [Test] public void CoseMessage1BadAlgorithmShouldNotHashMatch() { - ICoseSigningKeyProvider coseSigningKeyProvider = TestUtils.SetupMockSigningKeyProvider(); + ICoseSigningKeyProvider coseSigningKeyProvider = TestCertificateUtils.SetupMockSigningKeyProvider(); CoseSign1MessageFactory factory = new(); byte[] randomBytes = new byte[50]; diff --git a/CoseIndirectSignature.Tests/CoseIndirectSignature.Tests.csproj b/CoseIndirectSignature.Tests/CoseIndirectSignature.Tests.csproj index dea2000e..ff647ea3 100644 --- a/CoseIndirectSignature.Tests/CoseIndirectSignature.Tests.csproj +++ b/CoseIndirectSignature.Tests/CoseIndirectSignature.Tests.csproj @@ -5,7 +5,7 @@ enable false true - net8.0 + net10.0 enable false false diff --git a/CoseIndirectSignature.Tests/CoseSign1MessageIndirectSignatureExtensionsTests.cs b/CoseIndirectSignature.Tests/CoseSign1MessageIndirectSignatureExtensionsTests.cs index fb08cc3a..a8497bc3 100644 --- a/CoseIndirectSignature.Tests/CoseSign1MessageIndirectSignatureExtensionsTests.cs +++ b/CoseIndirectSignature.Tests/CoseSign1MessageIndirectSignatureExtensionsTests.cs @@ -20,7 +20,7 @@ public void Setup() [Test] public void TestTryGetIndirectSignatureAlgorithmSuccess() { - ICoseSigningKeyProvider coseSigningKeyProvider = SetupMockSigningKeyProvider(); + ICoseSigningKeyProvider coseSigningKeyProvider = TestCertificateUtils.SetupMockSigningKeyProvider(); IndirectSignatureFactory factory = new(); byte[] randomBytes = new byte[50]; new Random().NextBytes(randomBytes); @@ -34,7 +34,7 @@ public void TestTryGetIndirectSignatureAlgorithmSuccess() [Test] public void TestTryGetIndirectSignatureAlgorithmFailure() { - ICoseSigningKeyProvider coseSigningKeyProvider = SetupMockSigningKeyProvider(); + ICoseSigningKeyProvider coseSigningKeyProvider = TestCertificateUtils.SetupMockSigningKeyProvider(); // no content type Mock removeContentTypeHeaderExtender = new(MockBehavior.Strict); @@ -91,7 +91,7 @@ public void TestTryGetIndirectSignatureAlgorithmFailure() [Test] public void TestIsIndirectSignatureSuccess() { - ICoseSigningKeyProvider coseSigningKeyProvider = SetupMockSigningKeyProvider(); + ICoseSigningKeyProvider coseSigningKeyProvider = TestCertificateUtils.SetupMockSigningKeyProvider(); IndirectSignatureFactory factory = new(); byte[] randomBytes = new byte[50]; new Random().NextBytes(randomBytes); @@ -104,7 +104,7 @@ public void TestIsIndirectSignatureSuccess() [Test] public void TestIsIndirectSignatureFailure() { - ICoseSigningKeyProvider coseSigningKeyProvider = SetupMockSigningKeyProvider(); + ICoseSigningKeyProvider coseSigningKeyProvider = TestCertificateUtils.SetupMockSigningKeyProvider(); IndirectSignatureFactory factory = new(); byte[] randomBytes = new byte[50]; new Random().NextBytes(randomBytes); @@ -116,7 +116,7 @@ public void TestIsIndirectSignatureFailure() [Test] public void TestSignatureMatchesStreamSuccess() { - ICoseSigningKeyProvider coseSigningKeyProvider = SetupMockSigningKeyProvider(); + ICoseSigningKeyProvider coseSigningKeyProvider = TestCertificateUtils.SetupMockSigningKeyProvider(); IndirectSignatureFactory factory = new(); byte[] randomBytes = new byte[50]; new Random().NextBytes(randomBytes); @@ -129,7 +129,7 @@ public void TestSignatureMatchesStreamSuccess() [Test] public void TestSignatureMatchesStreamFailure() { - ICoseSigningKeyProvider coseSigningKeyProvider = SetupMockSigningKeyProvider(); + ICoseSigningKeyProvider coseSigningKeyProvider = TestCertificateUtils.SetupMockSigningKeyProvider(); IndirectSignatureFactory factory = new(); byte[] randomBytes = new byte[50]; byte[] randomBytes2 = new byte[50]; @@ -156,7 +156,7 @@ public void TestSignatureMatchesStreamFailure() [Test] public void TestSignatureMatchesBytesSuccess() { - ICoseSigningKeyProvider coseSigningKeyProvider = SetupMockSigningKeyProvider(); + ICoseSigningKeyProvider coseSigningKeyProvider = TestCertificateUtils.SetupMockSigningKeyProvider(); IndirectSignatureFactory factory = new(); byte[] randomBytes = new byte[50]; new Random().NextBytes(randomBytes); @@ -168,7 +168,7 @@ public void TestSignatureMatchesBytesSuccess() [Test] public void TestSignatureMatchesBytesFailure() { - ICoseSigningKeyProvider coseSigningKeyProvider = SetupMockSigningKeyProvider(); + ICoseSigningKeyProvider coseSigningKeyProvider = TestCertificateUtils.SetupMockSigningKeyProvider(); IndirectSignatureFactory factory = new(); byte[] randomBytes = new byte[50]; byte[] randomBytes2 = new byte[50]; @@ -191,7 +191,7 @@ public void TestSignatureMatchesBytesFailure() [Test] public void TestTryGetHashAlgorithmSuccess() { - ICoseSigningKeyProvider coseSigningKeyProvider = SetupMockSigningKeyProvider(); + ICoseSigningKeyProvider coseSigningKeyProvider = TestCertificateUtils.SetupMockSigningKeyProvider(); IndirectSignatureFactory factory = new(); byte[] randomBytes = new byte[50]; new Random().NextBytes(randomBytes); @@ -215,7 +215,7 @@ public void TestTryGetHashAlgorithmSuccess() [TestCase(8, Description = "TryGet - Null")] public void TestGetCoseHashVScenarios(int testCase) { - ICoseSigningKeyProvider coseSigningKeyProvider = SetupMockSigningKeyProvider(); + ICoseSigningKeyProvider coseSigningKeyProvider = TestCertificateUtils.SetupMockSigningKeyProvider(); IndirectSignatureFactory signaturefactory = new(); CoseSign1MessageFactory messageFactory = new(); byte[] randomBytes = new byte[50]; @@ -279,7 +279,7 @@ public void TestGetCoseHashVScenarios(int testCase) [Test] public void TestTryGetHashAlgorithmFailure() { - ICoseSigningKeyProvider coseSigningKeyProvider = SetupMockSigningKeyProvider(); + ICoseSigningKeyProvider coseSigningKeyProvider = TestCertificateUtils.SetupMockSigningKeyProvider(); IndirectSignatureFactory factory = new(); byte[] randomBytes = new byte[50]; byte[] randomBytes2 = new byte[50]; @@ -307,24 +307,4 @@ public void TestTryGetHashAlgorithmFailure() CoseSign1MessageIndirectSignatureExtensions.TryGetHashAlgorithm(IndirectSignature, out hashAlgorithm).Should().BeFalse(); hashAlgorithm.Should().BeNull(); } - - private static ICoseSigningKeyProvider SetupMockSigningKeyProvider([CallerMemberName] string testName = "none") - { - Mock mockedSignerKeyProvider = new(MockBehavior.Strict); - X509Certificate2 selfSignedCertWithRSA = TestCertificateUtils.CreateCertificate(testName); - - mockedSignerKeyProvider.Setup(x => x.GetProtectedHeaders()).Returns(null); - mockedSignerKeyProvider.Setup(x => x.GetUnProtectedHeaders()).Returns(null); - mockedSignerKeyProvider.Setup(x => x.HashAlgorithm).Returns(HashAlgorithmName.SHA256); - mockedSignerKeyProvider.Setup(x => x.GetECDsaKey(It.IsAny())).Returns(null); - mockedSignerKeyProvider.Setup(x => x.GetRSAKey(It.IsAny())).Returns(selfSignedCertWithRSA.GetRSAPrivateKey()); - mockedSignerKeyProvider.Setup(x => x.IsRSA).Returns(true); - - // Setup KeyChain property to return the public key from the certificate - RSA? publicKey = selfSignedCertWithRSA.GetRSAPublicKey(); - System.Collections.ObjectModel.ReadOnlyCollection keyChain = publicKey != null ? new List { publicKey }.AsReadOnly() : new List().AsReadOnly(); - mockedSignerKeyProvider.Setup(x => x.KeyChain).Returns(keyChain); - - return mockedSignerKeyProvider.Object; - } } diff --git a/CoseIndirectSignature.Tests/IndirectSignatureFactoryTests.cs b/CoseIndirectSignature.Tests/IndirectSignatureFactoryTests.cs index 339d8d69..66a10198 100644 --- a/CoseIndirectSignature.Tests/IndirectSignatureFactoryTests.cs +++ b/CoseIndirectSignature.Tests/IndirectSignatureFactoryTests.cs @@ -53,7 +53,7 @@ public void TestConstructors() [Test] public async Task TestCreateIndirectSignatureAsync() { - ICoseSigningKeyProvider coseSigningKeyProvider = TestUtils.SetupMockSigningKeyProvider(); + ICoseSigningKeyProvider coseSigningKeyProvider = TestCertificateUtils.SetupMockSigningKeyProvider(); using IndirectSignatureFactory factory = new(); byte[] randomBytes = new byte[50]; new Random().NextBytes(randomBytes); @@ -150,7 +150,7 @@ public async Task TestCreateIndirectSignatureAsync() [Test] public async Task TestCreateIndirectSignatureHashProvidedAsync() { - ICoseSigningKeyProvider coseSigningKeyProvider = TestUtils.SetupMockSigningKeyProvider(); + ICoseSigningKeyProvider coseSigningKeyProvider = TestCertificateUtils.SetupMockSigningKeyProvider(); using IndirectSignatureFactory factory = new(); byte[] randomBytes = new byte[50]; new Random().NextBytes(randomBytes); @@ -240,7 +240,7 @@ public async Task TestCreateIndirectSignatureHashProvidedAsync() [Test] public async Task TestCreateIndirectSignatureBytesAsync() { - ICoseSigningKeyProvider coseSigningKeyProvider = TestUtils.SetupMockSigningKeyProvider(); + ICoseSigningKeyProvider coseSigningKeyProvider = TestCertificateUtils.SetupMockSigningKeyProvider(); using IndirectSignatureFactory factory = new(); byte[] randomBytes = new byte[50]; new Random().NextBytes(randomBytes); @@ -326,7 +326,7 @@ public async Task TestCreateIndirectSignatureBytesAsync() [Test] public async Task TestCreateIndirectSignatureBytesHashProvidedAsync() { - ICoseSigningKeyProvider coseSigningKeyProvider = TestUtils.SetupMockSigningKeyProvider(); + ICoseSigningKeyProvider coseSigningKeyProvider = TestCertificateUtils.SetupMockSigningKeyProvider(); using IndirectSignatureFactory factory = new(); byte[] randomBytes = new byte[50]; new Random().NextBytes(randomBytes); @@ -422,7 +422,7 @@ public void TestCreateIndirectSignatureUnsupportedAlgorithmFailure() [Test] public void TestCreateIndirectSignatureAlreadyProvided() { - ICoseSigningKeyProvider coseSigningKeyProvider = TestUtils.SetupMockSigningKeyProvider(); + ICoseSigningKeyProvider coseSigningKeyProvider = TestCertificateUtils.SetupMockSigningKeyProvider(); using IndirectSignatureFactory factory = new(); byte[] randomBytes = new byte[50]; new Random().NextBytes(randomBytes); diff --git a/CoseIndirectSignature.Tests/TestUtils.cs b/CoseIndirectSignature.Tests/TestUtils.cs deleted file mode 100644 index f1f8847f..00000000 --- a/CoseIndirectSignature.Tests/TestUtils.cs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -namespace CoseIndirectSignature.Tests; - -/// -/// Test utility methods. -/// -public static class TestUtils -{ - /// - /// Sets up a mock signing key provider for testing purposes. - /// - /// The name of the test, defaults to the calling member. - /// A which uses a self-signed certificate for signing operations. - public static ICoseSigningKeyProvider SetupMockSigningKeyProvider([CallerMemberName] string testName = "none") - { - Mock mockedSignerKeyProvider = new(MockBehavior.Strict); - X509Certificate2 selfSignedCertWithRSA = TestCertificateUtils.CreateCertificate(testName); - - mockedSignerKeyProvider.Setup(x => x.GetProtectedHeaders()).Returns(null); - mockedSignerKeyProvider.Setup(x => x.GetUnProtectedHeaders()).Returns(null); - mockedSignerKeyProvider.Setup(x => x.HashAlgorithm).Returns(HashAlgorithmName.SHA256); - mockedSignerKeyProvider.Setup(x => x.GetECDsaKey(It.IsAny())).Returns(null); - mockedSignerKeyProvider.Setup(x => x.GetRSAKey(It.IsAny())).Returns(selfSignedCertWithRSA.GetRSAPrivateKey()); - mockedSignerKeyProvider.Setup(x => x.IsRSA).Returns(true); - - // Setup KeyChain property to return the public key from the certificate - RSA? publicKey = selfSignedCertWithRSA.GetRSAPublicKey(); - System.Collections.ObjectModel.ReadOnlyCollection keyChain = publicKey != null ? new List { publicKey }.AsReadOnly() : new List().AsReadOnly(); - mockedSignerKeyProvider.Setup(x => x.KeyChain).Returns(keyChain); - - return mockedSignerKeyProvider.Object; - } -} diff --git a/CoseSign1.Abstractions/CoseKeyType.cs b/CoseSign1.Abstractions/CoseKeyType.cs new file mode 100644 index 00000000..74e2db68 --- /dev/null +++ b/CoseSign1.Abstractions/CoseKeyType.cs @@ -0,0 +1,11 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +namespace CoseSign1.Abstractions; + +public enum CoseKeyType +{ + RSA, + ECDsa, + MLDsa, +} diff --git a/CoseSign1.Abstractions/Interfaces/ICoseSigningKeyProvider.cs b/CoseSign1.Abstractions/Interfaces/ICoseSigningKeyProvider.cs index 9929b95f..f36f0b21 100644 --- a/CoseSign1.Abstractions/Interfaces/ICoseSigningKeyProvider.cs +++ b/CoseSign1.Abstractions/Interfaces/ICoseSigningKeyProvider.cs @@ -11,24 +11,33 @@ public interface ICoseSigningKeyProvider /// /// Returns true if the signing key is RSA, false if the signing key is ECDsa. /// - public bool IsRSA { get; } + //public bool IsRSA { get; } /// /// The hashing algorithm to use /// - public HashAlgorithmName HashAlgorithm { get; } + //public HashAlgorithmName HashAlgorithm { get; } /// /// Gets RSA Key used for signing or verification operations. /// /// RSA Key if present, else returns null - public RSA? GetRSAKey(bool publicKey = false); + //public RSA? GetRSAKey(bool publicKey = false); /// /// Gets ECDsa Key used for signing or verification operations. /// /// /// ECDsa Key if present, else returns null - public ECDsa? GetECDsaKey(bool publicKey = false); + //public ECDsa? GetECDsaKey(bool publicKey = false); + + /// + /// Retrieves the MLDSA key associated with the current instance. + /// + /// true to return only the public portion of the key; false to return the full key if available. + /// An MLDsa object representing the DSA key, or null if no key is available. + //public MLDsa? GetMLDsaKey(bool publicKey = false); + + public CoseKey? GetCoseKey(bool publicKey = false); /// /// Gets the key chain representing the parents (in bottom-up order) of the RSA or ECDsa key. @@ -36,7 +45,7 @@ public interface ICoseSigningKeyProvider /// and subsequent elements represent the parent keys up the chain. /// /// List of AsymmetricAlgorithm representing the key chain, or empty list if no chain is available - public IReadOnlyList KeyChain { get; } + //public IReadOnlyList KeyChain { get; } /// /// Returns the Protected Headers diff --git a/CoseSign1.Certificates.Tests/CertificateCoseSigningKeyProviderTests.cs b/CoseSign1.Certificates.Tests/CertificateCoseSigningKeyProviderTests.cs index dde7bd8d..5d3725af 100644 --- a/CoseSign1.Certificates.Tests/CertificateCoseSigningKeyProviderTests.cs +++ b/CoseSign1.Certificates.Tests/CertificateCoseSigningKeyProviderTests.cs @@ -28,63 +28,65 @@ public void TestConstructorsSuccess() } } - /// - /// Testing HashAlgorithm Set to Default - /// - [Test] - public void TestDefaultHashAlgorithm() - { - TestCertificateCoseSigningKeyProvider testObj = new TestCertificateCoseSigningKeyProvider(); - testObj.HashAlgorithm.Should().Be(HashAlgorithmName.SHA256); - } - /// - /// Tests Setting Custom HashAlgorithm - /// - [Test] - public void TestSetCustomHashAlgorithm() - { - TestCertificateCoseSigningKeyProvider testObj = new TestCertificateCoseSigningKeyProvider(HashAlgorithmName.SHA512); - testObj.HashAlgorithm.Should().Be(HashAlgorithmName.SHA512); - } + // TODO: Do we need this? + ///// + ///// Testing HashAlgorithm Set to Default + ///// + //[Test] + //public void TestDefaultHashAlgorithm() + //{ + // TestCertificateCoseSigningKeyProvider testObj = new TestCertificateCoseSigningKeyProvider(); + // testObj.HashAlgorithm.Should().Be(HashAlgorithmName.SHA256); + //} + + ///// + ///// Tests Setting Custom HashAlgorithm + ///// + //[Test] + //public void TestSetCustomHashAlgorithm() + //{ + // TestCertificateCoseSigningKeyProvider testObj = new TestCertificateCoseSigningKeyProvider(HashAlgorithmName.SHA512); + // testObj.HashAlgorithm.Should().Be(HashAlgorithmName.SHA512); + //} // TODO: This class might not need to mock /// /// Testing GetRsaKey and IsRSA When RSA key is provided /// - [Test] - public void TestGetRSAKeyMethodWhenRSAExists() - { - X509Certificate2 testCert = TestCertificateUtils.CreateCertificate(); - Mock testObj = new(MockBehavior.Strict) - { - CallBase = true - }; - - testObj.Protected().Setup("ProvideRSAKey", ItExpr.IsAny()) - .Returns(testCert?.GetRSAPrivateKey() ?? throw new ArgumentNullException()) - .Verifiable(); - testObj.Object.GetRSAKey(); - - testObj.Protected().Verify("ProvideRSAKey", Times.Once(), ItExpr.IsAny()); - testObj.Object.IsRSA.Should().BeTrue(); - } - - /// - /// Testing GetRSAKey and IsRSA When RSA key is null - /// - [Test] - public void TestWhenRSAIsNull() - { - Mock testObj = new(MockBehavior.Strict) - { - CallBase = true - }; - - testObj.Protected().Setup("ProvideRSAKey", ItExpr.IsAny()).Returns(null).Verifiable(); - testObj.Object.GetRSAKey(); - testObj.Object.IsRSA.Should().BeFalse(); - } + //[Test] + //public void TestGetRSAKeyMethodWhenRSAExists() + //{ + // X509Certificate2 testCert = TestCertificateUtils.CreateCertificate(); + // Mock testObj = new(MockBehavior.Strict) + // { + // CallBase = true + // }; + + // testObj.Protected().Setup("ProvideRSAKey", ItExpr.IsAny()) + // .Returns(testCert?.GetRSAPrivateKey() ?? throw new ArgumentNullException()) + // .Verifiable(); + // testObj.Object.GetRSAKey(); + + // testObj.Protected().Verify("ProvideRSAKey", Times.Once(), ItExpr.IsAny()); + // testObj.Object.IsRSA.Should().BeTrue(); + //} + + ///// + ///// Testing GetRSAKey and IsRSA When RSA key is null + ///// + //[Test] + //public void TestWhenRSAIsNull() + //{ + // Mock testObj = new(MockBehavior.Strict) + // { + // CallBase = true + // }; + + // testObj.Protected().Setup("ProvideRSAKey", ItExpr.IsAny()).Returns(null).Verifiable(); + // testObj.Object.GetRSAKey(); + // testObj.Object.IsRSA.Should().BeFalse(); + //} /// /// Testing GetECDsaKey @@ -183,172 +185,172 @@ public void TestGetUnProtectedHeadersImplementation() testMockObj.TestGetUnProtectedHeadersImplementation().Should().BeNull(); } - /// - /// Testing KeyChain property returns empty list when GetCertificateChain throws - /// - [Test] - public void TestKeyChainWhenCertificateChainThrows() - { - TestCertificateCoseSigningKeyProvider testObj = new(); + ///// + ///// Testing KeyChain property returns empty list when GetCertificateChain throws + ///// + //[Test] + //public void TestKeyChainWhenCertificateChainThrows() + //{ + // TestCertificateCoseSigningKeyProvider testObj = new(); - // Since TestCertificateCoseSigningKeyProvider.GetCertificateChain throws NotImplementedException, - // KeyChain should return empty list - IReadOnlyList keyChain = testObj.KeyChain; + // // Since TestCertificateCoseSigningKeyProvider.GetCertificateChain throws NotImplementedException, + // // KeyChain should return empty list + // IReadOnlyList keyChain = testObj.KeyChain; - keyChain.Should().NotBeNull(); - keyChain.Should().BeEmpty(); - } + // keyChain.Should().NotBeNull(); + // keyChain.Should().BeEmpty(); + //} /// /// Testing KeyChain property returns keys from certificate chain /// - [Test] - public void TestKeyChainWithValidCertificateChain() - { - X509Certificate2Collection testChain = TestCertificateUtils.CreateTestChain(leafFirst: true); - X509Certificate2 testCert = testChain[0]; - - Mock testObj = new(MockBehavior.Strict) - { - CallBase = true - }; - - testObj.Protected().Setup("GetSigningCertificate").Returns(testCert); - testObj.Protected().Setup>("GetCertificateChain", ItExpr.IsAny()) - .Returns(testChain.Cast()); - - // Setup KeyChain property to avoid strict mock issues - List expectedKeys = testChain.Cast() - .Select(cert => cert.GetRSAPublicKey() as AsymmetricAlgorithm ?? cert.GetECDsaPublicKey()) - .Where(key => key != null) - .ToList(); - testObj.SetupGet(x => x.KeyChain).Returns(expectedKeys!); - - IReadOnlyList keyChain = testObj.Object.KeyChain; - - keyChain.Should().NotBeNull(); - keyChain.Count.Should().Be(testChain.Count); + //[Test] + //public void TestKeyChainWithValidCertificateChain() + //{ + // X509Certificate2Collection testChain = TestCertificateUtils.CreateTestChain(leafFirst: true); + // X509Certificate2 testCert = testChain[0]; + + // Mock testObj = new(MockBehavior.Strict) + // { + // CallBase = true + // }; + + // testObj.Protected().Setup("GetSigningCertificate").Returns(testCert); + // testObj.Protected().Setup>("GetCertificateChain", ItExpr.IsAny()) + // .Returns(testChain.Cast()); + + // // Setup KeyChain property to avoid strict mock issues + // List expectedKeys = testChain.Cast() + // .Select(cert => cert.GetRSAPublicKey() as AsymmetricAlgorithm ?? cert.GetECDsaPublicKey()) + // .Where(key => key != null) + // .ToList(); + // testObj.SetupGet(x => x.KeyChain).Returns(expectedKeys!); + + // IReadOnlyList keyChain = testObj.Object.KeyChain; + + // keyChain.Should().NotBeNull(); + // keyChain.Count.Should().Be(testChain.Count); - // Verify that each key in the chain corresponds to a certificate - for (int i = 0; i < testChain.Count; i++) - { - X509Certificate2 cert = testChain[i]; - AsymmetricAlgorithm? expectedKey = cert.GetRSAPublicKey() as AsymmetricAlgorithm ?? cert.GetECDsaPublicKey(); + // // Verify that each key in the chain corresponds to a certificate + // for (int i = 0; i < testChain.Count; i++) + // { + // X509Certificate2 cert = testChain[i]; + // AsymmetricAlgorithm? expectedKey = cert.GetRSAPublicKey() as AsymmetricAlgorithm ?? cert.GetECDsaPublicKey(); - keyChain[i].Should().NotBeNull(); - // Verify key type matches - if (expectedKey is RSA) - { - keyChain[i].Should().BeAssignableTo(); - } - else if (expectedKey is ECDsa) - { - keyChain[i].Should().BeAssignableTo(); - } - } - } + // keyChain[i].Should().NotBeNull(); + // // Verify key type matches + // if (expectedKey is RSA) + // { + // keyChain[i].Should().BeAssignableTo(); + // } + // else if (expectedKey is ECDsa) + // { + // keyChain[i].Should().BeAssignableTo(); + // } + // } + //} /// /// Testing KeyChain property with ECC certificates /// - [Test] - public void TestKeyChainWithEccCertificates() - { - // Create ECC certificates - X509Certificate2 leafCert = TestCertificateUtils.CreateCertificate("TestLeaf", useEcc: true); - X509Certificate2 rootCert = TestCertificateUtils.CreateCertificate("TestRoot", useEcc: true); + //[Test] + //public void TestKeyChainWithEccCertificates() + //{ + // // Create ECC certificates + // X509Certificate2 leafCert = TestCertificateUtils.CreateCertificate("TestLeaf", useEcc: true); + // X509Certificate2 rootCert = TestCertificateUtils.CreateCertificate("TestRoot", useEcc: true); - Mock testObj = new(MockBehavior.Strict) - { - CallBase = true - }; - - testObj.Protected().Setup("GetSigningCertificate").Returns(leafCert); - testObj.Protected().Setup>("GetCertificateChain", ItExpr.IsAny()) - .Returns(new[] { leafCert, rootCert }); - - // Setup KeyChain property to avoid strict mock issues - AsymmetricAlgorithm[] expectedKeys = new AsymmetricAlgorithm[] { leafCert.GetECDsaPublicKey()!, rootCert.GetECDsaPublicKey()! }; - testObj.SetupGet(x => x.KeyChain).Returns(expectedKeys); - - IReadOnlyList keyChain = testObj.Object.KeyChain; - - keyChain.Should().NotBeNull(); - keyChain.Count.Should().Be(2); - keyChain[0].Should().BeAssignableTo(); - keyChain[1].Should().BeAssignableTo(); - } - - /// - /// Testing KeyChain property with mixed RSA and ECC certificates - /// - [Test] - public void TestKeyChainWithMixedKeyTypes() - { - // Create mixed certificate types - X509Certificate2 rsaCert = TestCertificateUtils.CreateCertificate("TestRSA", useEcc: false); - X509Certificate2 eccCert = TestCertificateUtils.CreateCertificate("TestECC", useEcc: true); + // Mock testObj = new(MockBehavior.Strict) + // { + // CallBase = true + // }; + + // testObj.Protected().Setup("GetSigningCertificate").Returns(leafCert); + // testObj.Protected().Setup>("GetCertificateChain", ItExpr.IsAny()) + // .Returns(new[] { leafCert, rootCert }); + + // // Setup KeyChain property to avoid strict mock issues + // AsymmetricAlgorithm[] expectedKeys = new AsymmetricAlgorithm[] { leafCert.GetECDsaPublicKey()!, rootCert.GetECDsaPublicKey()! }; + // testObj.SetupGet(x => x.KeyChain).Returns(expectedKeys); + + // IReadOnlyList keyChain = testObj.Object.KeyChain; + + // keyChain.Should().NotBeNull(); + // keyChain.Count.Should().Be(2); + // keyChain[0].Should().BeAssignableTo(); + // keyChain[1].Should().BeAssignableTo(); + //} + + ///// + ///// Testing KeyChain property with mixed RSA and ECC certificates + ///// + //[Test] + //public void TestKeyChainWithMixedKeyTypes() + //{ + // // Create mixed certificate types + // X509Certificate2 rsaCert = TestCertificateUtils.CreateCertificate("TestRSA", useEcc: false); + // X509Certificate2 eccCert = TestCertificateUtils.CreateCertificate("TestECC", useEcc: true); - Mock testObj = new(MockBehavior.Strict) - { - CallBase = true - }; - - testObj.Protected().Setup("GetSigningCertificate").Returns(rsaCert); - testObj.Protected().Setup>("GetCertificateChain", ItExpr.IsAny()) - .Returns(new[] { rsaCert, eccCert }); - - // Setup KeyChain property to avoid strict mock issues - AsymmetricAlgorithm[] expectedKeys = new AsymmetricAlgorithm[] { rsaCert.GetRSAPublicKey()!, eccCert.GetECDsaPublicKey()! }; - testObj.SetupGet(x => x.KeyChain).Returns(expectedKeys); - - IReadOnlyList keyChain = testObj.Object.KeyChain; - - keyChain.Should().NotBeNull(); - keyChain.Count.Should().Be(2); - keyChain[0].Should().BeAssignableTo(); - keyChain[1].Should().BeAssignableTo(); - } - - /// - /// Testing KeyChain property when certificate has no extractable public key - /// - [Test] - public void TestKeyChainWithCertificateWithoutExtractableKey() - { - // Create a test class that returns empty certificate chain - Mock testObj = new(MockBehavior.Strict) - { - CallBase = true - }; - - // Mock a certificate that doesn't have extractable keys by returning empty chain - testObj.Protected().Setup("GetSigningCertificate").Returns(TestCertificateUtils.CreateCertificate()); - testObj.Protected().Setup>("GetCertificateChain", ItExpr.IsAny()) - .Returns(new X509Certificate2[0]); // Empty chain - - // Setup KeyChain property to return empty list for empty chain - testObj.SetupGet(x => x.KeyChain).Returns(new List()); - - IReadOnlyList keyChain = testObj.Object.KeyChain; - - keyChain.Should().NotBeNull(); - keyChain.Should().BeEmpty(); // No extractable keys from empty chain - } + // Mock testObj = new(MockBehavior.Strict) + // { + // CallBase = true + // }; + + // testObj.Protected().Setup("GetSigningCertificate").Returns(rsaCert); + // testObj.Protected().Setup>("GetCertificateChain", ItExpr.IsAny()) + // .Returns(new[] { rsaCert, eccCert }); + + // // Setup KeyChain property to avoid strict mock issues + // AsymmetricAlgorithm[] expectedKeys = new AsymmetricAlgorithm[] { rsaCert.GetRSAPublicKey()!, eccCert.GetECDsaPublicKey()! }; + // testObj.SetupGet(x => x.KeyChain).Returns(expectedKeys); + + // IReadOnlyList keyChain = testObj.Object.KeyChain; + + // keyChain.Should().NotBeNull(); + // keyChain.Count.Should().Be(2); + // keyChain[0].Should().BeAssignableTo(); + // keyChain[1].Should().BeAssignableTo(); + //} + + ///// + ///// Testing KeyChain property when certificate has no extractable public key + ///// + //[Test] + //public void TestKeyChainWithCertificateWithoutExtractableKey() + //{ + // // Create a test class that returns empty certificate chain + // Mock testObj = new(MockBehavior.Strict) + // { + // CallBase = true + // }; + + // // Mock a certificate that doesn't have extractable keys by returning empty chain + // testObj.Protected().Setup("GetSigningCertificate").Returns(TestCertificateUtils.CreateCertificate()); + // testObj.Protected().Setup>("GetCertificateChain", ItExpr.IsAny()) + // .Returns(new X509Certificate2[0]); // Empty chain + + // // Setup KeyChain property to return empty list for empty chain + // testObj.SetupGet(x => x.KeyChain).Returns(new List()); + + // IReadOnlyList keyChain = testObj.Object.KeyChain; + + // keyChain.Should().NotBeNull(); + // keyChain.Should().BeEmpty(); // No extractable keys from empty chain + //} /// /// Testing GetKeyChain protected method directly /// - [Test] - public void TestGetKeyChainProtectedMethod() - { - TestCertificateCoseSigningKeyProvider testObj = new(); + //[Test] + //public void TestGetKeyChainProtectedMethod() + //{ + // TestCertificateCoseSigningKeyProvider testObj = new(); - // This should return empty list since GetCertificateChain throws - IReadOnlyList keyChain = testObj.TestGetKeyChain(); + // // This should return empty list since GetCertificateChain throws + // IReadOnlyList keyChain = testObj.TestGetKeyChain(); - keyChain.Should().NotBeNull(); - keyChain.Should().BeEmpty(); - } + // keyChain.Should().NotBeNull(); + // keyChain.Should().BeEmpty(); + //} } \ No newline at end of file diff --git a/CoseSign1.Certificates.Tests/CoseSign1.Certificates.Tests.csproj b/CoseSign1.Certificates.Tests/CoseSign1.Certificates.Tests.csproj index 95bf5d23..9f86d14e 100644 --- a/CoseSign1.Certificates.Tests/CoseSign1.Certificates.Tests.csproj +++ b/CoseSign1.Certificates.Tests/CoseSign1.Certificates.Tests.csproj @@ -2,7 +2,7 @@ Exe - net8.0 + net10.0 enable false false diff --git a/CoseSign1.Certificates.Tests/TestCertificateCoseSigningKeyProvider.cs b/CoseSign1.Certificates.Tests/TestCertificateCoseSigningKeyProvider.cs index c9500115..dad13a1a 100644 --- a/CoseSign1.Certificates.Tests/TestCertificateCoseSigningKeyProvider.cs +++ b/CoseSign1.Certificates.Tests/TestCertificateCoseSigningKeyProvider.cs @@ -14,7 +14,7 @@ public TestCertificateCoseSigningKeyProvider(HashAlgorithmName? hashAlgorithm = public CoseHeaderMap? TestGetUnProtectedHeadersImplementation() => base.GetUnProtectedHeadersImplementation(); - public IReadOnlyList TestGetKeyChain() => base.GetKeyChain(); + //public IReadOnlyList TestGetKeyChain() => base.GetKeyChain(); protected override IEnumerable GetCertificateChain(X509ChainSortOrder sortOrder) { diff --git a/CoseSign1.Certificates.Tests/X509Certificate2SigningKeyProviderTests.cs b/CoseSign1.Certificates.Tests/X509Certificate2SigningKeyProviderTests.cs index e25d81fa..a2b845c6 100644 --- a/CoseSign1.Certificates.Tests/X509Certificate2SigningKeyProviderTests.cs +++ b/CoseSign1.Certificates.Tests/X509Certificate2SigningKeyProviderTests.cs @@ -148,143 +148,143 @@ public void GetCertificateChainShouldReturnException() exceptionText.Message.Should().MatchRegex(":Build is not successful for the provided SigningCertificate:"); } - /// - /// Testing KeyChain property with self-signed certificate - /// - [Test] - public void KeyChainShouldReturnSingleKeyForSelfSignedCert() - { - // Setup - X509Certificate2 testCert = TestCertificateUtils.CreateCertificate(); - X509Certificate2CoseSigningKeyProvider testObj = new(testCert); - - // Test - IReadOnlyList keyChain = testObj.KeyChain; - - // Validate - keyChain.Should().NotBeNull(); - keyChain.Count.Should().Be(1); - keyChain[0].Should().BeAssignableTo(); - } - - /// - /// Testing KeyChain property with certificate chain - /// - [Test] - public void KeyChainShouldReturnAllKeysInChain() - { - // Setup - X509Certificate2Collection testChain = TestCertificateUtils.CreateTestChain(); - Mock testChainBuilder = new(); - testChainBuilder.Setup(x => x.ChainElements).Returns(new List(testChain)); - testChainBuilder.Setup(x => x.Build(It.IsAny())).Returns(true); - - X509Certificate2CoseSigningKeyProvider testObj = new(testChainBuilder.Object, testChain[2]); // Use leaf certificate - - // Test - IReadOnlyList keyChain = testObj.KeyChain; - - // Validate - keyChain.Should().NotBeNull(); - keyChain.Count.Should().Be(testChain.Count); + ///// + ///// Testing KeyChain property with self-signed certificate + ///// + //[Test] + //public void KeyChainShouldReturnSingleKeyForSelfSignedCert() + //{ + // // Setup + // X509Certificate2 testCert = TestCertificateUtils.CreateCertificate(); + // X509Certificate2CoseSigningKeyProvider testObj = new(testCert); + + // // Test + // IReadOnlyList keyChain = testObj.KeyChain; + + // // Validate + // keyChain.Should().NotBeNull(); + // keyChain.Count.Should().Be(1); + // keyChain[0].Should().BeAssignableTo(); + //} + + ///// + ///// Testing KeyChain property with certificate chain + ///// + //[Test] + //public void KeyChainShouldReturnAllKeysInChain() + //{ + // // Setup + // X509Certificate2Collection testChain = TestCertificateUtils.CreateTestChain(); + // Mock testChainBuilder = new(); + // testChainBuilder.Setup(x => x.ChainElements).Returns(new List(testChain)); + // testChainBuilder.Setup(x => x.Build(It.IsAny())).Returns(true); + + // X509Certificate2CoseSigningKeyProvider testObj = new(testChainBuilder.Object, testChain[2]); // Use leaf certificate + + // // Test + // IReadOnlyList keyChain = testObj.KeyChain; + + // // Validate + // keyChain.Should().NotBeNull(); + // keyChain.Count.Should().Be(testChain.Count); - // All keys should be RSA since test chain uses RSA certificates - foreach (AsymmetricAlgorithm key in keyChain) - { - key.Should().BeAssignableTo(); - } - } - - /// - /// Testing KeyChain property with ECC certificate - /// - [Test] - public void KeyChainShouldReturnEccKeyForEccCert() - { - // Setup - X509Certificate2 testCert = TestCertificateUtils.CreateCertificate(useEcc: true); - X509Certificate2CoseSigningKeyProvider testObj = new(testCert); - - // Test - IReadOnlyList keyChain = testObj.KeyChain; - - // Validate - keyChain.Should().NotBeNull(); - keyChain.Count.Should().Be(1); - keyChain[0].Should().BeAssignableTo(); - } - - /// - /// Testing KeyChain property when chain building fails - /// - [Test] - public void KeyChainShouldReturnEmptyListWhenChainBuildingFails() - { - // Setup - X509Certificate2Collection testChain = TestCertificateUtils.CreateTestChain(); - Mock mockBuilder = new(MockBehavior.Strict); - mockBuilder.Setup(m => m.Build(It.IsAny())).Returns(false); - mockBuilder.Setup(m => m.ChainElements).Returns([.. testChain]); - mockBuilder.Setup(m => m.ChainPolicy).Returns(new X509ChainPolicy()); - mockBuilder.Setup(m => m.ChainStatus).Returns([new X509ChainStatus()]); + // // All keys should be RSA since test chain uses RSA certificates + // foreach (AsymmetricAlgorithm key in keyChain) + // { + // key.Should().BeAssignableTo(); + // } + //} + + ///// + ///// Testing KeyChain property with ECC certificate + ///// + //[Test] + //public void KeyChainShouldReturnEccKeyForEccCert() + //{ + // // Setup + // X509Certificate2 testCert = TestCertificateUtils.CreateCertificate(useEcc: true); + // X509Certificate2CoseSigningKeyProvider testObj = new(testCert); + + // // Test + // IReadOnlyList keyChain = testObj.KeyChain; + + // // Validate + // keyChain.Should().NotBeNull(); + // keyChain.Count.Should().Be(1); + // keyChain[0].Should().BeAssignableTo(); + //} + + ///// + ///// Testing KeyChain property when chain building fails + ///// + //[Test] + //public void KeyChainShouldReturnEmptyListWhenChainBuildingFails() + //{ + // // Setup + // X509Certificate2Collection testChain = TestCertificateUtils.CreateTestChain(); + // Mock mockBuilder = new(MockBehavior.Strict); + // mockBuilder.Setup(m => m.Build(It.IsAny())).Returns(false); + // mockBuilder.Setup(m => m.ChainElements).Returns([.. testChain]); + // mockBuilder.Setup(m => m.ChainPolicy).Returns(new X509ChainPolicy()); + // mockBuilder.Setup(m => m.ChainStatus).Returns([new X509ChainStatus()]); - X509Certificate2CoseSigningKeyProvider testObj = new(mockBuilder.Object, testChain.Last()); - - // Test - KeyChain should handle the exception gracefully - IReadOnlyList keyChain = testObj.KeyChain; - - // Validate - keyChain.Should().NotBeNull(); - keyChain.Should().BeEmpty(); - } - - /// - /// Testing that KeyChain matches GetRSAKey result for RSA certificates - /// - [Test] - public void KeyChainFirstElementShouldMatchGetRSAKeyForRsaCert() - { - // Setup - X509Certificate2 testCert = TestCertificateUtils.CreateCertificate(); - X509Certificate2CoseSigningKeyProvider testObj = new(testCert); - - // Test - IReadOnlyList keyChain = testObj.KeyChain; - RSA? rsaKey = testObj.GetRSAKey(publicKey: true); - - // Validate - keyChain.Should().NotBeNull(); - keyChain.Count.Should().Be(1); - rsaKey.Should().NotBeNull(); - keyChain[0].Should().BeAssignableTo(); - - // Both should represent the same public key - RSA chainRsaKey = (RSA)keyChain[0]; - chainRsaKey.KeySize.Should().Be(rsaKey!.KeySize); - } - - /// - /// Testing that KeyChain matches GetECDsaKey result for ECC certificates - /// - [Test] - public void KeyChainFirstElementShouldMatchGetECDsaKeyForEccCert() - { - // Setup - X509Certificate2 testCert = TestCertificateUtils.CreateCertificate(useEcc: true); - X509Certificate2CoseSigningKeyProvider testObj = new(testCert); - - // Test - IReadOnlyList keyChain = testObj.KeyChain; - ECDsa? ecdsaKey = testObj.GetECDsaKey(publicKey: true); - - // Validate - keyChain.Should().NotBeNull(); - keyChain.Count.Should().Be(1); - ecdsaKey.Should().NotBeNull(); - keyChain[0].Should().BeAssignableTo(); - - // Both should represent the same public key - ECDsa chainEcdsaKey = (ECDsa)keyChain[0]; - chainEcdsaKey.KeySize.Should().Be(ecdsaKey!.KeySize); - } + // X509Certificate2CoseSigningKeyProvider testObj = new(mockBuilder.Object, testChain.Last()); + + // // Test - KeyChain should handle the exception gracefully + // IReadOnlyList keyChain = testObj.KeyChain; + + // // Validate + // keyChain.Should().NotBeNull(); + // keyChain.Should().BeEmpty(); + //} + + ///// + ///// Testing that KeyChain matches GetRSAKey result for RSA certificates + ///// + //[Test] + //public void KeyChainFirstElementShouldMatchGetRSAKeyForRsaCert() + //{ + // // Setup + // X509Certificate2 testCert = TestCertificateUtils.CreateCertificate(); + // X509Certificate2CoseSigningKeyProvider testObj = new(testCert); + + // // Test + // IReadOnlyList keyChain = testObj.KeyChain; + // RSA? rsaKey = testObj.GetRSAKey(publicKey: true); + + // // Validate + // keyChain.Should().NotBeNull(); + // keyChain.Count.Should().Be(1); + // rsaKey.Should().NotBeNull(); + // keyChain[0].Should().BeAssignableTo(); + + // // Both should represent the same public key + // RSA chainRsaKey = (RSA)keyChain[0]; + // chainRsaKey.KeySize.Should().Be(rsaKey!.KeySize); + //} + + ///// + ///// Testing that KeyChain matches GetECDsaKey result for ECC certificates + ///// + //[Test] + //public void KeyChainFirstElementShouldMatchGetECDsaKeyForEccCert() + //{ + // // Setup + // X509Certificate2 testCert = TestCertificateUtils.CreateCertificate(useEcc: true); + // X509Certificate2CoseSigningKeyProvider testObj = new(testCert); + + // // Test + // IReadOnlyList keyChain = testObj.KeyChain; + // ECDsa? ecdsaKey = testObj.GetECDsaKey(publicKey: true); + + // // Validate + // keyChain.Should().NotBeNull(); + // keyChain.Count.Should().Be(1); + // ecdsaKey.Should().NotBeNull(); + // keyChain[0].Should().BeAssignableTo(); + + // // Both should represent the same public key + // ECDsa chainEcdsaKey = (ECDsa)keyChain[0]; + // chainEcdsaKey.KeySize.Should().Be(ecdsaKey!.KeySize); + //} } \ No newline at end of file diff --git a/CoseSign1.Certificates.Tests/X509ChainTrustValidatorTests.cs b/CoseSign1.Certificates.Tests/X509ChainTrustValidatorTests.cs index 6247d72c..7ce75be4 100644 --- a/CoseSign1.Certificates.Tests/X509ChainTrustValidatorTests.cs +++ b/CoseSign1.Certificates.Tests/X509ChainTrustValidatorTests.cs @@ -426,21 +426,11 @@ public void X509TrustValidatorBasicFailureCases() [Test] public void X509TrustValidatorValidatesNullCertificate() { - Mock mockedSignerKeyProvider = new(MockBehavior.Strict); + ICoseSigningKeyProvider mockedSignerKeyProvider = TestCertificateUtils.SetupMockSigningKeyProvider(); Mock mockBuilder = new(MockBehavior.Strict); ReadOnlyMemory testPayload = Encoding.ASCII.GetBytes("testPayload!"); - X509Certificate2 testCertRsa = TestCertificateUtils.CreateCertificate(); - - CoseHeaderMap protectedHeaders = new CoseHeaderMap(); - CoseHeaderMap unProtectedHeaders = new CoseHeaderMap(); - mockedSignerKeyProvider.Setup(x => x.GetProtectedHeaders()).Returns(protectedHeaders); - mockedSignerKeyProvider.Setup(x => x.GetUnProtectedHeaders()).Returns(unProtectedHeaders); - mockedSignerKeyProvider.Setup(x => x.HashAlgorithm).Returns(HashAlgorithmName.SHA256); - mockedSignerKeyProvider.Setup(x => x.GetECDsaKey(It.IsAny())).Returns(null); - mockedSignerKeyProvider.Setup(x => x.GetRSAKey(It.IsAny())).Returns(testCertRsa.GetRSAPrivateKey()); - mockedSignerKeyProvider.Setup(x => x.IsRSA).Returns(true); - - CoseSign1MessageBuilder coseSign1MessageBuilder = new(mockedSignerKeyProvider.Object); + + CoseSign1MessageBuilder coseSign1MessageBuilder = new(mockedSignerKeyProvider); CoseSign1Message message = coseSign1MessageBuilder.SetPayloadBytes(testPayload).Build() ?? throw new ArgumentNullException(); X509ChainTrustValidator testChainTrustValidator = new(mockBuilder.Object); diff --git a/CoseSign1.Certificates.Tests/X509CommonNameValidatorTests.cs b/CoseSign1.Certificates.Tests/X509CommonNameValidatorTests.cs index ffced47e..6f98f00f 100644 --- a/CoseSign1.Certificates.Tests/X509CommonNameValidatorTests.cs +++ b/CoseSign1.Certificates.Tests/X509CommonNameValidatorTests.cs @@ -132,19 +132,12 @@ public void X509CommonNameValidatorValidatesErrorPath() [Test] public void X509TrustValidatorValidatesNullCertificate() { - Mock mockedSignerKeyProvider = new(MockBehavior.Strict); + ICoseSigningKeyProvider mockedSignerKeyProvider = TestCertificateUtils.SetupMockSigningKeyProvider(); Mock mockBuilder = new(MockBehavior.Strict); ReadOnlyMemory testPayload = Encoding.ASCII.GetBytes("testPayload!"); X509Certificate2 testCertRSA = TestCertificateUtils.CreateCertificate(); - mockedSignerKeyProvider.Setup(x => x.GetProtectedHeaders()).Returns([]); - mockedSignerKeyProvider.Setup(x => x.GetUnProtectedHeaders()).Returns([]); - mockedSignerKeyProvider.Setup(x => x.HashAlgorithm).Returns(HashAlgorithmName.SHA256); - mockedSignerKeyProvider.Setup(x => x.GetECDsaKey(It.IsAny())).Returns(null); - mockedSignerKeyProvider.Setup(x => x.GetRSAKey(It.IsAny())).Returns(testCertRSA.GetRSAPrivateKey()); - mockedSignerKeyProvider.Setup(x => x.IsRSA).Returns(true); - - CoseSign1MessageBuilder coseSign1MessageBuilder = new(mockedSignerKeyProvider.Object); + CoseSign1MessageBuilder coseSign1MessageBuilder = new(mockedSignerKeyProvider); CoseSign1Message message = coseSign1MessageBuilder .SetPayloadBytes(testPayload) .SetContentType(ContentTypeConstants.Cose).Build(); diff --git a/CoseSign1.Certificates/CertificateCoseSigningKeyProvider.cs b/CoseSign1.Certificates/CertificateCoseSigningKeyProvider.cs index e39c791b..b34941b4 100644 --- a/CoseSign1.Certificates/CertificateCoseSigningKeyProvider.cs +++ b/CoseSign1.Certificates/CertificateCoseSigningKeyProvider.cs @@ -3,19 +3,21 @@ namespace CoseSign1.Certificates; +using System.Security.Cryptography.Cose; + /// /// Abstract class which contains common logic needed for all certificate based implementations. /// public abstract class CertificateCoseSigningKeyProvider : ICoseSigningKeyProvider { - /// - public HashAlgorithmName HashAlgorithm { get; } = HashAlgorithmName.SHA256; + ///// + //public HashAlgorithmName HashAlgorithm { get; } = HashAlgorithmName.SHA256; - /// - public bool IsRSA => GetRSAKey(true) != null; + ///// + //public bool IsRSA => GetRSAKey(true) != null; /// - public virtual IReadOnlyList KeyChain => GetKeyChain(); + //public virtual IReadOnlyList KeyChain => GetKeyChain(); /// /// An X509ChainBuilder instance to build the certificate chain. @@ -53,33 +55,33 @@ public abstract class CertificateCoseSigningKeyProvider : ICoseSigningKeyProvide /// Can be overridden by derived classes to provide custom key chain logic. /// /// List of AsymmetricAlgorithm representing the key chain - protected virtual IReadOnlyList GetKeyChain() - { - List keyChain = new(); + //protected virtual IReadOnlyList GetKeyChain() + //{ + // List keyChain = new(); - try - { - // Get the certificate chain in leaf-first order (bottom-up) - IEnumerable certChain = GetCertificateChain(X509ChainSortOrder.LeafFirst); + // try + // { + // // Get the certificate chain in leaf-first order (bottom-up) + // IEnumerable certChain = GetCertificateChain(X509ChainSortOrder.LeafFirst); - foreach (X509Certificate2 cert in certChain) - { - // Extract the public key from each certificate - AsymmetricAlgorithm? publicKey = cert.GetRSAPublicKey() as AsymmetricAlgorithm ?? cert.GetECDsaPublicKey(); - if (publicKey != null) - { - keyChain.Add(publicKey); - } - } - } - catch (Exception ex) when (ex is CoseSign1CertificateException || ex is ArgumentNullException) - { - // If certificate chain cannot be built, return empty list - // This allows graceful handling when chain building fails - } + // foreach (X509Certificate2 cert in certChain) + // { + // // Extract the public key from each certificate + // AsymmetricAlgorithm? publicKey = cert.GetRSAPublicKey() as AsymmetricAlgorithm ?? cert.GetECDsaPublicKey(); + // if (publicKey != null) + // { + // keyChain.Add(publicKey); + // } + // } + // } + // catch (Exception ex) when (ex is CoseSign1CertificateException || ex is ArgumentNullException) + // { + // // If certificate chain cannot be built, return empty list + // // This allows graceful handling when chain building fails + // } - return keyChain.AsReadOnly(); - } + // return keyChain.AsReadOnly(); + //} /// /// Virtual Method for UnProtectedHeaders so that it could be Overridden By Derived Class Instance @@ -98,7 +100,7 @@ protected CertificateCoseSigningKeyProvider() { } /// The used for the signing operation. public CertificateCoseSigningKeyProvider(HashAlgorithmName? hashAlgorithm = null) { - HashAlgorithm = hashAlgorithm ?? HashAlgorithm; + //HashAlgorithm = hashAlgorithm ?? HashAlgorithm; } /// @@ -110,7 +112,7 @@ public CertificateCoseSigningKeyProvider(HashAlgorithmName? hashAlgorithm = null public CertificateCoseSigningKeyProvider(ICertificateChainBuilder? certificateChainBuilder, HashAlgorithmName? hashAlgorithm = null, List? rootCertificates = null) { ChainBuilder = certificateChainBuilder ?? new X509ChainBuilder(); - HashAlgorithm = hashAlgorithm ?? HashAlgorithm; + //HashAlgorithm = hashAlgorithm ?? HashAlgorithm; if (rootCertificates?.Count > 0 is true) { ChainBuilder.ChainPolicy.ExtraStore.Clear(); @@ -179,5 +181,17 @@ public void AddRoots(List roots, bool append = false) roots.ForEach(c => store.Add(c)); } + + public CoseKey? GetCoseKey(bool publicKey = false) + { + X509Certificate2 cert = GetSigningCertificate(); + +#pragma warning disable SYSLIB5006 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. + return cert.GetRSAPrivateKey() is not null ? new CoseKey(cert.GetRSAPrivateKey(), RSASignaturePadding.Pkcs1, HashAlgorithmName.SHA256) + : cert.GetECDsaPrivateKey() is not null ? new CoseKey(cert.GetECDsaPrivateKey(), HashAlgorithmName.SHA256) + : cert.GetMLDsaPrivateKey() is not null ? new CoseKey(cert.GetMLDsaPrivateKey()) + : throw new CryptographicException("Unknown key type"); +#pragma warning restore SYSLIB5006 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. + } } diff --git a/CoseSign1.Headers.Tests/CoseSign1.Headers.Tests.csproj b/CoseSign1.Headers.Tests/CoseSign1.Headers.Tests.csproj index 6d05d75f..1095e944 100644 --- a/CoseSign1.Headers.Tests/CoseSign1.Headers.Tests.csproj +++ b/CoseSign1.Headers.Tests/CoseSign1.Headers.Tests.csproj @@ -2,7 +2,7 @@ Exe - net8.0 + net10.0 enable false false diff --git a/CoseSign1.Tests.Common/CoseSign1.Tests.Common.csproj b/CoseSign1.Tests.Common/CoseSign1.Tests.Common.csproj index d32f85b2..fad1def1 100644 --- a/CoseSign1.Tests.Common/CoseSign1.Tests.Common.csproj +++ b/CoseSign1.Tests.Common/CoseSign1.Tests.Common.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 false latest enable @@ -15,6 +15,11 @@ + + + + + diff --git a/CoseSign1.Tests.Common/TestCertificateUtils.cs b/CoseSign1.Tests.Common/TestCertificateUtils.cs index 45d83718..1e6c621c 100644 --- a/CoseSign1.Tests.Common/TestCertificateUtils.cs +++ b/CoseSign1.Tests.Common/TestCertificateUtils.cs @@ -5,6 +5,10 @@ namespace CoseSign1.Tests.Common; using System.Runtime.CompilerServices; +using System.Security.Cryptography.Cose; +using CoseSign1.Abstractions; +using CoseSign1.Abstractions.Interfaces; +using Moq; /// /// Class used to create in-memory certificates and certificate chains used for UnitTesting. @@ -138,12 +142,121 @@ public static X509Certificate2 CreateCertificate( } } - /// - /// Creates a certificate without private key from an existing certificate. - /// - /// The certificate to extract public key from. - /// A certificate with only the public key. - public static X509Certificate2 CreateCertificateWithoutPrivateKey(X509Certificate2 certificate) + private static X509Certificate2 CreateMldsaCertificate([CallerMemberName] string subjectName = "none", + X509Certificate2? issuingCa = null, + TimeSpan? duration = null, + bool addLifetimeEku = false) + { + using MLDsa algo = MLDsa.GenerateKey(MLDsaAlgorithm.MLDsa65); + + //Oid oid = new Oid("2.16.840.1.101.3.4.3.18", null); + //byte[] pkBytes = algo.ExportMLDsaPublicKey(); + +#pragma warning disable SYSLIB5006 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. + PublicKey pub = new(algo); + + CertificateRequest request = new CertificateRequest($"CN={subjectName}", algo); +#pragma warning restore SYSLIB5006 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. + + // Set basic certificate contraints + request.CertificateExtensions.Add( + new X509BasicConstraintsExtension(true, true, 12, true)); + + // Key usage: Digital Signature and Key Encipherment + request.CertificateExtensions.Add( + new X509KeyUsageExtension( + X509KeyUsageFlags.KeyCertSign, + true)); + + if (issuingCa != null) + { + // Set the AuthorityKeyIdentifier. There is no built-in + // support, so it needs to be copied from the Subject Key + // Identifier of the signing certificate and massaged slightly. + // AuthorityKeyIdentifier is "KeyID=" + // byte[] issuerSubjectKey = issuingCa.Extensions?["Subject Key Identifier"]?.RawData ?? throw new ArgumentOutOfRangeException(nameof(issuingCa), @"Issuing CA did not a ""Subject Key Identifier"" extension present"); + byte[] issuerSubjectKey = issuingCa.Extensions.First(x => x is X509SubjectKeyIdentifierExtension)?.RawData ?? throw new ArgumentOutOfRangeException(nameof(issuingCa), @"Issuing CA did not a ""Subject Key Identifier"" extension present"); + ArraySegment segment = new(issuerSubjectKey, 2, issuerSubjectKey.Length - 2); + byte[] authorityKeyIdentifier = new byte[segment.Count + 4]; + // these bytes define the "KeyID" part of the AuthorityKeyIdentifer + authorityKeyIdentifier[0] = 0x30; + authorityKeyIdentifier[1] = 0x16; + authorityKeyIdentifier[2] = 0x80; + authorityKeyIdentifier[3] = 0x14; + segment.CopyTo(authorityKeyIdentifier, 4); + request.CertificateExtensions.Add(new X509Extension("2.5.29.35", authorityKeyIdentifier, false)); + } + // DPS samples create certs with the device name as a SAN name + // in addition to the subject name + SubjectAlternativeNameBuilder sanBuilder = new(); + string dnsName = subjectName.Replace(":", "").Replace(" ", ""); + if (dnsName.Length > 40) + { + dnsName = dnsName.Substring(0, 39); + } + sanBuilder.AddDnsName(dnsName); + X509Extension sanExtension = sanBuilder.Build(); + request.CertificateExtensions.Add(sanExtension); + + // Enhanced key usages + OidCollection oids = + [ + new Oid("1.3.6.1.5.5.7.3.2"), // TLS Client auth + new Oid("1.3.6.1.5.5.7.3.1") // TLS Server auth + ]; + + if (addLifetimeEku) + { + oids.Add(new("1.3.6.1.4.1.311.10.3.13")); // Lifetime EKU + } + + request.CertificateExtensions.Add( + new X509EnhancedKeyUsageExtension(oids, false)); + + // add this subject key identifier + request.CertificateExtensions.Add( + new X509SubjectKeyIdentifierExtension(request.PublicKey, false)); + + // Certificate expiry: Valid from Yesterday to Now+365 days + // Unless the signing cert's validity is less. It's not possible + // to create a cert with longer validity than the signing cert. + DateTimeOffset notbefore = DateTimeOffset.UtcNow.AddDays(-1); + if (issuingCa != null && notbefore < issuingCa.NotBefore) + { + notbefore = new DateTimeOffset(issuingCa.NotBefore); + } + DateTimeOffset notafter = + duration is not null ? DateTimeOffset.UtcNow.Add(duration.Value) : + DateTimeOffset.UtcNow.AddDays(365); + if (issuingCa != null && notafter > issuingCa.NotAfter) + { + notafter = new DateTimeOffset(issuingCa.NotAfter); + } + + // cert serial is the epoch/unix timestamp + DateTime epoch = new(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); + long unixTime = Convert.ToInt64((DateTime.UtcNow - epoch).TotalSeconds); + byte[] serial = BitConverter.GetBytes(unixTime); + + X509Certificate2? generatedCertificate = null; + +#pragma warning disable SYSLIB5006 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. + X509SignatureGenerator gen = X509SignatureGenerator.CreateForMLDsa(algo); +#pragma warning restore SYSLIB5006 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. + + generatedCertificate = request.CreateSelfSigned( + notbefore, + notafter); + + return generatedCertificate; + } + +/// +/// Creates a certificate without private key from an existing certificate. +/// +/// The certificate to extract public key from. +/// A certificate with only the public key. +public static X509Certificate2 CreateCertificateWithoutPrivateKey(X509Certificate2 certificate) { return new X509Certificate2(certificate.Export(X509ContentType.Cert)); } @@ -213,5 +326,39 @@ public static X509Certificate2Collection CreateTestChainForPfx( return returnValue; } + public static ICoseSigningKeyProvider SetupMockSigningKeyProvider([CallerMemberName] string testName = "none", CoseKeyType keyType = CoseKeyType.RSA) + { + Mock mockedSignerKeyProvider = new(MockBehavior.Strict); + + mockedSignerKeyProvider.Setup(x => x.GetProtectedHeaders()).Returns(null); + mockedSignerKeyProvider.Setup(x => x.GetUnProtectedHeaders()).Returns(null); + + X509Certificate2? selfSignedCert; + CoseKey? coseKey; + + switch (keyType) + { + case CoseKeyType.RSA: + selfSignedCert = TestCertificateUtils.CreateCertificate(testName); + coseKey = new(selfSignedCert.GetRSAPrivateKey(), RSASignaturePadding.Pkcs1, HashAlgorithmName.SHA256); + break; + case CoseKeyType.ECDsa: + selfSignedCert = TestCertificateUtils.CreateCertificate(testName, useEcc: true); + coseKey = new(selfSignedCert.GetECDsaPrivateKey(), HashAlgorithmName.SHA256); + break; + case CoseKeyType.MLDsa: + selfSignedCert = TestCertificateUtils.CreateMldsaCertificate(testName); +#pragma warning disable SYSLIB5006 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. + coseKey = new(selfSignedCert.GetMLDsaPrivateKey()); +#pragma warning restore SYSLIB5006 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. + break; + default: + throw new ArgumentOutOfRangeException(nameof(keyType), keyType, "Unknown key type"); + } + + mockedSignerKeyProvider.Setup(x => x.GetCoseKey()).Returns(coseKey); + + return mockedSignerKeyProvider.Object; + } } diff --git a/CoseSign1.Tests/CoseSign1.Tests.csproj b/CoseSign1.Tests/CoseSign1.Tests.csproj index 919d6b4c..f8f119fc 100644 --- a/CoseSign1.Tests/CoseSign1.Tests.csproj +++ b/CoseSign1.Tests/CoseSign1.Tests.csproj @@ -2,7 +2,7 @@ Exe - net8.0 + net10.0 enable false false diff --git a/CoseSign1.Tests/CoseSign1MessageBuilderTests.cs b/CoseSign1.Tests/CoseSign1MessageBuilderTests.cs index ff79e102..b88b73df 100644 --- a/CoseSign1.Tests/CoseSign1MessageBuilderTests.cs +++ b/CoseSign1.Tests/CoseSign1MessageBuilderTests.cs @@ -50,7 +50,7 @@ public void TestConstructorsFailure() { // arrange Mock factoryObj = new(); - Mock mockedSigningKeyPovider = new(MockBehavior.Strict); + Mock mockedSigningKeyProvider = new(MockBehavior.Strict); List constructorTests = [ @@ -75,18 +75,10 @@ public void TestSettersWithFactoryObject() { byte[] testPayload = Encoding.ASCII.GetBytes("testPayload!"); X509Certificate2 testCert = TestCertificateUtils.CreateCertificate(); - Mock mockedSigningKeyPovider = new(MockBehavior.Strict); + ICoseSigningKeyProvider mockedSigningKeyProvider = TestCertificateUtils.SetupMockSigningKeyProvider(); Mock mockedCoseSignFactoryObject = new(); - CoseSign1MessageBuilder testCosesign1Builder = new(mockedSigningKeyPovider.Object, mockedCoseSignFactoryObject.Object); - - mockedSigningKeyPovider.Setup(x => x.GetProtectedHeaders()).Returns(null); - mockedSigningKeyPovider.Setup(x => x.GetUnProtectedHeaders()).Returns(null); - mockedSigningKeyPovider.Setup(x => x.HashAlgorithm).Returns(HashAlgorithmName.SHA256); - mockedSigningKeyPovider.Setup(x => x.GetECDsaKey(It.IsAny())).Returns(null); - mockedSigningKeyPovider.Setup(x => x.GetRSAKey(It.IsAny())).Returns(testCert.GetRSAPrivateKey()); - mockedSigningKeyPovider.Setup(x => x.IsRSA).Returns(true); - + CoseSign1MessageBuilder testCosesign1Builder = new(mockedSigningKeyProvider, mockedCoseSignFactoryObject.Object); CoseSign1Message response = testCosesign1Builder.SetPayloadBytes(testPayload).SetEmbedPayload(true).Build(); mockedCoseSignFactoryObject.Verify(v => v.CreateCoseSign1Message(It.IsAny>(), It.IsAny(), @@ -108,17 +100,10 @@ public void TestSettingHeaderExtender() byte[] testPayload = Encoding.ASCII.GetBytes("testPayload!"); X509Certificate2 testCert = TestCertificateUtils.CreateCertificate(); - Mock mockedSigningKeyPovider = new(MockBehavior.Strict); + ICoseSigningKeyProvider mockedSigningKeyProvider = TestCertificateUtils.SetupMockSigningKeyProvider(); Mock mockedHeaderExtender = new(MockBehavior.Strict); - CoseSign1MessageBuilder testCoseSign1Builder = new(mockedSigningKeyPovider.Object); - - mockedSigningKeyPovider.Setup(x => x.GetProtectedHeaders()).Returns([]); - mockedSigningKeyPovider.Setup(x => x.GetUnProtectedHeaders()).Returns([]); - mockedSigningKeyPovider.Setup(x => x.HashAlgorithm).Returns(HashAlgorithmName.SHA256); - mockedSigningKeyPovider.Setup(x => x.GetECDsaKey(It.IsAny())).Returns(null); - mockedSigningKeyPovider.Setup(x => x.GetRSAKey(It.IsAny())).Returns(testCert.GetRSAPrivateKey()); - mockedSigningKeyPovider.Setup(x => x.IsRSA).Returns(true); + CoseSign1MessageBuilder testCoseSign1Builder = new(mockedSigningKeyProvider); CoseHeaderLabel testHeaderLabel = new("test-header-label"); CoseHeaderLabel testHeaderLabel2 = new("test-header-label2"); diff --git a/CoseSign1.Tests/CoseSign1MessageFactoryTests.cs b/CoseSign1.Tests/CoseSign1MessageFactoryTests.cs index 9d5d5658..13f2e2f4 100644 --- a/CoseSign1.Tests/CoseSign1MessageFactoryTests.cs +++ b/CoseSign1.Tests/CoseSign1MessageFactoryTests.cs @@ -3,6 +3,8 @@ namespace CoseSign1.Tests; +using CoseSign1.Abstractions; + /// /// Class for Testing Methods of /// @@ -19,21 +21,13 @@ public void Setup() [Test] public void TestEmbedCoseSigningWithRSASuccess() { - Mock mockedSignerKeyProvider = new(MockBehavior.Strict); + ICoseSigningKeyProvider mockedSigningKeyProvider = TestCertificateUtils.SetupMockSigningKeyProvider(); CoseSign1MessageFactory coseSign1MessageFactory = new(); byte[] testPayload = Encoding.ASCII.GetBytes("testPayload!"); - X509Certificate2 selfSignedCertWithRSA = TestCertificateUtils.CreateCertificate(); - mockedSignerKeyProvider.Setup(x => x.GetProtectedHeaders()).Returns(null); - mockedSignerKeyProvider.Setup(x => x.GetUnProtectedHeaders()).Returns(null); - mockedSignerKeyProvider.Setup(x => x.HashAlgorithm).Returns(HashAlgorithmName.SHA256); - mockedSignerKeyProvider.Setup(x => x.GetECDsaKey(It.IsAny())).Returns(null); - mockedSignerKeyProvider.Setup(x => x.GetRSAKey(It.IsAny())).Returns(selfSignedCertWithRSA.GetRSAPrivateKey()); - mockedSignerKeyProvider.Setup(x => x.IsRSA).Returns(true); + CoseSign1Message response = coseSign1MessageFactory.CreateCoseSign1Message(testPayload, mockedSigningKeyProvider, true); - CoseSign1Message response = coseSign1MessageFactory.CreateCoseSign1Message(testPayload, mockedSignerKeyProvider.Object, true); - - mockedSignerKeyProvider.Object.IsRSA.Should().BeTrue(); + // TODO: do we want to check the signing certificate in the actual response to make sure it's RSA? response.Should().NotBeNull(); } @@ -43,23 +37,38 @@ public void TestEmbedCoseSigningWithRSASuccess() [Test] public void TestEmbedCoseSigningWithECDsaSuccess() { - Mock mockedSignerKeyProvider = new(MockBehavior.Strict); + ICoseSigningKeyProvider mockedSigningKeyProvider = TestCertificateUtils.SetupMockSigningKeyProvider(keyType: CoseKeyType.ECDsa); CoseSign1MessageFactory coseSign1MessageFactory = new(); Mock mockedHeaderExtender = new(); byte[] testPayload = Encoding.ASCII.GetBytes("testPayload!"); X509Certificate2 selfSignedCertwithECDsA = TestCertificateUtils.CreateCertificate(useEcc: true); - mockedSignerKeyProvider.Setup(x => x.GetProtectedHeaders()).Returns(null); - mockedSignerKeyProvider.Setup(x => x.GetUnProtectedHeaders()).Returns(null); - mockedSignerKeyProvider.Setup(x => x.HashAlgorithm).Returns(HashAlgorithmName.SHA256); - mockedSignerKeyProvider.Setup(x => x.GetECDsaKey(It.IsAny())).Returns(selfSignedCertwithECDsA.GetECDsaPrivateKey()); - mockedSignerKeyProvider.Setup(x => x.GetRSAKey(It.IsAny())).Returns(null); - mockedSignerKeyProvider.Setup(x => x.IsRSA).Returns(false); + mockedHeaderExtender.Setup(m => m.ExtendUnProtectedHeaders(It.IsAny())).Verifiable(); + mockedHeaderExtender.Setup(m => m.ExtendProtectedHeaders(It.IsAny())).Verifiable(); + + CoseSign1Message response = coseSign1MessageFactory.CreateCoseSign1Message(testPayload, mockedSigningKeyProvider, true, ContentTypeConstants.Cose, mockedHeaderExtender.Object); + + response.Should().NotBeNull(); + mockedHeaderExtender.Verify(m => m.ExtendUnProtectedHeaders(It.IsAny()), Times.Once); + mockedHeaderExtender.Verify(m => m.ExtendProtectedHeaders(It.IsAny()), Times.Once); + } + + /// + /// Testing with ECDsa Signing Key and embed payload true. + /// + [Test] + public void TestEmbedCoseSigningWithMLDsaSuccess() + { + ICoseSigningKeyProvider mockedSigningKeyProvider = TestCertificateUtils.SetupMockSigningKeyProvider(keyType: CoseKeyType.MLDsa); + CoseSign1MessageFactory coseSign1MessageFactory = new(); + Mock mockedHeaderExtender = new(); + byte[] testPayload = Encoding.ASCII.GetBytes("testPayload!"); + X509Certificate2 selfSignedCertwithECDsA = TestCertificateUtils.CreateCertificate(useEcc: true); mockedHeaderExtender.Setup(m => m.ExtendUnProtectedHeaders(It.IsAny())).Verifiable(); mockedHeaderExtender.Setup(m => m.ExtendProtectedHeaders(It.IsAny())).Verifiable(); - CoseSign1Message response = coseSign1MessageFactory.CreateCoseSign1Message(testPayload, mockedSignerKeyProvider.Object, true, ContentTypeConstants.Cose, mockedHeaderExtender.Object); + CoseSign1Message response = coseSign1MessageFactory.CreateCoseSign1Message(testPayload, mockedSigningKeyProvider, true, ContentTypeConstants.Cose, mockedHeaderExtender.Object); response.Should().NotBeNull(); mockedHeaderExtender.Verify(m => m.ExtendUnProtectedHeaders(It.IsAny()), Times.Once); @@ -72,11 +81,10 @@ public void TestEmbedCoseSigningWithECDsaSuccess() [Test] public void TestEmbedCoseSigningWithHeaderExtender() { - Mock mockedSignerKeyProvider = new(MockBehavior.Strict); + ICoseSigningKeyProvider mockedSigningKeyProvider = TestCertificateUtils.SetupMockSigningKeyProvider(keyType: CoseKeyType.ECDsa); CoseSign1MessageFactory coseSign1MessageFactory = new(); Mock mockedHeaderExtender = new(); byte[] testPayload = Encoding.ASCII.GetBytes("testPayload!"); - X509Certificate2 selfSignedCertwithECDsA = TestCertificateUtils.CreateCertificate(useEcc: true); CoseHeaderLabel testHeaderLabel = new("test-header-label"); CoseHeaderLabel testHeaderLabel2 = new("test-header-label2"); @@ -91,17 +99,10 @@ public void TestEmbedCoseSigningWithHeaderExtender() { testHeaderLabel2, "test-header-value2" } }; - mockedSignerKeyProvider.Setup(x => x.GetProtectedHeaders()).Returns(null); - mockedSignerKeyProvider.Setup(x => x.GetUnProtectedHeaders()).Returns(null); - mockedSignerKeyProvider.Setup(x => x.HashAlgorithm).Returns(HashAlgorithmName.SHA256); - mockedSignerKeyProvider.Setup(x => x.GetECDsaKey(It.IsAny())).Returns(selfSignedCertwithECDsA.GetECDsaPrivateKey()); - mockedSignerKeyProvider.Setup(x => x.GetRSAKey(It.IsAny())).Returns(null); - mockedSignerKeyProvider.Setup(x => x.IsRSA).Returns(false); - mockedHeaderExtender.Setup(m => m.ExtendProtectedHeaders(It.IsAny())).Returns(testProtectedHeaders2); mockedHeaderExtender.Setup(m => m.ExtendUnProtectedHeaders(It.IsAny())).Returns(null); - CoseSign1Message response = coseSign1MessageFactory.CreateCoseSign1Message(testPayload, mockedSignerKeyProvider.Object, true, ContentTypeConstants.Cose, mockedHeaderExtender.Object); + CoseSign1Message response = coseSign1MessageFactory.CreateCoseSign1Message(testPayload, mockedSigningKeyProvider, true, ContentTypeConstants.Cose, mockedHeaderExtender.Object); response.Should().NotBeNull(); response.ProtectedHeaders.Count.Should().Be(3); @@ -110,54 +111,21 @@ public void TestEmbedCoseSigningWithHeaderExtender() response.ProtectedHeaders.Last().Key.Should().Be(testProtectedHeaders2.Keys.Last()); } - /// - /// Test when both Keys are provided - /// - [Test] - public void TestEmbedCoseSigningWithBothKeysSuccess() - { - Mock mockedSignerKeyProvider = new(MockBehavior.Strict); - CoseSign1MessageFactory coseSign1MessageFactory = new(); - Mock mockedHeaderExtender = new(); - byte[] testPayload = Encoding.ASCII.GetBytes("testPayload!"); - X509Certificate2 selfSignedCertwithRSA = TestCertificateUtils.CreateCertificate(); - X509Certificate2 selfSignedCertwithECDsA = TestCertificateUtils.CreateCertificate(useEcc: true); - - mockedSignerKeyProvider.Setup(x => x.GetProtectedHeaders()).Returns(null); - mockedSignerKeyProvider.Setup(x => x.GetUnProtectedHeaders()).Returns(null); - mockedSignerKeyProvider.Setup(x => x.HashAlgorithm).Returns(HashAlgorithmName.SHA256); - mockedSignerKeyProvider.Setup(x => x.GetECDsaKey(It.IsAny())).Returns(selfSignedCertwithECDsA.GetECDsaPrivateKey()); - mockedSignerKeyProvider.Setup(x => x.GetRSAKey(It.IsAny())).Returns(selfSignedCertwithRSA.GetRSAPrivateKey()); ; - mockedSignerKeyProvider.Setup(x => x.IsRSA).Returns(true); - - CoseSign1Message response = coseSign1MessageFactory.CreateCoseSign1Message(testPayload, mockedSignerKeyProvider.Object, true); - - mockedSignerKeyProvider.Object.IsRSA.Should().BeTrue(); - response.Should().NotBeNull(); - } - /// /// Testing for Detached CoseSign1Message /// [Test] public void TestDetachedCoseSigningSuccess() { - Mock mockedSignerKeyProvider = new(MockBehavior.Strict); + ICoseSigningKeyProvider mockedSigningKeyProvider = TestCertificateUtils.SetupMockSigningKeyProvider(); CoseSign1MessageFactory coseSign1MessageFactory = new(); Mock mockedHeaderExtender = new(); byte[] testPayload = Encoding.ASCII.GetBytes("testPayload!"); - X509Certificate2 selfSignedCertwithRSA = TestCertificateUtils.CreateCertificate(); - - mockedSignerKeyProvider.Setup(x => x.GetProtectedHeaders()).Returns(null); - mockedSignerKeyProvider.Setup(x => x.GetUnProtectedHeaders()).Returns(null); - mockedSignerKeyProvider.Setup(x => x.HashAlgorithm).Returns(HashAlgorithmName.SHA256); - mockedSignerKeyProvider.Setup(x => x.GetECDsaKey(It.IsAny())).Returns(null); - mockedSignerKeyProvider.Setup(x => x.GetRSAKey(It.IsAny())).Returns(selfSignedCertwithRSA.GetRSAPrivateKey()); - mockedSignerKeyProvider.Setup(x => x.IsRSA).Returns(true); - CoseSign1Message response = coseSign1MessageFactory.CreateCoseSign1Message(testPayload, mockedSignerKeyProvider.Object, embedPayload: false); + CoseSign1Message response = coseSign1MessageFactory.CreateCoseSign1Message(testPayload, mockedSigningKeyProvider, embedPayload: false); - mockedSignerKeyProvider.Object.IsRSA.Should().BeTrue(); + // TODO: do we want to check the signing certificate in the actual response to make sure it's RSA? + //mockedSignerKeyProvider.Object.IsRSA.Should().BeTrue(); response.Should().NotBeNull(); } @@ -173,10 +141,7 @@ public void TestCoseSigningException() mockedSignerKeyProvider.Setup(x => x.GetProtectedHeaders()).Returns(null); mockedSignerKeyProvider.Setup(x => x.GetUnProtectedHeaders()).Returns(null); - mockedSignerKeyProvider.Setup(x => x.HashAlgorithm).Returns(HashAlgorithmName.SHA256); - mockedSignerKeyProvider.Setup(x => x.GetECDsaKey(It.IsAny())).Returns(null); - mockedSignerKeyProvider.Setup(x => x.GetRSAKey(It.IsAny())).Returns(null); - mockedSignerKeyProvider.Setup(x => x.IsRSA).Returns(false); + mockedSignerKeyProvider.Setup(x => x.GetCoseKey()).Returns(null); CoseSigningException? exceptionText = Assert.Throws( () => coseSign1MessageFactory.CreateCoseSign1Message(testPayload, @@ -221,10 +186,7 @@ public void TestWhenNoPayloadAndNoSigningKey() mockedSignerKeyProvider.Setup(x => x.GetProtectedHeaders()).Returns(null); mockedSignerKeyProvider.Setup(x => x.GetUnProtectedHeaders()).Returns(null); - mockedSignerKeyProvider.Setup(x => x.HashAlgorithm).Returns(HashAlgorithmName.SHA256); - mockedSignerKeyProvider.Setup(x => x.GetECDsaKey(It.IsAny())).Returns(null); - mockedSignerKeyProvider.Setup(x => x.GetRSAKey(It.IsAny())).Returns(null); - mockedSignerKeyProvider.Setup(x => x.IsRSA).Returns(false); + CoseSigningException? exceptionText = Assert.Throws(() => coseSign1MessageFactory.CreateCoseSign1Message(testPayload, mockedSignerKeyProvider.Object)); diff --git a/CoseSign1.Transparent.CTS.Tests/CoseSign1.Transparent.CTS.Tests.csproj b/CoseSign1.Transparent.CTS.Tests/CoseSign1.Transparent.CTS.Tests.csproj index d3a5ab11..879d8aec 100644 --- a/CoseSign1.Transparent.CTS.Tests/CoseSign1.Transparent.CTS.Tests.csproj +++ b/CoseSign1.Transparent.CTS.Tests/CoseSign1.Transparent.CTS.Tests.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 enable enable diff --git a/CoseSign1.Transparent.Tests/CoseSign1.Transparent.Tests.csproj b/CoseSign1.Transparent.Tests/CoseSign1.Transparent.Tests.csproj index baac1322..e6a56256 100644 --- a/CoseSign1.Transparent.Tests/CoseSign1.Transparent.Tests.csproj +++ b/CoseSign1.Transparent.Tests/CoseSign1.Transparent.Tests.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 enable enable diff --git a/CoseSign1/CoseSign1.csproj b/CoseSign1/CoseSign1.csproj index 401851b5..f92d685b 100644 --- a/CoseSign1/CoseSign1.csproj +++ b/CoseSign1/CoseSign1.csproj @@ -36,8 +36,6 @@ - - @@ -52,4 +50,7 @@ + + + diff --git a/CoseSign1/CoseSign1MessageFactory.cs b/CoseSign1/CoseSign1MessageFactory.cs index e043e28a..16dd4034 100644 --- a/CoseSign1/CoseSign1MessageFactory.cs +++ b/CoseSign1/CoseSign1MessageFactory.cs @@ -104,16 +104,7 @@ private static CoseSigner GetSigner( unProtectedHeaders = headerExtender.ExtendUnProtectedHeaders(unProtectedHeaders); } - // Get the RSA or ECDSA Signing Key. - AsymmetricAlgorithm? key = signingKeyProvider.GetRSAKey() as AsymmetricAlgorithm ?? signingKeyProvider.GetECDsaKey(); - - // Build the CoseSigner object. - return key switch - { - RSA => new CoseSigner((RSA)key, RSASignaturePadding.Pss, signingKeyProvider.HashAlgorithm, protectedHeaders, unProtectedHeaders), - ECDsa => new CoseSigner(key, signingKeyProvider.HashAlgorithm, protectedHeaders, unProtectedHeaders), - _ => throw new CoseSigningException("Unsupported certificate type for COSE signing.") - }; + return new CoseSigner(signingKeyProvider.GetCoseKey(), protectedHeaders, unProtectedHeaders); } // Use only for embed signing -- will throw on streams over 2gb diff --git a/CoseSignTool.Abstractions.Tests/CoseSignTool.Abstractions.Tests.csproj b/CoseSignTool.Abstractions.Tests/CoseSignTool.Abstractions.Tests.csproj index 864a1607..022177ea 100644 --- a/CoseSignTool.Abstractions.Tests/CoseSignTool.Abstractions.Tests.csproj +++ b/CoseSignTool.Abstractions.Tests/CoseSignTool.Abstractions.Tests.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 enable enable true diff --git a/CoseSignTool.Abstractions/CoseSignTool.Abstractions.csproj b/CoseSignTool.Abstractions/CoseSignTool.Abstractions.csproj index 95a007b9..111ced7e 100644 --- a/CoseSignTool.Abstractions/CoseSignTool.Abstractions.csproj +++ b/CoseSignTool.Abstractions/CoseSignTool.Abstractions.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 enable enable true diff --git a/CoseSignTool.CTS.Plugin.Tests/CoseSignTool.CTS.Plugin.Tests.csproj b/CoseSignTool.CTS.Plugin.Tests/CoseSignTool.CTS.Plugin.Tests.csproj index 3060532b..c1bfee50 100644 --- a/CoseSignTool.CTS.Plugin.Tests/CoseSignTool.CTS.Plugin.Tests.csproj +++ b/CoseSignTool.CTS.Plugin.Tests/CoseSignTool.CTS.Plugin.Tests.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 enable enable true diff --git a/CoseSignTool.CTS.Plugin/CoseSignTool.CTS.Plugin.csproj b/CoseSignTool.CTS.Plugin/CoseSignTool.CTS.Plugin.csproj index ce6ebef9..09d8d743 100644 --- a/CoseSignTool.CTS.Plugin/CoseSignTool.CTS.Plugin.csproj +++ b/CoseSignTool.CTS.Plugin/CoseSignTool.CTS.Plugin.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 enable enable true diff --git a/CoseSignTool.IndirectSignature.Plugin.Tests/CoseSignTool.IndirectSignature.Plugin.Tests.csproj b/CoseSignTool.IndirectSignature.Plugin.Tests/CoseSignTool.IndirectSignature.Plugin.Tests.csproj index dd26c140..3ab7885b 100644 --- a/CoseSignTool.IndirectSignature.Plugin.Tests/CoseSignTool.IndirectSignature.Plugin.Tests.csproj +++ b/CoseSignTool.IndirectSignature.Plugin.Tests/CoseSignTool.IndirectSignature.Plugin.Tests.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 enable enable true diff --git a/CoseSignTool.IndirectSignature.Plugin/CoseSignTool.IndirectSignature.Plugin.csproj b/CoseSignTool.IndirectSignature.Plugin/CoseSignTool.IndirectSignature.Plugin.csproj index 64732b14..4d0ddfe7 100644 --- a/CoseSignTool.IndirectSignature.Plugin/CoseSignTool.IndirectSignature.Plugin.csproj +++ b/CoseSignTool.IndirectSignature.Plugin/CoseSignTool.IndirectSignature.Plugin.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 enable enable true diff --git a/CoseSignTool.IndirectSignature.Plugin/IndirectSignatureCommandBase.cs b/CoseSignTool.IndirectSignature.Plugin/IndirectSignatureCommandBase.cs index b68d3149..9ed9999a 100644 --- a/CoseSignTool.IndirectSignature.Plugin/IndirectSignatureCommandBase.cs +++ b/CoseSignTool.IndirectSignature.Plugin/IndirectSignatureCommandBase.cs @@ -120,7 +120,9 @@ protected internal static (X509Certificate2? certificate, List } X509Certificate2Collection collection = new X509Certificate2Collection(); +#pragma warning disable SYSLIB0057 // Type or member is obsolete collection.Import(pfxPath, password, X509KeyStorageFlags.Exportable); +#pragma warning restore SYSLIB0057 // Type or member is obsolete if (collection.Count == 0) { diff --git a/CoseSignTool.Tests/CoseSignTool.Tests.csproj b/CoseSignTool.Tests/CoseSignTool.Tests.csproj index 80e77898..ae334e4e 100644 --- a/CoseSignTool.Tests/CoseSignTool.Tests.csproj +++ b/CoseSignTool.Tests/CoseSignTool.Tests.csproj @@ -1,7 +1,7 @@ Exe - net8.0 + net10.0 AnyCPU enable diff --git a/CoseSignTool/CoseSignTool.csproj b/CoseSignTool/CoseSignTool.csproj index df5f6d5e..7c7e0e36 100644 --- a/CoseSignTool/CoseSignTool.csproj +++ b/CoseSignTool/CoseSignTool.csproj @@ -2,7 +2,7 @@ Exe - net8.0 + net10.0 win-x64;linux-x64;osx-x64;osx-arm64; AnyCPU diff --git a/Directory.Packages.props b/Directory.Packages.props index dd926278..8986ebf3 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -2,29 +2,25 @@ true - - + - - - @@ -34,11 +30,10 @@ - - + \ No newline at end of file diff --git a/docs/PluginNamingConventions.md b/docs/PluginNamingConventions.md index e6882b2b..baac3783 100644 --- a/docs/PluginNamingConventions.md +++ b/docs/PluginNamingConventions.md @@ -36,7 +36,7 @@ To add a new plugin that gets automatically built and packaged: ```xml - net8.0 + net10.0 YourCompany.Feature.Plugin diff --git a/docs/PluginQuickStart.md b/docs/PluginQuickStart.md index 62b8fc47..d2a89917 100644 --- a/docs/PluginQuickStart.md +++ b/docs/PluginQuickStart.md @@ -23,7 +23,7 @@ Update the project file (`MyFirst.Plugin.csproj`): ```xml - net8.0 + net10.0 enable enable MyFirst.Plugin diff --git a/docs/Plugins.md b/docs/Plugins.md index 58b873ff..d2b7f01c 100644 --- a/docs/Plugins.md +++ b/docs/Plugins.md @@ -85,7 +85,7 @@ Create a new .NET 8.0 class library project: ```xml - net8.0 + net10.0 enable enable YourCompany.YourService.Plugin