Skip to content

Commit

Permalink
Refactor CngKey PCP test key creation
Browse files Browse the repository at this point in the history
  • Loading branch information
vcsjones committed Jan 13, 2023
1 parent d965006 commit 354cbd9
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 125 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;

namespace Test.Cryptography
{
internal sealed class CngPlatformProviderKey : IDisposable
{
public CngPlatformProviderKey(
CngAlgorithm algorithm,
string keySuffix = null,
[CallerMemberName] string testName = null,
params CngProperty[] additionalParameters)
{
CngKeyCreationParameters cngCreationParameters = new CngKeyCreationParameters
{
Provider = CngProvider.MicrosoftPlatformCryptoProvider,
KeyCreationOptions = CngKeyCreationOptions.OverwriteExistingKey,
};

foreach (CngProperty parameter in additionalParameters)
{
cngCreationParameters.Parameters.Add(parameter);
}

Key = CngKey.Create(algorithm, $"{testName}{algorithm.Algorithm}{keySuffix}", cngCreationParameters);
}

internal CngKey Key { get; }

public void Dispose()
{
Key.Delete();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -193,39 +193,14 @@ public static void HashAlgorithm_SupportsOtherECDHImplementations()
[OuterLoop("Hardware backed key generation takes several seconds.")]
public static void PlatformCryptoProvider_DeriveKeyMaterial()
{
CngKey key1 = null;
CngKey key2 = null;

try
{
CngKeyCreationParameters cngCreationParameters = new CngKeyCreationParameters
{
Provider = CngProvider.MicrosoftPlatformCryptoProvider,
KeyCreationOptions = CngKeyCreationOptions.OverwriteExistingKey,
};

key1 = CngKey.Create(
CngAlgorithm.ECDiffieHellmanP256,
$"{nameof(PlatformCryptoProvider_DeriveKeyMaterial)}{nameof(key1)}",
cngCreationParameters);

key2 = CngKey.Create(
CngAlgorithm.ECDiffieHellmanP256,
$"{nameof(PlatformCryptoProvider_DeriveKeyMaterial)}{nameof(key2)}",
cngCreationParameters);

using (ECDiffieHellmanCng ecdhCng1 = new ECDiffieHellmanCng(key1))
using (ECDiffieHellmanCng ecdhCng2 = new ECDiffieHellmanCng(key2))
{
byte[] derivedKey1 = ecdhCng1.DeriveKeyMaterial(key2);
byte[] derivedKey2 = ecdhCng2.DeriveKeyMaterial(key1);
Assert.Equal(derivedKey1, derivedKey2);
}
}
finally
using (CngPlatformProviderKey platformKey1 = new CngPlatformProviderKey(CngAlgorithm.ECDiffieHellmanP256, "key1"))
using (CngPlatformProviderKey platformKey2 = new CngPlatformProviderKey(CngAlgorithm.ECDiffieHellmanP256, "key2"))
using (ECDiffieHellmanCng ecdhCng1 = new ECDiffieHellmanCng(platformKey1.Key))
using (ECDiffieHellmanCng ecdhCng2 = new ECDiffieHellmanCng(platformKey2.Key))
{
key1?.Delete();
key2?.Delete();
byte[] derivedKey1 = ecdhCng1.DeriveKeyMaterial(platformKey2.Key);
byte[] derivedKey2 = ecdhCng2.DeriveKeyMaterial(platformKey1.Key);
Assert.Equal(derivedKey1, derivedKey2);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,11 @@ public static class PropertyTests
[OuterLoop("Hardware backed key generation takes several seconds.")]
public static void CreatePersisted_PlatformEccKeyHasKeySize(string algorithm, int expectedKeySize)
{
CngKey key = null;
CngAlgorithm cngAlgorithm = new CngAlgorithm(algorithm);

try
using (CngPlatformProviderKey platformKey = new CngPlatformProviderKey(cngAlgorithm))
{
key = CngKey.Create(
new CngAlgorithm(algorithm),
$"{nameof(CreatePersisted_PlatformEccKeyHasKeySize)}_{algorithm}",
new CngKeyCreationParameters
{
Provider = CngProvider.MicrosoftPlatformCryptoProvider,
KeyCreationOptions = CngKeyCreationOptions.OverwriteExistingKey,
});

Assert.Equal(expectedKeySize, key.KeySize);
}
finally
{
key?.Delete(); // Delete does a Dispose for us.
Assert.Equal(expectedKeySize, platformKey.Key.KeySize);
}
}

Expand All @@ -44,27 +31,15 @@ public static void CreatePersisted_PlatformEccKeyHasKeySize(string algorithm, in
[OuterLoop("Hardware backed key generation takes several seconds.")]
public static void CreatePersisted_PlatformRsaKeyHasKeySize(int keySize)
{
CngKey key = null;
CngProperty keyLengthProperty = new CngProperty("Length", BitConverter.GetBytes(keySize), CngPropertyOptions.None);
CngPlatformProviderKey platformKey = new CngPlatformProviderKey(
CngAlgorithm.Rsa,
keySuffix: keySize.ToString(),
additionalParameters: keyLengthProperty);

try
{
CngKeyCreationParameters cngCreationParameters = new CngKeyCreationParameters
{
Provider = CngProvider.MicrosoftPlatformCryptoProvider,
KeyCreationOptions = CngKeyCreationOptions.OverwriteExistingKey,
};
cngCreationParameters.Parameters.Add(new CngProperty("Length", BitConverter.GetBytes(keySize), CngPropertyOptions.None));

key = CngKey.Create(
CngAlgorithm.Rsa,
$"{nameof(CreatePersisted_PlatformRsaKeyHasKeySize)}_{keySize}",
cngCreationParameters);

Assert.Equal(keySize, key.KeySize);
}
finally
using (platformKey)
{
key?.Delete(); // Delete does a Dispose for us.
Assert.Equal(keySize, platformKey.Key.KeySize);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
Link="CommonTest\System\Security\Cryptography\AlgorithmImplementations\ECDiffieHellman\ECDiffieHellmanFactory.cs" />
<Compile Include="$(CommonTestPath)System\Security\Cryptography\ByteUtils.cs"
Link="CommonTest\System\Security\Cryptography\ByteUtils.cs" />
<Compile Include="$(CommonTestPath)System\Security\Cryptography\CngPlatformProviderKey.cs"
Link="CommonTest\System\Security\Cryptography\CngPlatformProviderKey.cs" />
<Compile Include="$(CommonTestPath)System\Security\Cryptography\CryptoUtils.cs"
Link="CommonTest\System\Security\Cryptography\CryptoUtils.cs" />
<Compile Include="$(CommonTestPath)System\Security\Cryptography\PlatformSupport.cs"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,8 @@
Link="CommonTest\System\Security\Cryptography\509Certificates\RevocationResponder.cs" />
<Compile Include="$(CommonTestPath)System\Security\Cryptography\ByteUtils.cs"
Link="CommonTest\System\Security\Cryptography\ByteUtils.cs" />
<Compile Include="$(CommonTestPath)System\Security\Cryptography\CngPlatformProviderKey.cs"
Link="CommonTest\System\Security\Cryptography\CngPlatformProviderKey.cs" />
<Compile Include="$(CommonTestPath)System\Security\Cryptography\CryptoUtils.cs"
Link="CommonTest\System\Security\Cryptography\CryptoUtils.cs" />
<Compile Include="$(CommonTestPath)System\Security\Cryptography\PlatformSupport.cs"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -575,80 +575,42 @@ public static void SignatureAlgorithmOidReadableForGostCertificate()
[OuterLoop("Hardware backed key generation takes several seconds.")]
public static void CreateCertificate_MicrosoftPlatformCryptoProvider_EcdsaKey()
{
CngKey key = null;

try
using (CngPlatformProviderKey platformKey = new CngPlatformProviderKey(CngAlgorithm.ECDsaP384))
using (ECDsaCng ecdsa = new ECDsaCng(platformKey.Key))
{
CngKeyCreationParameters cngCreationParameters = new CngKeyCreationParameters
{
Provider = CngProvider.MicrosoftPlatformCryptoProvider,
KeyCreationOptions = CngKeyCreationOptions.OverwriteExistingKey,
};
CertificateRequest req = new CertificateRequest("CN=potato", ecdsa, HashAlgorithmName.SHA256);

key = CngKey.Create(
CngAlgorithm.ECDsaP384,
nameof(CreateCertificate_MicrosoftPlatformCryptoProvider_EcdsaKey),
cngCreationParameters);

using (ECDsaCng ecdsa = new ECDsaCng(key))
using (X509Certificate2 cert = req.CreateSelfSigned(DateTimeOffset.UtcNow, DateTimeOffset.UtcNow))
using (ECDsa certKey = cert.GetECDsaPrivateKey())
{
CertificateRequest req = new CertificateRequest("CN=potato", ecdsa, HashAlgorithmName.SHA256);

using (X509Certificate2 cert = req.CreateSelfSigned(DateTimeOffset.UtcNow, DateTimeOffset.UtcNow))
using (ECDsa certKey = cert.GetECDsaPrivateKey())
{
Assert.NotNull(certKey);
byte[] data = new byte[] { 12, 11, 02, 08, 25, 14, 11, 18, 16 };
byte[] signature = certKey.SignData(data, HashAlgorithmName.SHA256);
bool valid = ecdsa.VerifyData(data, signature, HashAlgorithmName.SHA256);
Assert.True(valid, "valid signature");
}
Assert.NotNull(certKey);
byte[] data = new byte[] { 12, 11, 02, 08, 25, 14, 11, 18, 16 };
byte[] signature = certKey.SignData(data, HashAlgorithmName.SHA256);
bool valid = ecdsa.VerifyData(data, signature, HashAlgorithmName.SHA256);
Assert.True(valid, "valid signature");
}
}
finally
{
key?.Delete();
}
}

[ConditionalFact(typeof(PlatformSupport), nameof(PlatformSupport.PlatformCryptoProviderFunctional))]
[OuterLoop("Hardware backed key generation takes several seconds.")]
public static void CreateCertificate_MicrosoftPlatformCryptoProvider_RsaKey()
{
CngKey key = null;

try
using (CngPlatformProviderKey platformKey = new CngPlatformProviderKey(CngAlgorithm.Rsa))
using (RSACng rsa = new RSACng(platformKey.Key))
{
CngKeyCreationParameters cngCreationParameters = new CngKeyCreationParameters
{
Provider = CngProvider.MicrosoftPlatformCryptoProvider,
KeyCreationOptions = CngKeyCreationOptions.OverwriteExistingKey,
};
CertificateRequest req = new CertificateRequest("CN=potato", rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);

key = CngKey.Create(
CngAlgorithm.Rsa,
nameof(CreateCertificate_MicrosoftPlatformCryptoProvider_RsaKey),
cngCreationParameters);

using (RSACng rsa = new RSACng(key))
using (X509Certificate2 cert = req.CreateSelfSigned(DateTimeOffset.UtcNow, DateTimeOffset.UtcNow))
using (RSA certKey = cert.GetRSAPrivateKey())
{
CertificateRequest req = new CertificateRequest("CN=potato", rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);

using (X509Certificate2 cert = req.CreateSelfSigned(DateTimeOffset.UtcNow, DateTimeOffset.UtcNow))
using (RSA certKey = cert.GetRSAPrivateKey())
{
Assert.NotNull(certKey);
byte[] data = new byte[] { 12, 11, 02, 08, 25, 14, 11, 18, 16 };
byte[] signature = certKey.SignData(data, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
bool valid = rsa.VerifyData(data, signature, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
Assert.True(valid, "valid signature");
}
Assert.NotNull(certKey);
byte[] data = new byte[] { 12, 11, 02, 08, 25, 14, 11, 18, 16 };
byte[] signature = certKey.SignData(data, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
bool valid = rsa.VerifyData(data, signature, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
Assert.True(valid, "valid signature");
}
}
finally
{
key?.Delete();
}
}

public static IEnumerable<object[]> StorageFlags => CollectionImportTests.StorageFlags;
Expand Down

0 comments on commit 354cbd9

Please sign in to comment.