diff --git a/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedCmsTests.cs b/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedCmsTests.cs index 8e5583004b92aa..c6b0983affae80 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedCmsTests.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignedCmsTests.cs @@ -669,21 +669,37 @@ public static void AddFirstSigner_SlhDsa(SubjectIdentifierType identifierType, b [MemberData(nameof(AddFirstSignerMLDsaTestData))] public static void AddFirstSigner_MLDsa(SubjectIdentifierType identifierType, bool detached, string digestOid, MLDsaAlgorithm algorithm) { + void SignWithMLDsa(SignedCms cms) + { + using (X509Certificate2 signerCert = Certificates.MLDsaIetf[algorithm].TryGetCertificateWithPrivateKey()) + { + CmsSigner signer = new CmsSigner(identifierType, signerCert); + signer.IncludeOption = X509IncludeOption.EndCertOnly; + signer.DigestAlgorithm = new Oid(digestOid, digestOid); + cms.ComputeSignature(signer); + } + } + + if (PlatformDetection.IsNetFramework && (digestOid == Oids.Shake128 || digestOid == Oids.Shake256)) + { + const int CryptEUnknownAlgorithm = unchecked((int)0x80091002); + + // .NET Framework's CMS is backed by Windows CAPI, which does not recognize SHAKE + // digest algorithms and fails signing with CRYPT_E_UNKNOWN_ALGO. .NET builds the + // CMS in managed code and succeeds. + ContentInfo contentInfo = new ContentInfo(new byte[] { 9, 8, 7, 6, 5 }); + SignedCms cms = new SignedCms(contentInfo, detached); + CryptographicException exception = Assert.Throws(() => SignWithMLDsa(cms)); + Assert.Equal(CryptEUnknownAlgorithm, exception.HResult); + return; + } + byte[]? signature = null; AssertAddFirstSigner( identifierType, detached, - cms => - { - using (X509Certificate2 signerCert = Certificates.MLDsaIetf[algorithm].TryGetCertificateWithPrivateKey()) - { - CmsSigner signer = new CmsSigner(identifierType, signerCert); - signer.IncludeOption = X509IncludeOption.EndCertOnly; - signer.DigestAlgorithm = new Oid(digestOid, digestOid); - cms.ComputeSignature(signer); - } - }, + SignWithMLDsa, firstSigner => { // Store signature for comparison after roundtrip. diff --git a/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignerInfoTests.cs b/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignerInfoTests.cs index 61ec029dbfab17..466b258795ea15 100644 --- a/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignerInfoTests.cs +++ b/src/libraries/System.Security.Cryptography.Pkcs/tests/SignedCms/SignerInfoTests.cs @@ -820,18 +820,34 @@ public static void AddCounterSigner_SlhDsa(SubjectIdentifierType identifierType, [MemberData(nameof(AddCounterSignerMLDsaTestData))] public static void AddCounterSigner_MLDsa(SubjectIdentifierType identifierType, string digestOid, MLDsaAlgorithm algorithm) { + void CounterSignWithMLDsa(SignerInfo signer) + { + using (X509Certificate2 signerCert = Certificates.MLDsaIetf[algorithm].TryGetCertificateWithPrivateKey()) + { + CmsSigner counterSigner = new CmsSigner(identifierType, signerCert); + counterSigner.IncludeOption = X509IncludeOption.EndCertOnly; + counterSigner.DigestAlgorithm = new Oid(digestOid, digestOid); + signer.ComputeCounterSignature(counterSigner); + } + } + + if (PlatformDetection.IsNetFramework && (digestOid == Oids.Shake128 || digestOid == Oids.Shake256)) + { + const int CryptEUnknownAlgorithm = unchecked((int)0x80091002); + + // .NET Framework's CMS is backed by Windows CAPI, which does not recognize SHAKE + // digest algorithms and fails signing with CRYPT_E_UNKNOWN_ALGO. .NET builds the + // CMS in managed code and succeeds. + SignedCms cms = new SignedCms(); + cms.Decode(SignedDocuments.RsaPkcs1OneSignerIssuerAndSerialNumber); + CryptographicException exception = Assert.Throws(() => CounterSignWithMLDsa(cms.SignerInfos[0])); + Assert.Equal(CryptEUnknownAlgorithm, exception.HResult); + return; + } + AssertAddCounterSigner( identifierType, - signer => - { - using (X509Certificate2 signerCert = Certificates.MLDsaIetf[algorithm].TryGetCertificateWithPrivateKey()) - { - CmsSigner counterSigner = new CmsSigner(identifierType, signerCert); - counterSigner.IncludeOption = X509IncludeOption.EndCertOnly; - counterSigner.DigestAlgorithm = new Oid(digestOid, digestOid); - signer.ComputeCounterSignature(counterSigner); - } - }, + CounterSignWithMLDsa, (cms, counterSigner) => { byte[] signature = counterSigner.GetSignature();