Skip to content

Commit d65dc86

Browse files
karinazhouDavid-Engel
authored andcommitted
Add encalve enabled always encrypted feature (dotnet#293)
1 parent b1d4b96 commit d65dc86

File tree

69 files changed

+6222
-835
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+6222
-835
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<docs>
2+
<members name="SqlConnectionAttestationProtocol">
3+
<SqlConnectionAttestationProtocol>
4+
<summary>
5+
Specifies a value for Attestation Protocol.
6+
</summary>
7+
</SqlConnectionAttestationProtocol>
8+
<NotSpecified>
9+
<summary>If the attestation protocol is not specified. Use this as default value.</summary>
10+
<value>0</value>
11+
</NotSpecified>
12+
<AAS>
13+
<summary>Attestation portocol for Azure Attestation Service</summary>
14+
<value>1</value>
15+
</AAS>
16+
<HGS>
17+
<summary>Attestation protocol for Host Guardian Service</summary>
18+
<value>3</value>
19+
</HGS>
20+
</members>
21+
</docs>

doc/snippets/Microsoft.Data.SqlClient/SqlConnectionStringBuilder.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,10 @@ False
321321
<value>The enclave attestation Url.</value>
322322
<remarks>To be added.</remarks>
323323
</EnclaveAttestationUrl>
324+
<AttestationProtocol>
325+
<summary>Set/Get the value of Attestation Protocol.</summary>
326+
<returns>Returns Attestation Protocol.</returns>
327+
</AttestationProtocol>
324328
<Encrypt>
325329
<summary>Gets or sets a Boolean value that indicates whether SQL Server uses SSL encryption for all data sent between the client and server if the server has a certificate installed.</summary>
326330
<value>The value of the <see cref="P:Microsoft.Data.SqlClient.SqlConnectionStringBuilder.Encrypt" /> property, or <see langword="false" /> if none has been supplied.</value>

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ public sealed partial class SqlConnectionStringBuilder : System.Data.Common.DbCo
5353
public Microsoft.Data.SqlClient.SqlConnectionColumnEncryptionSetting ColumnEncryptionSetting { get { throw null; } set { } }
5454
/// <include file='../../../../doc/snippets/Microsoft.Data.SqlClient/SqlConnectionStringBuilder.xml' path='docs/members[@name="SqlConnectionStringBuilder"]/EnclaveAttestationUrl/*'/>
5555
public string EnclaveAttestationUrl { get { throw null; } set { } }
56+
57+
/// <include file='../../../../doc/snippets/Microsoft.Data.SqlClient/SqlConnectionStringBuilder.xml' path='docs/members[@name="SqlConnectionStringBuilder"]/AttestationProtocol/*' />
58+
public Microsoft.Data.SqlClient.SqlConnectionAttestationProtocol AttestationProtocol {get { throw null; } set { } }
5659
}
5760
/// <include file='../../../../doc/snippets/Microsoft.Data.SqlClient/SqlParameter.xml' path='docs/members[@name="SqlParameter"]/SqlParameter/*'/>
5861
public sealed partial class SqlParameter : System.Data.Common.DbParameter, System.ICloneable, System.Data.IDataParameter, System.Data.IDbDataParameter
@@ -100,6 +103,20 @@ public enum SqlConnectionColumnEncryptionSetting
100103
/// <include file='../../../../doc/snippets/Microsoft.Data.SqlClient/SqlConnectionColumnEncryptionSetting.xml' path='docs/members[@name="SqlConnectionColumnEncryptionSetting"]/Enabled/*'/>
101104
Enabled = 1,
102105
}
106+
107+
/// <include file='..\..\..\..\doc\snippets\Microsoft.Data.SqlClient\SqlConnectionAttestationProtocol.xml' path='docs/members[@name="SqlConnectionAttestationProtocol"]/SqlConnectionAttestationProtocol/*' />
108+
public enum SqlConnectionAttestationProtocol
109+
{
110+
/// <include file='..\..\..\..\doc\snippets\Microsoft.Data.SqlClient\SqlConnectionAttestationProtocol.xml' path='docs/members[@name="SqlConnectionAttestationProtocol"]/NotSpecified/*' />
111+
NotSpecified = 0,
112+
113+
/// <include file='..\..\..\..\doc\snippets\Microsoft.Data.SqlClient\SqlConnectionAttestationProtocol.xml' path='docs/members[@name="SqlConnectionAttestationProtocol"]/AAS/*' />
114+
AAS = 1,
115+
116+
/// <include file='..\..\..\..\doc\snippets\Microsoft.Data.SqlClient\SqlConnectionAttestationProtocol.xml' path='docs/members[@name="SqlConnectionAttestationProtocol"]/HGS/*' />
117+
HGS = 3
118+
}
119+
103120
/// <include file='../../../../doc/snippets/Microsoft.Data.SqlClient/SqlColumnEncryptionCertificateStoreProvider.xml' path='docs/members[@name="SqlColumnEncryptionCertificateStoreProvider"]/SqlColumnEncryptionCertificateStoreProvider/*'/>
104121
public partial class SqlColumnEncryptionCertificateStoreProvider : Microsoft.Data.SqlClient.SqlColumnEncryptionKeyStoreProvider
105122
{

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,13 @@
4545
<Compile Include="Microsoft\Data\SqlClient\SqlDelegatedTransaction.NetCoreApp.cs" />
4646
<Compile Include="Microsoft\Data\SqlClient\TdsParser.NetCoreApp.cs" />
4747
<Compile Include="Microsoft\Data\SqlClient\SNI\SNIPacket.NetCoreApp.cs" />
48+
<Compile Include="Microsoft\Data\SqlClient\AzureAttestationBasedEnclaveProvider.NetCoreApp.cs" />
49+
<Compile Include="Microsoft\Data\SqlClient\VirtualSecureModeEnclaveProvider.NetCoreApp.cs" />
50+
<Compile Include="Microsoft\Data\SqlClient\VirtualSecureModeEnclaveProviderBase.NetCoreApp.cs" />
51+
<Compile Include="Microsoft\Data\SqlClient\AlwaysEncryptedAttestationException.NetCoreApp.cs" />
52+
<Compile Include="Microsoft\Data\SqlClient\AlwaysEncryptedEnclaveProviderUtils.NetCoreApp.cs" />
53+
<Compile Include="Microsoft\Data\SqlClient\EnclaveProviderBase.NetCoreApp.cs" />
54+
<Compile Include="Microsoft\Data\SqlClient\EnclaveSessionCache.NetCoreApp.cs" />
4855
</ItemGroup>
4956
<ItemGroup Condition="'$(IsPartialFacadeAssembly)' != 'true' AND '$(OSGroup)' != 'AnyOS' AND '$(TargetGroup)' == 'netstandard'">
5057
<Compile Include="Microsoft\Data\SqlClient\SqlDelegatedTransaction.NetStandard.cs" />
@@ -270,7 +277,6 @@
270277
<Compile Include="Microsoft\Data\SqlClient\SqlQueryMetadataCache.cs" />
271278
<Compile Include="Microsoft\Data\SqlClient\SqlColumnEncryptionEnclaveProvider.cs" />
272279
<Compile Include="Microsoft\Data\SqlClient\SqlEnclaveAttestationParameters.cs" />
273-
<Compile Include="Microsoft\Data\SqlClient\SqlColumnEncryptionEnclaveProviderConfigurationManager.cs" />
274280
<Compile Include="Microsoft\Data\SqlClient\ColumnEncryptionKeyInfo.cs" />
275281
<Compile Include="Microsoft\Data\SqlClient\EnclaveDelegate.cs" />
276282
<Compile Include="Microsoft\Data\SqlClient\DataClassification\SensitivityClassification.cs" />
@@ -587,6 +593,7 @@
587593
</EmbeddedResource>
588594
</ItemGroup>
589595
<ItemGroup>
596+
<PackageReference Include="Microsoft.IdentityModel.Protocols.OpenIdConnect" Version="5.5.0" />
590597
<PackageReference Condition="'$(TargetsWindows)' == 'true' And '$(IsPartialFacadeAssembly)' != 'true' and '$(IsUAPAssembly)' != 'true'" Include="Microsoft.Win32.Registry" Version="4.5.0" />
591598
<PackageReference Include="System.Configuration.ConfigurationManager" Version="4.5.0" />
592599
<PackageReference Include="System.Security.Permissions" Version="4.5.0" />

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/Common/DbConnectionStringCommon.cs

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,128 @@ internal static string ColumnEncryptionSettingToString(SqlConnectionColumnEncryp
214214
}
215215
}
216216

