diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj
index 2cd3537ea7..1217ab3ec4 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj
+++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj
@@ -152,6 +152,9 @@
Microsoft\Data\SqlClient\AlwaysEncryptedEnclaveProviderUtils.cs
+
+ Microsoft\Data\SqlClient\AlwaysEncryptedKeyConverter.cs
+
Microsoft\Data\SqlClient\ApplicationIntent.cs
@@ -622,7 +625,6 @@
-
diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj
index e291206a4a..3dbf46c3aa 100644
--- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj
+++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj
@@ -198,6 +198,9 @@
Microsoft\Data\SqlClient\AlwaysEncryptedEnclaveProviderUtils.cs
+
+ Microsoft\Data\SqlClient\AlwaysEncryptedKeyConverter.cs
+
Microsoft\Data\SqlClient\AzureAttestationBasedEnclaveProvider.cs
@@ -652,7 +655,6 @@
-
diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/AlwaysEncryptedKeyConverter.Cng.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/AlwaysEncryptedKeyConverter.Cng.cs
deleted file mode 100644
index f0d9943ca8..0000000000
--- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/AlwaysEncryptedKeyConverter.Cng.cs
+++ /dev/null
@@ -1,71 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// 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;
-using System.Security.Cryptography;
-using System.Security.Cryptography.X509Certificates;
-
-namespace Microsoft.Data.SqlClient
-{
- internal sealed partial class KeyConverter
- {
- internal static RSA CreateRSAFromPublicKeyBlob(byte[] keyBlob)
- {
- CngKey key = CngKey.Import(keyBlob, CngKeyBlobFormat.GenericPublicBlob);
- return new RSACng(key);
- }
-
- internal static ECDiffieHellman CreateECDiffieHellmanFromPublicKeyBlob(byte[] keyBlob)
- {
- CngKey key = CngKey.Import(keyBlob, CngKeyBlobFormat.GenericPublicBlob);
- return new ECDiffieHellmanCng(key);
- }
-
- internal static ECDiffieHellman CreateECDiffieHellman(int keySize)
- {
- // Cng sets the key size and hash algorithm at creation time and these
- // parameters are then used later when DeriveKeyMaterial is called
- ECDiffieHellmanCng clientDHKey = new ECDiffieHellmanCng(keySize);
- clientDHKey.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash;
- clientDHKey.HashAlgorithm = CngAlgorithm.Sha256;
- return clientDHKey;
- }
-
- public static byte[] GetECDiffieHellmanPublicKeyBlob(ECDiffieHellman ecDiffieHellman)
- {
- if (ecDiffieHellman is ECDiffieHellmanCng cng)
- {
- return cng.Key.Export(CngKeyBlobFormat.EccPublicBlob);
- }
- else
- {
- throw new InvalidOperationException();
- }
- }
-
- internal static byte[] DeriveKey(ECDiffieHellman ecDiffieHellman, ECDiffieHellmanPublicKey publicKey)
- {
- if (ecDiffieHellman is ECDiffieHellmanCng cng)
- {
- return cng.DeriveKeyMaterial(publicKey);
- }
- else
- {
- throw new InvalidOperationException();
- }
- }
-
- internal static RSA GetRSAFromCertificate(X509Certificate2 certificate)
- {
- RSAParameters parameters;
- using (RSA rsaCsp = certificate.GetRSAPublicKey())
- {
- parameters = rsaCsp.ExportParameters(includePrivateParameters: false);
- }
- RSACng rsaCng = new RSACng();
- rsaCng.ImportParameters(parameters);
- return rsaCng;
- }
- }
-}
diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/AlwaysEncryptedKeyConverter.CrossPlatform.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/AlwaysEncryptedKeyConverter.cs
similarity index 75%
rename from src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/AlwaysEncryptedKeyConverter.CrossPlatform.cs
rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/AlwaysEncryptedKeyConverter.cs
index 8b3def875c..bad2ca5efa 100644
--- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/AlwaysEncryptedKeyConverter.CrossPlatform.cs
+++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/AlwaysEncryptedKeyConverter.cs
@@ -1,4 +1,4 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
@@ -39,6 +39,7 @@ private readonly struct ECCPublicKeyBlob
// => ECDiffieHellmanPublicKey.ToByteArray() is not supported in Unix
internal static byte[] GetECDiffieHellmanPublicKeyBlob(ECDiffieHellman ecDiffieHellman)
{
+#if NET6_0_OR_GREATER
byte[] keyBlob = new byte[ECCPublicKeyBlob.Size];
// Set magic number
@@ -53,6 +54,16 @@ internal static byte[] GetECDiffieHellmanPublicKeyBlob(ECDiffieHellman ecDiffieH
Buffer.BlockCopy(ecPoint.X, 0, keyBlob, ECCPublicKeyBlob.HeaderSize, ECCPublicKeyBlob.KeySize);
Buffer.BlockCopy(ecPoint.Y, 0, keyBlob, ECCPublicKeyBlob.HeaderSize + ECCPublicKeyBlob.KeySize, ECCPublicKeyBlob.KeySize);
return keyBlob;
+#else
+ if (ecDiffieHellman is ECDiffieHellmanCng cng)
+ {
+ return cng.Key.Export(CngKeyBlobFormat.EccPublicBlob);
+ }
+ else
+ {
+ throw new InvalidOperationException();
+ }
+#endif
}
// The RSA public key blob is structured as follows:
@@ -75,6 +86,7 @@ private readonly struct RSAPublicKeyBlob
internal static RSA CreateRSAFromPublicKeyBlob(byte[] keyBlob)
{
+#if NET6_0_OR_GREATER
Debug.Assert(keyBlob.Length == RSAPublicKeyBlob.Size, $"RSA public key blob was not the expected length. Actual: {keyBlob.Length}. Expected: {RSAPublicKeyBlob.Size}");
byte[] exponent = new byte[RSAPublicKeyBlob.ExponentSize];
@@ -87,10 +99,15 @@ internal static RSA CreateRSAFromPublicKeyBlob(byte[] keyBlob)
Modulus = modulus
};
return RSA.Create(rsaParameters);
+#else
+ CngKey key = CngKey.Import(keyBlob, CngKeyBlobFormat.GenericPublicBlob);
+ return new RSACng(key);
+#endif
}
internal static ECDiffieHellman CreateECDiffieHellmanFromPublicKeyBlob(byte[] keyBlob)
{
+#if NET6_0_OR_GREATER
Debug.Assert(keyBlob.Length == ECCPublicKeyBlob.Size, $"ECC public key blob was not the expected length. Actual: {keyBlob.Length}. Expected: {ECCPublicKeyBlob.Size}");
byte[] x = new byte[ECCPublicKeyBlob.KeySize];
@@ -109,27 +126,61 @@ internal static ECDiffieHellman CreateECDiffieHellmanFromPublicKeyBlob(byte[] ke
};
return ECDiffieHellman.Create(parameters);
+#else
+ CngKey key = CngKey.Import(keyBlob, CngKeyBlobFormat.GenericPublicBlob);
+ return new ECDiffieHellmanCng(key);
+#endif
}
internal static ECDiffieHellman CreateECDiffieHellman(int keySize)
{
+#if NET6_0_OR_GREATER
// platform agnostic creates a key of the correct size but does not
// set the key derivation type or algorithm, these must be set by calling
// DeriveKeyFromHash later in DeriveKey
ECDiffieHellman clientDHKey = ECDiffieHellman.Create();
clientDHKey.KeySize = keySize;
+#else
+ // Cng sets the key size and hash algorithm at creation time and these
+ // parameters are then used later when DeriveKeyMaterial is called
+ ECDiffieHellmanCng clientDHKey = new ECDiffieHellmanCng(keySize);
+ clientDHKey.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash;
+ clientDHKey.HashAlgorithm = CngAlgorithm.Sha256;
+#endif
return clientDHKey;
}
- internal static byte[] DeriveKey(ECDiffieHellman ecd, ECDiffieHellmanPublicKey publicKey)
+ internal static byte[] DeriveKey(ECDiffieHellman ecDiffieHellman, ECDiffieHellmanPublicKey publicKey)
{
+#if NET6_0_OR_GREATER
// see notes in CreateECDDiffieHellman
- return ecd.DeriveKeyFromHash(publicKey, HashAlgorithmName.SHA256);
+ return ecDiffieHellman.DeriveKeyFromHash(publicKey, HashAlgorithmName.SHA256);
+#else
+ if (ecDiffieHellman is ECDiffieHellmanCng cng)
+ {
+ return cng.DeriveKeyMaterial(publicKey);
+ }
+ else
+ {
+ throw new InvalidOperationException();
+ }
+#endif
}
internal static RSA GetRSAFromCertificate(X509Certificate2 certificate)
{
+#if NET6_0_OR_GREATER
return certificate.GetRSAPublicKey();
+#else
+ RSAParameters parameters;
+ using (RSA rsaCsp = certificate.GetRSAPublicKey())
+ {
+ parameters = rsaCsp.ExportParameters(includePrivateParameters: false);
+ }
+ RSACng rsaCng = new RSACng();
+ rsaCng.ImportParameters(parameters);
+ return rsaCng;
+#endif
}
}
}