Skip to content

Commit 37f7fbd

Browse files
authored
Sync Crypto api usage (#1022)
1 parent 9b4cf94 commit 37f7fbd

21 files changed

+275
-1381
lines changed

src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,12 @@
318318
<Compile Include="Microsoft.Data.SqlClient.TypeForwards.cs" />
319319
</ItemGroup>
320320
<ItemGroup Condition="'$(OSGroup)' != 'AnyOS' AND '$(TargetGroup)' == 'netstandard' AND '$(TargetFramework)' == 'netstandard2.0'">
321-
<Compile Include="Microsoft\Data\SqlClient\EnclaveDelegate.NetStandard.cs" />
321+
<Compile Include="..\..\src\Microsoft\Data\SqlClient\EnclaveDelegate.NotSupported.cs">
322+
<Link>Microsoft\Data\SqlClient\EnclaveDelegate.NotSupported.cs</Link>
323+
</Compile>
324+
<Compile Include="..\..\src\Microsoft\Data\SqlClient\SqlEnclaveAttestationParameters.NotSupported.cs">
325+
<Link>Microsoft\Data\SqlClient\SqlEnclaveAttestationParameters.NotSupported.cs</Link>
326+
</Compile>
322327
</ItemGroup>
323328
<ItemGroup Condition="'$(OSGroup)' != 'AnyOS' AND '$(TargetGroup)' == 'netstandard'">
324329
<Compile Include="Microsoft\Data\SqlClient\SqlAuthenticationProviderManager.NetStandard.cs" />
@@ -335,23 +340,29 @@
335340
<Compile Include="..\..\src\Microsoft\Data\SqlClient\AlwaysEncryptedEnclaveProviderUtils.cs">
336341
<Link>Microsoft\Data\SqlClient\AlwaysEncryptedEnclaveProviderUtils.cs</Link>
337342
</Compile>
338-
<Compile Include="..\..\src\Microsoft\Data\SqlClient\AlwaysEncryptedKeyConverter.cs">
339-
<Link>Microsoft\Data\SqlClient\AlwaysEncryptedKeyConverter.cs</Link>
340-
</Compile>
343+
<Compile Include="Microsoft\Data\SqlClient\AlwaysEncryptedKeyConverter.CrossPlatform.cs" />
341344
<Compile Include="..\..\src\Microsoft\Data\SqlClient\EnclaveProviderBase.cs">
342345
<Link>Microsoft\Data\SqlClient\EnclaveProviderBase.cs</Link>
343346
</Compile>
344347
<Compile Include="..\..\src\Microsoft\Data\SqlClient\EnclaveSessionCache.cs">
345348
<Link>Microsoft\Data\SqlClient\EnclaveSessionCache.cs</Link>
346349
</Compile>
347350
<Compile Include="Microsoft\Data\SqlClient\SqlColumnEncryptionEnclaveProvider.NetCoreApp.cs" />
348-
<Compile Include="Microsoft\Data\SqlClient\SqlEnclaveAttestationParameters.NetCoreApp.cs" />
349-
<Compile Include="Microsoft\Data\SqlClient\EnclaveDelegate.CrossPlatformCrypto.cs" />
350-
<Compile Include="Microsoft\Data\SqlClient\AzureAttestationBasedEnclaveProvider.cs" />
351+
<Compile Include="..\..\src\Microsoft\Data\SqlClient\SqlEnclaveAttestationParameters.Crypto.cs">
352+
<Link>Microsoft\Data\SqlClient\SqlEnclaveAttestationParameters.Crypto.cs</Link>
353+
</Compile>
354+
<Compile Include="..\..\src\Microsoft\Data\SqlClient\EnclaveDelegate.Crypto.cs">
355+
<Link>Microsoft\Data\SqlClient\EnclaveDelegate.Crypto.cs</Link>
356+
</Compile>
357+
<Compile Include="..\..\src\Microsoft\Data\SqlClient\AzureAttestationBasedEnclaveProvider.cs">
358+
<Link>Microsoft\Data\SqlClient\AzureAttestationBasedEnclaveProvider.cs</Link>
359+
</Compile>
351360
<Compile Include="..\..\src\Microsoft\Data\SqlClient\VirtualSecureModeEnclaveProvider.cs">
352361
<Link>Microsoft\Data\SqlClient\VirtualSecureModeEnclaveProvider.cs</Link>
353362
</Compile>
354-
<Compile Include="Microsoft\Data\SqlClient\VirtualSecureModeEnclaveProviderBase.cs" />
363+
<Compile Include="..\..\src\Microsoft\Data\SqlClient\VirtualSecureModeEnclaveProviderBase.cs">
364+
<Link>Microsoft\Data\SqlClient\VirtualSecureModeEnclaveProviderBase.cs</Link>
365+
</Compile>
355366
</ItemGroup>
356367
<!-- netcoreapp 3.1 & netstandard 2.1 and above -->
357368
<ItemGroup Condition="'$(OSGroup)' != 'AnyOS' AND '$(TargetFramework)' != 'netcoreapp2.1' AND '$(TargetFramework)' != 'netstandard2.0'">
@@ -523,7 +534,6 @@
523534
<Compile Include="Microsoft\Data\SqlClient\AlwaysEncryptedHelperClasses.cs" />
524535
<Compile Include="Microsoft\Data\SqlClient\SqlQueryMetadataCache.cs" />
525536
<Compile Include="Microsoft\Data\SqlClient\SqlColumnEncryptionEnclaveProvider.cs" />
526-
<Compile Include="Microsoft\Data\SqlClient\SqlEnclaveAttestationParameters.cs" />
527537
</ItemGroup>
528538
<!-- Windows only -->
529539
<ItemGroup Condition="'$(TargetsWindows)' == 'true'">

src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/AlwaysEncryptedKeyConverter.cs renamed to src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/AlwaysEncryptedKeyConverter.CrossPlatform.cs

Lines changed: 72 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,56 @@
55
using System;
66
using System.Diagnostics;
77
using System.Security.Cryptography;
8+
using System.Security.Cryptography.X509Certificates;
89

910
namespace Microsoft.Data.SqlClient
1011
{
11-
// Contains methods to convert cryptography keys between different formats.
12-
internal sealed class KeyConverter
13-
{
12+
internal sealed partial class KeyConverter
13+
{
14+
// Magic numbers identifying blob types
15+
// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-wcce/cba27df5-4880-4f95-a879-783f8657e53b
16+
private readonly struct KeyBlobMagicNumber
17+
{
18+
internal static readonly byte[] ECDHPublicP384 = new byte[] { 0x45, 0x43, 0x4b, 0x33 };
19+
}
20+
21+
// The ECC public key blob is structured as follows:
22+
// BCRYPT_ECCKEY_BLOB header
23+
// byte[KeySize] X
24+
// byte[KeySize] Y
25+
private readonly struct ECCPublicKeyBlob
26+
{
27+
// Size of an ECC public key blob
28+
internal const int Size = 104;
29+
// Size of the BCRYPT_ECCKEY_BLOB header
30+
internal const int HeaderSize = 8;
31+
// Size of each coordinate
32+
internal const int KeySize = (Size - HeaderSize) / 2;
33+
}
34+
35+
// Serializes an ECDiffieHellmanPublicKey to an ECC public key blob
36+
// "ECDiffieHellmanPublicKey.ToByteArray() doesn't have a (standards-)defined export
37+
// format. The version used by ECDiffieHellmanPublicKeyCng is Windows-specific"
38+
// from https://github.com/dotnet/runtime/issues/27276
39+
// => ECDiffieHellmanPublicKey.ToByteArray() is not supported in Unix
40+
internal static byte[] GetECDiffieHellmanPublicKeyBlob(ECDiffieHellman ecDiffieHellman)
41+
{
42+
byte[] keyBlob = new byte[ECCPublicKeyBlob.Size];
43+
44+
// Set magic number
45+
Buffer.BlockCopy(KeyBlobMagicNumber.ECDHPublicP384, 0, keyBlob, 0, 4);
46+
// Set key size
47+
keyBlob[4] = (byte)ECCPublicKeyBlob.KeySize;
48+
49+
ECPoint ecPoint = ecDiffieHellman.PublicKey.ExportParameters().Q;
50+
Debug.Assert(ecPoint.X.Length == ECCPublicKeyBlob.KeySize && ecPoint.Y.Length == ECCPublicKeyBlob.KeySize,
51+
$"ECDH public key was not the expected length. Actual (X): {ecPoint.X.Length}. Actual (Y): {ecPoint.Y.Length} Expected: {ECCPublicKeyBlob.Size}");
52+
// Copy x and y coordinates to key blob
53+
Buffer.BlockCopy(ecPoint.X, 0, keyBlob, ECCPublicKeyBlob.HeaderSize, ECCPublicKeyBlob.KeySize);
54+
Buffer.BlockCopy(ecPoint.Y, 0, keyBlob, ECCPublicKeyBlob.HeaderSize + ECCPublicKeyBlob.KeySize, ECCPublicKeyBlob.KeySize);
55+
return keyBlob;
56+
}
57+
1458
// The RSA public key blob is structured as follows:
1559
// BCRYPT_RSAKEY_BLOB header
1660
// byte[ExponentSize] publicExponent
@@ -29,59 +73,32 @@ private readonly struct RSAPublicKeyBlob
2973
internal const int ModulusOffset = HeaderSize;
3074
}
3175

32-
// Extracts the public key's modulus and exponent from an RSA public key blob
33-
// and returns an RSAParameters object
34-
internal static RSAParameters RSAPublicKeyBlobToParams(byte[] keyBlob)
76+
internal static RSA CreateRSAFromPublicKeyBlob(byte[] keyBlob)
3577
{
36-
Debug.Assert(keyBlob.Length == RSAPublicKeyBlob.Size,
37-
$"RSA public key blob was not the expected length. Actual: {keyBlob.Length}. Expected: {RSAPublicKeyBlob.Size}");
78+
Debug.Assert(keyBlob.Length == RSAPublicKeyBlob.Size, $"RSA public key blob was not the expected length. Actual: {keyBlob.Length}. Expected: {RSAPublicKeyBlob.Size}");
3879

3980
byte[] exponent = new byte[RSAPublicKeyBlob.ExponentSize];
4081
byte[] modulus = new byte[RSAPublicKeyBlob.ModulusSize];
4182
Buffer.BlockCopy(keyBlob, RSAPublicKeyBlob.ExponentOffset, exponent, 0, RSAPublicKeyBlob.ExponentSize);
4283
Buffer.BlockCopy(keyBlob, RSAPublicKeyBlob.ModulusOffset, modulus, 0, RSAPublicKeyBlob.ModulusSize);
43-
44-
return new RSAParameters()
84+
var rsaParameters = new RSAParameters()
4585
{
4686
Exponent = exponent,
4787
Modulus = modulus
4888
};
89+
return RSA.Create(rsaParameters);
4990
}
5091

51-
// The ECC public key blob is structured as follows:
52-
// BCRYPT_ECCKEY_BLOB header
53-
// byte[KeySize] X
54-
// byte[KeySize] Y
55-
private readonly struct ECCPublicKeyBlob
56-
{
57-
// Size of an ECC public key blob
58-
internal const int Size = 104;
59-
// Size of the BCRYPT_ECCKEY_BLOB header
60-
internal const int HeaderSize = 8;
61-
// Size of each coordinate
62-
internal const int KeySize = (Size - HeaderSize) / 2;
63-
}
64-
65-
// Magic numbers identifying blob types
66-
// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-wcce/cba27df5-4880-4f95-a879-783f8657e53b
67-
private readonly struct KeyBlobMagicNumber
68-
{
69-
internal static readonly byte[] ECDHPublicP384 = new byte[] { 0x45, 0x43, 0x4b, 0x33 };
70-
}
71-
72-
// Extracts the public key's X and Y coordinates from an ECC public key blob
73-
// and returns an ECParameters object
74-
internal static ECParameters ECCPublicKeyBlobToParams(byte[] keyBlob)
92+
internal static ECDiffieHellman CreateECDiffieHellmanFromPublicKeyBlob(byte[] keyBlob)
7593
{
76-
Debug.Assert(keyBlob.Length == ECCPublicKeyBlob.Size,
77-
$"ECC public key blob was not the expected length. Actual: {keyBlob.Length}. Expected: {ECCPublicKeyBlob.Size}");
94+
Debug.Assert(keyBlob.Length == ECCPublicKeyBlob.Size, $"ECC public key blob was not the expected length. Actual: {keyBlob.Length}. Expected: {ECCPublicKeyBlob.Size}");
7895

7996
byte[] x = new byte[ECCPublicKeyBlob.KeySize];
8097
byte[] y = new byte[ECCPublicKeyBlob.KeySize];
8198
Buffer.BlockCopy(keyBlob, ECCPublicKeyBlob.HeaderSize, x, 0, ECCPublicKeyBlob.KeySize);
8299
Buffer.BlockCopy(keyBlob, ECCPublicKeyBlob.HeaderSize + ECCPublicKeyBlob.KeySize, y, 0, ECCPublicKeyBlob.KeySize);
83100

84-
return new ECParameters
101+
var parameters = new ECParameters
85102
{
86103
Curve = ECCurve.NamedCurves.nistP384,
87104
Q = new ECPoint
@@ -90,29 +107,29 @@ internal static ECParameters ECCPublicKeyBlobToParams(byte[] keyBlob)
90107
Y = y
91108
},
92109
};
110+
111+
return ECDiffieHellman.Create(parameters);
93112
}
94113

95-
// Serializes an ECDiffieHellmanPublicKey to an ECC public key blob
96-
// "ECDiffieHellmanPublicKey.ToByteArray() doesn't have a (standards-)defined export
97-
// format. The version used by ECDiffieHellmanPublicKeyCng is Windows-specific"
98-
// from https://github.com/dotnet/runtime/issues/27276
99-
// => ECDiffieHellmanPublicKey.ToByteArray() is not supported in Unix
100-
internal static byte[] ECDHPublicKeyToECCKeyBlob(ECDiffieHellmanPublicKey publicKey)
114+
internal static ECDiffieHellman CreateECDiffieHellman(int keySize)
101115
{
102-
byte[] keyBlob = new byte[ECCPublicKeyBlob.Size];
116+
// platform agnostic creates a key of the correct size but does not
117+
// set the key derivation type or algorithm, these must be set by calling
118+
// DeriveKeyFromHash later in DeriveKey
119+
ECDiffieHellman clientDHKey = ECDiffieHellman.Create();
120+
clientDHKey.KeySize = keySize;
121+
return clientDHKey;
122+
}
103123

104-
// Set magic number
105-
Buffer.BlockCopy(KeyBlobMagicNumber.ECDHPublicP384, 0, keyBlob, 0, 4);
106-
// Set key size
107-
keyBlob[4] = (byte)ECCPublicKeyBlob.KeySize;
124+
internal static byte[] DeriveKey(ECDiffieHellman ecd, ECDiffieHellmanPublicKey publicKey)
125+
{
126+
// see notes in CreateECDDiffieHellman
127+
return ecd.DeriveKeyFromHash(publicKey, HashAlgorithmName.SHA256);
128+
}
108129

109-
ECPoint ecPoint = publicKey.ExportParameters().Q;
110-
Debug.Assert(ecPoint.X.Length == ECCPublicKeyBlob.KeySize && ecPoint.Y.Length == ECCPublicKeyBlob.KeySize,
111-
$"ECDH public key was not the expected length. Actual (X): {ecPoint.X.Length}. Actual (Y): {ecPoint.Y.Length} Expected: {ECCPublicKeyBlob.Size}");
112-
// Copy x and y coordinates to key blob
113-
Buffer.BlockCopy(ecPoint.X, 0, keyBlob, ECCPublicKeyBlob.HeaderSize, ECCPublicKeyBlob.KeySize);
114-
Buffer.BlockCopy(ecPoint.Y, 0, keyBlob, ECCPublicKeyBlob.HeaderSize + ECCPublicKeyBlob.KeySize, ECCPublicKeyBlob.KeySize);
115-
return keyBlob;
130+
internal static RSA GetRSAFromCertificate(X509Certificate2 certificate)
131+
{
132+
return certificate.GetRSAPublicKey();
116133
}
117134
}
118135
}

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlEnclaveAttestationParameters.NetCoreApp.cs

Lines changed: 0 additions & 27 deletions
This file was deleted.

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlEnclaveAttestationParameters.cs

Lines changed: 0 additions & 44 deletions
This file was deleted.

0 commit comments

Comments
 (0)