217+
#region <<AttestationProtocol Utility>>
218+
219+
/// <summary>
220+
/// Attestation Protocol.
221+
/// </summary>
222+
const string AttestationProtocolHGS = "HGS";
223+
const string AttestationProtocolAAS = "AAS";
224+
225+
/// <summary>
226+
/// Convert a string value to the corresponding SqlConnectionAttestationProtocol
227+
/// </summary>
228+
/// <param name="value"></param>
229+
/// <param name="result"></param>
230+
/// <returns></returns>
231+
internal static bool TryConvertToAttestationProtocol(string value, out SqlConnectionAttestationProtocol result)
232+
{
233+
if (StringComparer.InvariantCultureIgnoreCase.Equals(value, AttestationProtocolHGS))
234+
{
235+
result = SqlConnectionAttestationProtocol.HGS;
236+
return true;
237+
}
238+
else if (StringComparer.InvariantCultureIgnoreCase.Equals(value, AttestationProtocolAAS))
239+
{
240+
result = SqlConnectionAttestationProtocol.AAS;
241+
return true;
242+
}
243+
else
244+
{
245+
result = DbConnectionStringDefaults.AttestationProtocol;
246+
return false;
247+
}
248+
}
249+
250+
internal static bool IsValidAttestationProtocol(SqlConnectionAttestationProtocol value)
251+
{
252+
Debug.Assert(Enum.GetNames(typeof(SqlConnectionAttestationProtocol)).Length == 3, "SqlConnectionAttestationProtocol enum has changed, update needed");
253+
return value == SqlConnectionAttestationProtocol.NotSpecified
254+
|| value == SqlConnectionAttestationProtocol.HGS
255+
|| value == SqlConnectionAttestationProtocol.AAS;
256+
257+
}
258+
259+
internal static string AttestationProtocolToString(SqlConnectionAttestationProtocol value)
260+
{
261+
Debug.Assert(IsValidAttestationProtocol(value), "value is not a valid attestation protocol");
262+
263+
switch (value)
264+
{
265+
case SqlConnectionAttestationProtocol.HGS:
266+
return AttestationProtocolHGS;
267+
case SqlConnectionAttestationProtocol.AAS:
268+
return AttestationProtocolAAS;
269+
default:
270+
return null;
271+
}
272+
}
273+
274+
internal static SqlConnectionAttestationProtocol ConvertToAttestationProtocol(string keyword, object value)
275+
{
276+
if (null == value)
277+
{
278+
return DbConnectionStringDefaults.AttestationProtocol;
279+
}
280+
281+
string sValue = (value as string);
282+
SqlConnectionAttestationProtocol result;
283+
284+
if (null != sValue)
285+
{
286+
// try again after remove leading & trailing whitespaces.
287+
sValue = sValue.Trim();
288+
if (TryConvertToAttestationProtocol(sValue, out result))
289+
{
290+
return result;
291+
}
292+
293+
// string values must be valid
294+
throw ADP.InvalidConnectionOptionValue(keyword);
295+
}
296+
else
297+
{
298+
// the value is not string, try other options
299+
SqlConnectionAttestationProtocol eValue;
300+
301+
if (value is SqlConnectionAttestationProtocol)
302+
{
303+
eValue = (SqlConnectionAttestationProtocol)value;
304+
}
305+
else if (value.GetType().IsEnum)
306+
{
307+
// explicitly block scenarios in which user tries to use wrong enum types, like:
308+
// builder["SqlConnectionAttestationProtocol"] = EnvironmentVariableTarget.Process;
309+
// workaround: explicitly cast non-SqlConnectionAttestationProtocol enums to int
310+
throw ADP.ConvertFailed(value.GetType(), typeof(SqlConnectionAttestationProtocol), null);
311+
}
312+
else
313+
{
314+
try
315+
{
316+
// Enum.ToObject allows only integral and enum values (enums are blocked above), rasing ArgumentException for the rest
317+
eValue = (SqlConnectionAttestationProtocol)Enum.ToObject(typeof(SqlConnectionAttestationProtocol), value);
318+
}
319+
catch (ArgumentException e)
320+
{
321+
// to be consistent with the messages we send in case of wrong type usage, replace
322+
// the error with our exception, and keep the original one as inner one for troubleshooting
323+
throw ADP.ConvertFailed(value.GetType(), typeof(SqlConnectionAttestationProtocol), e);
324+
}
325+
}
326+
327+
if (IsValidAttestationProtocol(eValue))
328+
{
329+
return eValue;
330+
}
331+
else
332+
{
333+
throw ADP.InvalidEnumerationValue(typeof(SqlConnectionAttestationProtocol), (int)eValue);
334+
}
335+
}
336+
}
337+
338+
#endregion
217339

