Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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<CryptographicException>(() => 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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<CryptographicException>(() => 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();
Expand Down
Loading