Skip to content

Commit

Permalink
Support Windows based ECDSA SignedCms (#91183)
Browse files Browse the repository at this point in the history
  • Loading branch information
jborean93 committed Aug 28, 2023
1 parent c2e29f0 commit 602db78
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 4 deletions.
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();
}
}

0 comments on commit 602db78

Please sign in to comment.