218340
internal static bool IsValidApplicationIntentValue(ApplicationIntent value)
219341
{
@@ -524,6 +646,7 @@ internal static partial class DbConnectionStringDefaults
524646
internal static readonly SqlAuthenticationMethod Authentication = SqlAuthenticationMethod.NotSpecified;
525647
internal const SqlConnectionColumnEncryptionSetting ColumnEncryptionSetting = SqlConnectionColumnEncryptionSetting.Disabled;
526648
internal const string EnclaveAttestationUrl = "";
649+
internal const SqlConnectionAttestationProtocol AttestationProtocol = SqlConnectionAttestationProtocol.NotSpecified;
527650
}
528651

529652

@@ -559,6 +682,7 @@ internal static partial class DbConnectionStringKeywords
559682
internal const string Authentication = "Authentication";
560683
internal const string ColumnEncryptionSetting = "Column Encryption Setting";
561684
internal const string EnclaveAttestationUrl = "Enclave Attestation Url";
685+
internal const string AttestationProtocol = "Attestation Protocol";
562686

563687
// common keywords (OleDb, OracleClient, SqlClient)
564688
internal const string DataSource = "Data Source";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System;
6+
7+
namespace Microsoft.Data.SqlClient
8+
{
9+
internal class AlwaysEncryptedAttestationException : Exception
10+
{
11+
public AlwaysEncryptedAttestationException(string message, Exception innerException) : base(message, innerException) { }
12+
13+
public AlwaysEncryptedAttestationException(string message) : base(message) { }
14+
15+
public AlwaysEncryptedAttestationException() : base() { }
16+
}
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System;
6+
using System.Linq;
7+
8+
namespace Microsoft.Data.SqlClient
9+
{
10+
internal class EnclavePublicKey
11+
{
12+
public byte[] PublicKey { get; set; }
13+
14+
public EnclavePublicKey(byte[] payload)
15+
{
16+
PublicKey = payload;
17+
}
18+
}
19+
20+
internal class EnclaveDiffieHellmanInfo
21+
{
22+
public int Size { get; private set; }
23+
24+
public byte[] PublicKey { get; private set; }
25+
26+
public byte[] PublicKeySignature { get; private set; }
27+
28+
public EnclaveDiffieHellmanInfo(byte[] payload)
29+
{
30+
Size = payload.Length;
31+
32+
int offset = 0;
33+
int publicKeySize = BitConverter.ToInt32(payload, offset);
34+
offset += sizeof(int);
35+
36+
int publicKeySignatureSize = BitConverter.ToInt32(payload, offset);
37+
offset += sizeof(int);
38+
39+
PublicKey = payload.Skip(offset).Take(publicKeySize).ToArray();
40+
offset += publicKeySize;
41+
42+
PublicKeySignature = payload.Skip(offset).Take(publicKeySignatureSize).ToArray();
43+
offset += publicKeySignatureSize;
44+
}
45+
}
46+
47+
internal enum EnclaveType
48+
{
49+
None = 0,
50+
51+
Vbs = 1,
52+
53+
Sgx = 2
54+
}
55+
}

0 commit comments

Comments
 (0)