From bae5fd93574d5e70ddb91ff8f58357e8db211fa0 Mon Sep 17 00:00:00 2001 From: steveharter Date: Thu, 7 Jul 2016 11:11:49 -0500 Subject: [PATCH] Add support for Ecc Commit migrated from https://github.com/dotnet/corefx/commit/3debb53396c688ae4111df3222282cd9537b7760 --- .../Cryptography/Pal.Windows/X509Pal.PublicKey.cs | 146 +++++++++++++++++++-- ...m.Security.Cryptography.X509Certificates.csproj | 6 + .../tests/PfxTests.cs | 43 ++++++ .../tests/PublicKeyTests.cs | 100 ++++++++++++++ .../tests/TestData.cs | 125 +++++++++++++++++- 5 files changed, 401 insertions(+), 19 deletions(-) diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/X509Pal.PublicKey.cs b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/X509Pal.PublicKey.cs index 35db5dc..7ed57c9 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/X509Pal.PublicKey.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/src/Internal/Cryptography/Pal.Windows/X509Pal.PublicKey.cs @@ -2,23 +2,15 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using Internal.Cryptography.Pal.Native; using System; -using System.IO; -using System.Text; using System.Diagnostics; -using System.Globalization; +using System.IO; using System.Runtime.InteropServices; - -using Internal.Cryptography; -using Internal.Cryptography.Pal.Native; - using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; - -using SafeBCryptKeyHandle = Microsoft.Win32.SafeHandles.SafeBCryptKeyHandle; -using SafeNCryptKeyHandle = Microsoft.Win32.SafeHandles.SafeNCryptKeyHandle; using NTSTATUS = Interop.BCrypt.NTSTATUS; +using SafeBCryptKeyHandle = Microsoft.Win32.SafeHandles.SafeBCryptKeyHandle; using static Interop.Crypt32; @@ -30,6 +22,9 @@ namespace Internal.Cryptography.Pal /// internal sealed partial class X509Pal : IX509Pal { + const string BCRYPT_ECC_CURVE_NAME_PROPERTY = "ECCCurveName"; + const string BCRYPT_ECC_PARAMETERS_PROPERTY = "ECCParameters"; + public AsymmetricAlgorithm DecodePublicKey(Oid oid, byte[] encodedKeyValue, byte[] encodedParameters, ICertificatePal certificatePal) { if (oid.Value == Oids.Ecc) @@ -65,15 +60,52 @@ namespace Internal.Cryptography.Pal private static ECDsa DecodeECDsaPublicKey(CertificatePal certificatePal) { + ECDsa ecdsa; using (SafeBCryptKeyHandle bCryptKeyHandle = ImportPublicKeyInfo(certificatePal.CertContext)) { - CngKeyBlobFormat blobFormat = CngKeyBlobFormat.EccPublicBlob; - byte[] keyBlob = ExportKeyBlob(bCryptKeyHandle, blobFormat); + CngKeyBlobFormat blobFormat; + byte[] keyBlob; +#if NETNATIVE + blobFormat = CngKeyBlobFormat.EccPublicBlob; + keyBlob = ExportKeyBlob(bCryptKeyHandle, blobFormat); using (CngKey cngKey = CngKey.Import(keyBlob, blobFormat)) { - return new ECDsaCng(cngKey); + ecdsa = new ECDsaCng(cngKey); } +#else + string curveName = GetCurveName(bCryptKeyHandle); + + if (curveName == null) + { + if (HasExplicitParameters(bCryptKeyHandle)) + { + blobFormat = CngKeyBlobFormat.EccFullPublicBlob; + } + else + { + blobFormat = CngKeyBlobFormat.EccPublicBlob; + } + + keyBlob = ExportKeyBlob(bCryptKeyHandle, blobFormat); + using (CngKey cngKey = CngKey.Import(keyBlob, blobFormat)) + { + ecdsa = new ECDsaCng(cngKey); + } + } + else + { + blobFormat = CngKeyBlobFormat.EccPublicBlob; + keyBlob = ExportKeyBlob(bCryptKeyHandle, blobFormat); + ECParameters ecparams = new ECParameters(); + ExportNamedCurveParameters(ref ecparams, keyBlob, false); + ecparams.Curve = ECCurve.CreateFromFriendlyName(curveName); + ecdsa = new ECDsaCng(); + ecdsa.ImportParameters(ecparams); + } +#endif } + + return ecdsa; } private static SafeBCryptKeyHandle ImportPublicKeyInfo(SafeCertContextHandle certContext) @@ -129,6 +161,41 @@ namespace Internal.Cryptography.Pal #endif //NETNATIVE } +#if !NETNATIVE + private static void ExportNamedCurveParameters(ref ECParameters ecParams, byte[] ecBlob, bool includePrivateParameters) + { + // We now have a buffer laid out as follows: + // BCRYPT_ECCKEY_BLOB header + // byte[cbKey] Q.X + // byte[cbKey] Q.Y + // -- Private only -- + // byte[cbKey] D + + unsafe + { + Debug.Assert(ecBlob.Length >= sizeof(Interop.BCrypt.BCRYPT_ECCKEY_BLOB)); + + fixed (byte* pEcBlob = ecBlob) + { + Interop.BCrypt.BCRYPT_ECCKEY_BLOB* pBcryptBlob = (Interop.BCrypt.BCRYPT_ECCKEY_BLOB*)pEcBlob; + + int offset = sizeof(Interop.BCrypt.BCRYPT_ECCKEY_BLOB); + + ecParams.Q = new ECPoint + { + X = Interop.BCrypt.Consume(ecBlob, ref offset, pBcryptBlob->cbKey), + Y = Interop.BCrypt.Consume(ecBlob, ref offset, pBcryptBlob->cbKey) + }; + + if (includePrivateParameters) + { + ecParams.D = Interop.BCrypt.Consume(ecBlob, ref offset, pBcryptBlob->cbKey); + } + } + } + } +#endif + private static byte[] DecodeKeyBlob(CryptDecodeObjectStructType lpszStructType, byte[] encodedKeyValue) { int cbDecoded = 0; @@ -253,6 +320,57 @@ namespace Internal.Cryptography.Pal q = qLocal; g = gLocal; } + + private static bool HasExplicitParameters(SafeBCryptKeyHandle bcryptHandle) + { + byte[] explicitParams = GetProperty(bcryptHandle, BCRYPT_ECC_PARAMETERS_PROPERTY); + return (explicitParams != null && explicitParams.Length > 0); + } + + private static string GetCurveName(SafeBCryptKeyHandle bcryptHandle) + { + return GetPropertyAsString(bcryptHandle, BCRYPT_ECC_CURVE_NAME_PROPERTY); + } + + private static string GetPropertyAsString(SafeBCryptKeyHandle cryptHandle, string propertyName) + { + Debug.Assert(!cryptHandle.IsInvalid); + byte[] value = GetProperty(cryptHandle, propertyName); + if (value == null || value.Length == 0) + return null; + + unsafe + { + fixed (byte* pValue = value) + { + string valueAsString = Marshal.PtrToStringUni((IntPtr)pValue); + return valueAsString; + } + } + } + + private static byte[] GetProperty(SafeBCryptKeyHandle cryptHandle, string propertyName) + { + Debug.Assert(!cryptHandle.IsInvalid); + unsafe + { + int numBytesNeeded; + NTSTATUS errorCode = Interop.BCrypt.BCryptGetProperty(cryptHandle, propertyName, null, 0, out numBytesNeeded, 0); + if (errorCode != NTSTATUS.STATUS_SUCCESS) + return null; + + byte[] propertyValue = new byte[numBytesNeeded]; + fixed (byte* pPropertyValue = propertyValue) + { + errorCode = Interop.BCrypt.BCryptGetProperty(cryptHandle, propertyName, pPropertyValue, propertyValue.Length, out numBytesNeeded, 0); + } + if (errorCode != NTSTATUS.STATUS_SUCCESS) + return null; + + Array.Resize(ref propertyValue, numBytesNeeded); + return propertyValue; + } + } } } diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/src/System.Security.Cryptography.X509Certificates.csproj b/src/libraries/System.Security.Cryptography.X509Certificates/src/System.Security.Cryptography.X509Certificates.csproj index 19e1b1b..bfa6c57 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/src/System.Security.Cryptography.X509Certificates.csproj +++ b/src/libraries/System.Security.Cryptography.X509Certificates/src/System.Security.Cryptography.X509Certificates.csproj @@ -136,6 +136,12 @@ Common\Interop\Windows\BCrypt\Interop.BCryptExportKey.cs + + Common\Interop\Windows\BCrypt\Interop.BCryptGetProperty.cs + + + Common\Interop\Windows\BCrypt\Interop.Blobs.cs + Common\Interop\Windows\BCrypt\Interop.NTSTATUS.cs diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/tests/PfxTests.cs b/src/libraries/System.Security.Cryptography.X509Certificates/tests/PfxTests.cs index 9b1aedc..b2f3864 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/tests/PfxTests.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/tests/PfxTests.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Collections.Generic; using System.Runtime.InteropServices; using Test.Cryptography; using Xunit; @@ -10,6 +11,19 @@ namespace System.Security.Cryptography.X509Certificates.Tests { public static class PfxTests { + public static IEnumerable BrainpoolCurvesPfx + { + get + { +#if NETNATIVE + yield break; +#else + yield return new object[] { TestData.ECDsabrainpoolP160r1_Pfx }; + yield return new object[] { TestData.ECDsabrainpoolP160r1_Explicit_Pfx }; +#endif + } + } + [Fact] public static void TestConstructor() { @@ -118,6 +132,35 @@ namespace System.Security.Cryptography.X509Certificates.Tests } } + [Theory, MemberData(nameof(BrainpoolCurvesPfx))] + public static void ReadECDsaPrivateKey_BrainpoolP160r1_Pfx(byte[] pfxData) + { + try + { + using (var cert = new X509Certificate2(pfxData, TestData.PfxDataPassword)) + { + using (ECDsa ecdsa = cert.GetECDsaPrivateKey()) + { + Assert.NotNull(ecdsa); + + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + AssertEccAlgorithm(ecdsa, "ECDH"); + } + } + } + } + catch (CryptographicException) + { + // Windows 7, Windows 8, Ubuntu 14, CentOS can fail. Verify known good platforms don't fail. + Assert.False(PlatformDetection.IsWindows && PlatformDetection.WindowsVersion >= 10); + Assert.False(PlatformDetection.IsUbuntu1604); + Assert.False(PlatformDetection.IsOSX); + + return; + } + } + [Fact] public static void ReadECDsaPrivateKey_OpenSslPfx() { diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/tests/PublicKeyTests.cs b/src/libraries/System.Security.Cryptography.X509Certificates/tests/PublicKeyTests.cs index e4696da..9e2addf 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/tests/PublicKeyTests.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/tests/PublicKeyTests.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Collections.Generic; using System.IO; using System.Text; using Test.Cryptography; @@ -27,6 +28,27 @@ namespace System.Security.Cryptography.X509Certificates.Tests } } + /// + /// First parameter is the cert, the second is a hash of "Hello" + /// + public static IEnumerable BrainpoolCurves + { + get + { +#if NETNATIVE + yield break; +#else + yield return new object[] { + TestData.ECDsabrainpoolP160r1_CertificatePemBytes, + "9145C79DD4DF758EB377D13B0DB81F83CE1A63A4099DDC32FE228B06EB1F306423ED61B6B4AF4691".HexToByteArray() }; + + yield return new object[] { + TestData.ECDsabrainpoolP160r1_ExplicitCertificatePemBytes, + "6D74F1C9BCBBA5A25F67E670B3DABDB36C24E8FAC3266847EB2EE7E3239208ADC696BB421AB380B4".HexToByteArray() }; +#endif + } + } + [Fact] public static void TestOid_RSA() { @@ -151,6 +173,35 @@ namespace System.Security.Cryptography.X509Certificates.Tests } } + [Theory, MemberData(nameof(BrainpoolCurves))] + public static void TestKey_ECDsabrainpool_PublicKey(byte[] curveData, byte[] notUsed) + { + byte[] helloBytes = Encoding.ASCII.GetBytes("Hello"); + + try + { + using (var cert = new X509Certificate2(curveData)) + { + using (ECDsa ec = cert.GetECDsaPublicKey()) + { + Assert.Equal(160, ec.KeySize); + + // The public key should be unable to sign. + Assert.ThrowsAny(() => ec.SignData(helloBytes, HashAlgorithmName.SHA256)); + } + } + } + catch (CryptographicException) + { + // Windows 7, Windows 8, Ubuntu 14, CentOS can fail. Verify known good platforms don't fail. + Assert.False(PlatformDetection.IsWindows && PlatformDetection.WindowsVersion >= 10); + Assert.False(PlatformDetection.IsUbuntu1604); + Assert.False(PlatformDetection.IsOSX); + + return; + } + } + [Fact] public static void TestECDsaPublicKey() { @@ -205,6 +256,45 @@ namespace System.Security.Cryptography.X509Certificates.Tests } } + [Theory, MemberData(nameof(BrainpoolCurves))] + public static void TestECDsaPublicKey_BrainpoolP160r1_ValidatesSignature(byte[] curveData, byte[] existingSignature) + { + byte[] helloBytes = Encoding.ASCII.GetBytes("Hello"); + + try + { + using (var cert = new X509Certificate2(curveData)) + { + using (ECDsa publicKey = cert.GetECDsaPublicKey()) + { + Assert.Equal(160, publicKey.KeySize); + + // It is an Elliptic Curve Cryptography public key. + Assert.Equal("1.2.840.10045.2.1", cert.PublicKey.Oid.Value); + + bool isSignatureValid = publicKey.VerifyData(helloBytes, existingSignature, HashAlgorithmName.SHA256); + Assert.True(isSignatureValid, "isSignatureValid"); + + unchecked + { + --existingSignature[existingSignature.Length - 1]; + } + isSignatureValid = publicKey.VerifyData(helloBytes, existingSignature, HashAlgorithmName.SHA256); + Assert.False(isSignatureValid, "isSignatureValidNeg"); + } + } + } + catch (CryptographicException) + { + // Windows 7, Windows 8, Ubuntu 14, CentOS can fail. Verify known good platforms don't fail. + Assert.False(PlatformDetection.IsWindows && PlatformDetection.WindowsVersion >= 10); + Assert.False(PlatformDetection.IsUbuntu1604); + Assert.False(PlatformDetection.IsOSX); + + return; + } + } + [Fact] public static void TestECDsaPublicKey_NonSignatureCert() { @@ -276,6 +366,16 @@ namespace System.Security.Cryptography.X509Certificates.Tests TestKey_ECDsaCng(TestData.ECDsa521Certificate, TestData.ECDsaCng521PublicKey); } + [Fact] + [PlatformSpecific(PlatformID.Windows)] + public static void TestKey_BrainpoolP160r1() + { + if (PlatformDetection.WindowsVersion >= 10) + { + TestKey_ECDsaCng(TestData.ECDsabrainpoolP160r1_CertificatePemBytes, TestData.ECDsabrainpoolP160r1_PublicKey); + } + } + private static void TestKey_ECDsaCng(byte[] certBytes, TestData.ECDsaCngKeyValues expected) { #if !NETNATIVE diff --git a/src/libraries/System.Security.Cryptography.X509Certificates/tests/TestData.cs b/src/libraries/System.Security.Cryptography.X509Certificates/tests/TestData.cs index f6fdd14..257338d 100644 --- a/src/libraries/System.Security.Cryptography.X509Certificates/tests/TestData.cs +++ b/src/libraries/System.Security.Cryptography.X509Certificates/tests/TestData.cs @@ -195,7 +195,6 @@ Og7vtpU6pzjkJZIIpohmgg== "60ccd59a84878d2430f7ef34d0631db142674a0e4bbf3a0eefb6953aa738e425" + "9208a68866823100").HexToByteArray(); - public static byte[] StoreSavedAsCerData = ( "308201e530820152a0030201020210d5b5bc1c458a558845bff51cb4dff31c30" + "0906052b0e03021d05003011310f300d060355040313064d794e616d65301e17" + @@ -1076,6 +1075,115 @@ dRUwHwYDVR0jBBgwFoAU5FG2Fmi86hJOCf4KnjaxOGWVdRUwDAYDVR0TBAUwAwEB wggvPj3b2WMXsVWiPr4S1Y/nBA== -----END CERTIFICATE-----"); + internal static readonly byte[] ECDsabrainpoolP160r1_Pfx = ( + "308203D00201033082039606092A864886F70D010701A0820387048203833082" + + "037F3082029F06092A864886F70D010706A08202903082028C02010030820285" + + "06092A864886F70D010701301C060A2A864886F70D010C0106300E0408E4D7F5" + + "F71CA4D5380202080080820258F19503250C93322C81CCC92C57AD76AD4DDF79" + + "10DBAB6A63D6AAF3F470AC5283BDEB532086D3379B7A3D68D17FAC483EBEA029" + + "1D2B5F862885E048A3034580A41F238AA836B9E94C12B0656B51C72355AED1DD" + + "19FE771E3768095D6467FC8742BE0BC5D65360CD875D35C23D272842F64791A1" + + "53F96AFBD3D7660EC016BF9D59B2B68C2A34D93B133697D6B77DB27649BEEABC" + + "0B68D35DB3779DD4C871C9C26799E6ABB5E9048DDC44C6E6310F3A023AD09E97" + + "1AB1DF38FDF3091FB35125EA3A14F5D72A00EC4C637951F026DE79C0E30E0244" + + "808FB46EFD4EA9C67411DC2B13842B273F405F6D58D45D1D2D47BC1362ED9884" + + "C2C44EA334A3B02C7E661F489DED798B63D64F90916596BADC87C68C868FCECB" + + "6F246410186BBB2F2DC2ED24BF215AA54570072E21970CF856398BB1FD8C2F61" + + "0788231C51D45CE471A235464147A405799F8CBE39AA30A8BFD2534C738AE330" + + "8771394D871429EF2D6AB6381F793D7CBC0374D4E529B8B6AA37BE04FBE71A9A" + + "A7954814C0C8841740539ED97DB56C3CBE5851C9D875E4B6023AE095B62C9DC5" + + "36E06DA40C4B874776CBABDDAB50BDD5ECF9D997EEB1483D3AC23E6F37DD4CBD" + + "64163E7A115BCE44554C53DD860B83CBE3B35F1E26B87185C602E4FFB3A99458" + + "0D6A9334F74AA29B3609926FE86F197C955CBAEC2A41EE1572A4295F62D4D9CA" + + "050CD933BC0BA43D7744EAFA9D6B8253241EB36C605DC334A6470BC709F13985" + + "8AC238FD7F3C14EDDAB6E29996FE966A96EAC23CF17063C89315734D76CCB21F" + + "94A7E4A44A5F6DCB93CEEEFB539664296F8F609CFE293200FE4B5EE57AB3A1E7" + + "A3483DC6243081D906092A864886F70D010701A081CB0481C83081C53081C206" + + "0B2A864886F70D010C0A0102A0818B308188301C060A2A864886F70D010C0103" + + "300E0408CD30F3C5A9918832020208000468BF29F33058622BA159CDD3DE2B49" + + "CBDD736BF1483FF4D43BACCC93B544A513D5E47DB4FECADBB4E3277A6B90345D" + + "7E73F507924A615D968F807834D3796EFB0A3EF214A75883E3AB90086DA2418B" + + "0B2D657DEA39A8600172B6975FFB39E88863DB11283A5CEA1FCB312530230609" + + "2A864886F70D01091531160414472193B362B056F6D6928EFF4C43FF1EFEB173" + + "4E30313021300906052B0E03021A05000414B703685D5039D8EEF1A46F772F31" + + "F177FDE874EC0408B4EF89F18902CE9502020800").HexToByteArray(); + + internal static readonly byte[] ECDsabrainpoolP160r1_Explicit_Pfx = ( + "30820501020103308204C706092A864886F70D010701A08204B8048204B43082" + + "04B03082032F06092A864886F70D010706A08203203082031C02010030820315" + + "06092A864886F70D010701301C060A2A864886F70D010C0106300E0408C55E7D" + + "72B26355D202020800808202E8B8BCB9180C8751F860C5F77C04CC921A89D836" + + "E8BC06DA99238EF8D65FB3473AF97D930B93471B28F08F483062BCEDB44287FA" + + "E813B6CA812393475F50BB2D0AD233A8CE0832DECE54EF78A1F289A7802A9900" + + "BAA2B7392BCF6C963D54D8DD63898D5D2FA472E77194763822157664417D93D8" + + "BF740A4A5683FFFDF8B4CC7E074C6DCFF73E21368D743F0A1CE33484B02A4502" + + "F7340A853F82F606B10DEA7239EF56C8DBDAED8DD3C956DD4D3E42CA517318E6" + + "0DF70721469C512E120C500956D960A59EEB4A3A6541891319ACA68AB99462EA" + + "CB59B52F6C6BFCF24EEA4E19BDDC5DDE1B6F36549DD589E1B10CAA02D4A53C36" + + "1F1B9F101F9375394CF9BC8D941F94CC4F128EC861AA6B4182E1F81D2C0BADEA" + + "2E6596BAC8819DE293ECEEC7C54BE97CD3917E0497F2559D44EF3484618DCB9B" + + "85820762F392925BB36BD482DF544B614CDF9C6728BD92E858C1DF61435E7A03" + + "DED27DA460603A61BE7DB93870E9530EB51384663E42A49C342891B8E757ED49" + + "18A590D59734EA1C95E992CD93B80EBD3C246999305C204A813E0DCF26E64446" + + "15A79E74042C7EAD4FEF0E68AA9DF627B5F4C037BF728015B6BBFA046CAA805C" + + "BE7B1867262B36172E8759FAE7B965FF9B98D3539A48525E10A57A84C55AEFAC" + + "3ED9025AB8B0680E0896DDD776C0AFC1A95BDD5DBE0ECCEB860B3CD3D6A2A493" + + "2BC7774246A6936AFABA9BA8292841F9D6417AFFB00872E9B4ADF11889AEF20A" + + "FCB8EAEBADAF38A2A240D36940B1585B37F7CA6A887EE1FBA199990FC104CD1F" + + "A983CC2CE91156559EFCFC0F25B7C24B161DF4B4436F14428C4AE06F49FCC328" + + "D00891A44AFAE5412FD330E23CFAE6107B4C965DFDB6335E8EFDF2C40767846B" + + "C95ABF784DE155EED92DAB7A265DC17BC3ADA68D04E378D2E4E8924B05937092" + + "E779EB04899E4FB19AAE7AA5FCF8D7A33BA464E4BB1FFB4E4D4CD71152F42B68" + + "F5AB298B10DEB653C7F77F66B761DFD61E4E2DDD13B0B15639473BF5C3B8A31D" + + "3D2334287F61E1A06F44CD3F2E74F59F43876F0D923082017906092A864886F7" + + "0D010701A082016A04820166308201623082015E060B2A864886F70D010C0A01" + + "02A082012630820122301C060A2A864886F70D010C0103300E0408A92CDE5D9A" + + "F5278D0202080004820100A302E03B1BDF59D4ECD6F0FE7745F7C0DCE2CCEF0E" + + "B26A7B92839B60288B05445BA1C91109D7E632E0C7B742E2D7D0947573AFEF1F" + + "FAFCF8135DA3B5EE26A8E3AB7F415A8A19112724F850F024D3527F1FE2A303B1" + + "34A644307AC6816E59E08540FA782351B27E37775AF3CD904E50A1A76C7C4F34" + + "7EE78A1ED51FF71D00954130369012750746A280983E883E59AFDBBCCC7D1AA0" + + "ECDCF2079ECFA4645E156ACC5FD6913763FC93C2E0C572042D00FE4EEB5E75DE" + + "28C21FA1A7356C4071572DF23CC23833EA26705C0AA080636E27512B5F5755FE" + + "A0514A31833D52C48A743BCDC0B58257FEDD23EE4EDBC06B574019E792B44BD6" + + "3F3770875A25075183AF2C3125302306092A864886F70D01091531160414141C" + + "1C8591A700DDE70FAC750C1539B2DFECAA3C30313021300906052B0E03021A05" + + "0004143706E218219A899C700BD7AE3E8650FD1B2885AB0408E77FDD798BCADE" + + "3C02020800").HexToByteArray(); + + internal static readonly byte[] ECDsabrainpoolP160r1_CertificatePemBytes = ByteUtils.AsciiBytes( + @"-----BEGIN CERTIFICATE----- +MIIB+TCCAbagAwIBAgIJAIJ8gBL6U36GMAoGCCqGSM49BAMCMHAxCzAJBgNVBAYT +AlVTMRUwEwYDVQQIDAxOb3J0aCBEYWtvdGExDjAMBgNVBAcMBUZhcmdvMRgwFgYD +VQQKDA9NaWNyb3NvZnQgQ29ycC4xIDAeBgNVBAsMFy5ORVQgRnJhbWV3b3JrIChD +b3JlRngpMB4XDTE2MDYxMDE0NTYzOFoXDTE2MDcxMDE0NTYzOFowcDELMAkGA1UE +BhMCVVMxFTATBgNVBAgMDE5vcnRoIERha290YTEOMAwGA1UEBwwFRmFyZ28xGDAW +BgNVBAoMD01pY3Jvc29mdCBDb3JwLjEgMB4GA1UECwwXLk5FVCBGcmFtZXdvcmsg +KENvcmVGeCkwQjAUBgcqhkjOPQIBBgkrJAMDAggBAQEDKgAEQk2dep8HoNJcbCal +ie5QIMYsNnphtOo9WUCgrrzEG3wfrxz39HcAXaNQME4wHQYDVR0OBBYEFPprBFD9 +qDQynQJmJUpVKv9WR8z5MB8GA1UdIwQYMBaAFPprBFD9qDQynQJmJUpVKv9WR8z5 +MAwGA1UdEwQFMAMBAf8wCgYIKoZIzj0EAwIDMQAwLgIVAN3U12PFcEe4HHi+Rio+ +xk3lf6EbAhUAqdeGDOXgpHEoWEmzOQ6nWWQik1k= +-----END CERTIFICATE-----"); + + internal static readonly byte[] ECDsabrainpoolP160r1_ExplicitCertificatePemBytes = ByteUtils.AsciiBytes( + @"-----BEGIN CERTIFICATE----- +MIICijCCAkigAwIBAgIJAJVtMTsUqcjsMAoGCCqGSM49BAMCMHAxCzAJBgNVBAYT +AlVTMRUwEwYDVQQIDAxOb3J0aCBEYWtvdGExDjAMBgNVBAcMBUZhcmdvMRgwFgYD +VQQKDA9NaWNyb3NvZnQgQ29ycC4xIDAeBgNVBAsMFy5ORVQgRnJhbWV3b3JrIChD +b3JlRngpMB4XDTE2MDYxMDE1MDg1NVoXDTE2MDcxMDE1MDg1NVowcDELMAkGA1UE +BhMCVVMxFTATBgNVBAgMDE5vcnRoIERha290YTEOMAwGA1UEBwwFRmFyZ28xGDAW +BgNVBAoMD01pY3Jvc29mdCBDb3JwLjEgMB4GA1UECwwXLk5FVCBGcmFtZXdvcmsg +KENvcmVGeCkwgdMwgaQGByqGSM49AgEwgZgCAQEwIAYHKoZIzj0BAQIVAOleSl9z +cFncYN/HrZWz2BOVFWIPMCwEFDQOe+KigOt04r5hutp0XZfo98MABBQeWJqFlUI0 +EhNPqi297JXI2GdeWAQpBL7VrxbqP2pPYpOMRjHrWve9vNvDFmfLR3oajsM4+UdB +ZpyXYxbaYyECFQDpXkpfc3BZ3GDfWZHUUClAnmD8CQIBAQMqAARz9ueEHonciPIW +lTsd673ZaNpP9GMoFfHns3DnUC0pC1Grh+6sZcPIo1AwTjAdBgNVHQ4EFgQU65OI +c9u4x/ZfIRyjcSaZTUKSsuIwHwYDVR0jBBgwFoAU65OIc9u4x/ZfIRyjcSaZTUKS +suIwDAYDVR0TBAUwAwEB/zAKBggqhkjOPQQDAgMwADAtAhUAxMT7z8lLv7hgWmGh +5siYmHkAExoCFFaaS2r7/kdkXsauyr37q6ewD6s+ +-----END CERTIFICATE-----"); + internal static readonly ECDsaCngKeyValues ECDsaCng256PublicKey = new ECDsaCngKeyValues() { @@ -1091,7 +1199,7 @@ wggvPj3b2WMXsVWiPr4S1Y/nBA== + "ba0d8b40f3c6dbd500e8b69f07c70c661771655228ea5a178a910ef5cb1759f6f2e062021d4f973f5bb62031be87ae915cff" + "121586809e3219af300906072a8648ce3d04010349003046022100f221063dca71955d17c8f0e0f63a144c4065578fd9f68e" + "1ae6a7683e209ea742022100ed1db6a8be27cfb20ab43e0ca061622ceff26f7249a0f791e4d6be1a4e52adfa").HexToByteArray(); - + internal static readonly ECDsaCngKeyValues ECDsaCng384PublicKey = new ECDsaCngKeyValues() { @@ -1099,7 +1207,7 @@ wggvPj3b2WMXsVWiPr4S1Y/nBA== QY = "d15f307cc6cc6c8baeeeb168bfb02c34d6eb0621efb3d06ad31c06b29eaf6ec2ec67bf288455e729d82e5a6439f70901".HexToByteArray(), D = "f55ba33e28cea32a014e2fe1213bb4d41cef361f1fee022116b15be50feb96bc946b10a46a9a7a94176787e0928a3e1d".HexToByteArray(), }; - + internal static readonly byte[] ECDsa384Certificate = ("3082015f3081e6a00302010202101e78eb573e70a2a64744672296988ad7300906072a8648ce3d0401301431123010060355" + "04031309456333383455736572301e170d3135303931303231333634365a170d3136303931303033333634365a3014311230" @@ -1109,7 +1217,7 @@ wggvPj3b2WMXsVWiPr4S1Y/nBA== + "003066023100a8fbaeeae61953897eae5f0beeeffaca48e89bc0cb782145f39f4ba5b03390ce6a28e432e664adf5ebc6a802" + "040b238b023100dcc19109383b9482fdda68f40a63ee41797dbb8f25c0284155cc4238d682fbb3fb6e86ea0933297e850a26" + "16f6c39bbf").HexToByteArray(); - + internal static readonly ECDsaCngKeyValues ECDsaCng521PublicKey = new ECDsaCngKeyValues() { @@ -1117,7 +1225,14 @@ wggvPj3b2WMXsVWiPr4S1Y/nBA== QY = "00bfe103f53cbcb039873b1a3e81a9da9abd71995e722318367281d30b35a338bf356662342b653eff38e85881863b7128ddbb856d8ae158365550bb6330b93d4ef0".HexToByteArray(), D = "0153603164bcef5c9f62388d06dcbf5681479be4397c07ff6f44bb848465e3397537d5f61abc7bc9266d4df6bae1df4847fcfd3dabdda37a2fe549b821ea858d088d".HexToByteArray(), }; - + + internal static readonly ECDsaCngKeyValues ECDsabrainpoolP160r1_PublicKey = + new ECDsaCngKeyValues() + { + QX = "424D9D7A9F07A0D25C6C26A589EE5020C62C367A".HexToByteArray(), + QY = "61B4EA3D5940A0AEBCC41B7C1FAF1CF7F477005D".HexToByteArray(), + }; + internal static readonly byte[] ECDsa521Certificate = ("308201a93082010ca00302010202102c3134fe79bb9daa48df6431f4c1e4f3300906072a8648ce3d04013014311230100603" + "5504031309456335323155736572301e170d3135303931303231333832305a170d3136303931303033333832305a30143112" -- 2.7.4