Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Windows based ECDSA SignedCms #91183

Merged
merged 1 commit into from
Aug 28, 2023
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 @@ -22,17 +22,17 @@ static partial void PrepareRegistrationECDsa(Dictionary<string, CmsSignature> lo
lookup.Add(Oids.ECDsaWithSha3_384, new ECDsaCmsSignature(Oids.ECDsaWithSha3_384, HashAlgorithmName.SHA3_384));
lookup.Add(Oids.ECDsaWithSha3_512, new ECDsaCmsSignature(Oids.ECDsaWithSha3_512, HashAlgorithmName.SHA3_512));
#endif
lookup.Add(Oids.EcPublicKey, new ECDsaCmsSignature(null, default));
lookup.Add(Oids.EcPublicKey, new ECDsaCmsSignature(null, null));
}

private sealed partial class ECDsaCmsSignature : CmsSignature
{
private readonly HashAlgorithmName _expectedDigest;
private readonly HashAlgorithmName? _expectedDigest;
private readonly string? _signatureAlgorithm;

internal override RSASignaturePadding? SignaturePadding => null;

internal ECDsaCmsSignature(string? signatureAlgorithm, HashAlgorithmName expectedDigest)
internal ECDsaCmsSignature(string? signatureAlgorithm, HashAlgorithmName? expectedDigest)
{
_signatureAlgorithm = signatureAlgorithm;
_expectedDigest = expectedDigest;
Expand All @@ -56,7 +56,7 @@ internal override bool VerifySignature(
ReadOnlyMemory<byte>? signatureParameters,
X509Certificate2 certificate)
{
if (_expectedDigest != digestAlgorithmName)
if (_expectedDigest != null && _expectedDigest != digestAlgorithmName)
{
throw new CryptographicException(
SR.Format(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ internal static class Oids
public const string RsaPss = "1.2.840.113549.1.1.10";
public const string Esdh = "1.2.840.113549.1.9.16.3.5";
public const string Dh = "1.2.840.10046.2.1";
public const string EcPublicKey = "1.2.840.10045.2.1";
public const string EcdsaSha256 = "1.2.840.10045.4.3.2";

// Cryptographic Attribute Types
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -823,6 +823,20 @@ public static void ExistingDocument_Rsa_Sha3_512()
}
}

[Fact]
public static void ExistingDocument_Ecdsa_Sha256_FromNetFX()
{
SignedCms cms = new SignedCms();
cms.Decode(SignedDocuments.Ecdsa_Sha256_FromNetFX_SignedDocument);

cms.CheckSignature(true); // Assert.NoThrow
Assert.Single(cms.SignerInfos);

SignerInfo signerInfo = cms.SignerInfos[0];
Assert.Equal(Oids.Sha256, signerInfo.DigestAlgorithm.Value);
Assert.Equal(Oids.EcPublicKey, signerInfo.SignatureAlgorithm.Value);
}

private static void VerifyWithExplicitPrivateKey(X509Certificate2 cert, AsymmetricAlgorithm key)
{
using (var pubCert = new X509Certificate2(cert.RawData))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1789,5 +1789,38 @@ internal static class SignedDocuments
"F11C632B4F605A41821A3F15B4F537FD5F0EE3426A7A03732AC946C3B435" +
"776A873A3DAE93FB8312C681144CF51F05CE37A0DB4C1544E178F88E421C" +
"0B5456D18C13B335DA808CE60C4E35F507").HexToByteArray();

// produced with the below PowerShell code using the pfx Certificates.ECDsaP256Win
// $cert = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new(
// [System.Convert]::FromBase64String($Certificates_ECDsaP256Win),
// 'Test',
// 'EphemeralKeySet')
// $signer = [System.Security.Cryptography.Pkcs.CmsSigner]::new('IssuerAndSerialNumber', $cert)
// $signer.IncludeOption = 'ExcludeRoot'
// $signer.DigestAlgorithm = '2.16.840.1.101.3.4.2.1'
// $contentInfo = [System.Security.Cryptography.Pkcs.ContentInfo]::new([byte[]]@(0))
// $signedCms = [System.Security.Cryptography.Pkcs.SignedCms]::new($contentInfo, $false)
// $signedCms.ComputeSignature($signer, $true)
// $signedCms.Encode()
internal static readonly byte[] Ecdsa_Sha256_FromNetFX_SignedDocument = (
"3082023106092A864886F70D010702A08202223082021E020101310F300D" +
"06096086480165030402010500301006092A864886F70D010701A0030401" +
"00A082015C308201583081FFA003020102021035428F3B3C5107AD49E776" +
"D6E74C4DC8300A06082A8648CE3D04030230153113301106035504030C0A" +
"45434453412054657374301E170D3135303530313030333730335A170D31" +
"36303530313030353730335A30153113301106035504030C0A4543445341" +
"20546573743059301306072A8648CE3D020106082A8648CE3D0301070342" +
"00047590F69CA114E92927E034C997B7C882A8C992AC00CEFB4EB8319015" +
"36F291E1B515263BCD20E1EA32496FDAC84E2D8D1B703266A9088F6EAF65" +
"2549D9BB63D5A331302F300E0603551D0F0101FF040403020388301D0603" +
"551D0E0416041411218A92C5EB12273B3C5CCFB8220CCCFDF387DB300A06" +
"082A8648CE3D040302034800304502201AFE595E19F1AE4B6A4B231E8851" +
"926438C55B5DDE632E6ADF13C1023A65898E022100CBDF434FDD197D8B59" +
"4E8026E44263BADE773C2BEBD060CC4109484A498E7C7E31819530819202" +
"0101302930153113301106035504030C0A45434453412054657374021035" +
"428F3B3C5107AD49E776D6E74C4DC8300D06096086480165030402010500" +
"300B06072A8648CE3D020105000446304402203557687B26E650E4F86F4B" +
"77A5BF5851350C96F01142696CC1391632CB95C3370220017FD4D9329F00" +
"1EC74210CD34CAEE3878B2302602DB7930347E104679734291").HexToByteArray();
}
}