Skip to content

Commit

Permalink
Add encalve enabled always encrypted feature (#293)
Browse files Browse the repository at this point in the history
  • Loading branch information
karinazhou authored and David-Engel committed Nov 4, 2019
1 parent b1d4b96 commit d65dc86
Show file tree
Hide file tree
Showing 69 changed files with 6,222 additions and 835 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<docs>
<members name="SqlConnectionAttestationProtocol">
<SqlConnectionAttestationProtocol>
<summary>
Specifies a value for Attestation Protocol.
</summary>
</SqlConnectionAttestationProtocol>
<NotSpecified>
<summary>If the attestation protocol is not specified. Use this as default value.</summary>
<value>0</value>
</NotSpecified>
<AAS>
<summary>Attestation portocol for Azure Attestation Service</summary>
<value>1</value>
</AAS>
<HGS>
<summary>Attestation protocol for Host Guardian Service</summary>
<value>3</value>
</HGS>
</members>
</docs>
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,10 @@ False
<value>The enclave attestation Url.</value>
<remarks>To be added.</remarks>
</EnclaveAttestationUrl>
<AttestationProtocol>
<summary>Set/Get the value of Attestation Protocol.</summary>
<returns>Returns Attestation Protocol.</returns>
</AttestationProtocol>
<Encrypt>
<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>
<value>The value of the <see cref="P:Microsoft.Data.SqlClient.SqlConnectionStringBuilder.Encrypt" /> property, or <see langword="false" /> if none has been supplied.</value>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ public sealed partial class SqlConnectionStringBuilder : System.Data.Common.DbCo
public Microsoft.Data.SqlClient.SqlConnectionColumnEncryptionSetting ColumnEncryptionSetting { get { throw null; } set { } }
/// <include file='../../../../doc/snippets/Microsoft.Data.SqlClient/SqlConnectionStringBuilder.xml' path='docs/members[@name="SqlConnectionStringBuilder"]/EnclaveAttestationUrl/*'/>
public string EnclaveAttestationUrl { get { throw null; } set { } }

/// <include file='../../../../doc/snippets/Microsoft.Data.SqlClient/SqlConnectionStringBuilder.xml' path='docs/members[@name="SqlConnectionStringBuilder"]/AttestationProtocol/*' />
public Microsoft.Data.SqlClient.SqlConnectionAttestationProtocol AttestationProtocol {get { throw null; } set { } }
}
/// <include file='../../../../doc/snippets/Microsoft.Data.SqlClient/SqlParameter.xml' path='docs/members[@name="SqlParameter"]/SqlParameter/*'/>
public sealed partial class SqlParameter : System.Data.Common.DbParameter, System.ICloneable, System.Data.IDataParameter, System.Data.IDbDataParameter
Expand Down Expand Up @@ -100,6 +103,20 @@ public enum SqlConnectionColumnEncryptionSetting
/// <include file='../../../../doc/snippets/Microsoft.Data.SqlClient/SqlConnectionColumnEncryptionSetting.xml' path='docs/members[@name="SqlConnectionColumnEncryptionSetting"]/Enabled/*'/>
Enabled = 1,
}

/// <include file='..\..\..\..\doc\snippets\Microsoft.Data.SqlClient\SqlConnectionAttestationProtocol.xml' path='docs/members[@name="SqlConnectionAttestationProtocol"]/SqlConnectionAttestationProtocol/*' />
public enum SqlConnectionAttestationProtocol
{
/// <include file='..\..\..\..\doc\snippets\Microsoft.Data.SqlClient\SqlConnectionAttestationProtocol.xml' path='docs/members[@name="SqlConnectionAttestationProtocol"]/NotSpecified/*' />
NotSpecified = 0,

/// <include file='..\..\..\..\doc\snippets\Microsoft.Data.SqlClient\SqlConnectionAttestationProtocol.xml' path='docs/members[@name="SqlConnectionAttestationProtocol"]/AAS/*' />
AAS = 1,

/// <include file='..\..\..\..\doc\snippets\Microsoft.Data.SqlClient\SqlConnectionAttestationProtocol.xml' path='docs/members[@name="SqlConnectionAttestationProtocol"]/HGS/*' />
HGS = 3
}

/// <include file='../../../../doc/snippets/Microsoft.Data.SqlClient/SqlColumnEncryptionCertificateStoreProvider.xml' path='docs/members[@name="SqlColumnEncryptionCertificateStoreProvider"]/SqlColumnEncryptionCertificateStoreProvider/*'/>
public partial class SqlColumnEncryptionCertificateStoreProvider : Microsoft.Data.SqlClient.SqlColumnEncryptionKeyStoreProvider
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@
<Compile Include="Microsoft\Data\SqlClient\SqlDelegatedTransaction.NetCoreApp.cs" />
<Compile Include="Microsoft\Data\SqlClient\TdsParser.NetCoreApp.cs" />
<Compile Include="Microsoft\Data\SqlClient\SNI\SNIPacket.NetCoreApp.cs" />
<Compile Include="Microsoft\Data\SqlClient\AzureAttestationBasedEnclaveProvider.NetCoreApp.cs" />
<Compile Include="Microsoft\Data\SqlClient\VirtualSecureModeEnclaveProvider.NetCoreApp.cs" />
<Compile Include="Microsoft\Data\SqlClient\VirtualSecureModeEnclaveProviderBase.NetCoreApp.cs" />
<Compile Include="Microsoft\Data\SqlClient\AlwaysEncryptedAttestationException.NetCoreApp.cs" />
<Compile Include="Microsoft\Data\SqlClient\AlwaysEncryptedEnclaveProviderUtils.NetCoreApp.cs" />
<Compile Include="Microsoft\Data\SqlClient\EnclaveProviderBase.NetCoreApp.cs" />
<Compile Include="Microsoft\Data\SqlClient\EnclaveSessionCache.NetCoreApp.cs" />
</ItemGroup>
<ItemGroup Condition="'$(IsPartialFacadeAssembly)' != 'true' AND '$(OSGroup)' != 'AnyOS' AND '$(TargetGroup)' == 'netstandard'">
<Compile Include="Microsoft\Data\SqlClient\SqlDelegatedTransaction.NetStandard.cs" />
Expand Down Expand Up @@ -270,7 +277,6 @@
<Compile Include="Microsoft\Data\SqlClient\SqlQueryMetadataCache.cs" />
<Compile Include="Microsoft\Data\SqlClient\SqlColumnEncryptionEnclaveProvider.cs" />
<Compile Include="Microsoft\Data\SqlClient\SqlEnclaveAttestationParameters.cs" />
<Compile Include="Microsoft\Data\SqlClient\SqlColumnEncryptionEnclaveProviderConfigurationManager.cs" />
<Compile Include="Microsoft\Data\SqlClient\ColumnEncryptionKeyInfo.cs" />
<Compile Include="Microsoft\Data\SqlClient\EnclaveDelegate.cs" />
<Compile Include="Microsoft\Data\SqlClient\DataClassification\SensitivityClassification.cs" />
Expand Down Expand Up @@ -587,6 +593,7 @@
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.IdentityModel.Protocols.OpenIdConnect" Version="5.5.0" />
<PackageReference Condition="'$(TargetsWindows)' == 'true' And '$(IsPartialFacadeAssembly)' != 'true' and '$(IsUAPAssembly)' != 'true'" Include="Microsoft.Win32.Registry" Version="4.5.0" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="4.5.0" />
<PackageReference Include="System.Security.Permissions" Version="4.5.0" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,128 @@ internal static string ColumnEncryptionSettingToString(SqlConnectionColumnEncryp
}
}

#region <<AttestationProtocol Utility>>

/// <summary>
/// Attestation Protocol.
/// </summary>
const string AttestationProtocolHGS = "HGS";
const string AttestationProtocolAAS = "AAS";

/// <summary>
/// Convert a string value to the corresponding SqlConnectionAttestationProtocol
/// </summary>
/// <param name="value"></param>
/// <param name="result"></param>
/// <returns></returns>
internal static bool TryConvertToAttestationProtocol(string value, out SqlConnectionAttestationProtocol result)
{
if (StringComparer.InvariantCultureIgnoreCase.Equals(value, AttestationProtocolHGS))
{
result = SqlConnectionAttestationProtocol.HGS;
return true;
}
else if (StringComparer.InvariantCultureIgnoreCase.Equals(value, AttestationProtocolAAS))
{
result = SqlConnectionAttestationProtocol.AAS;
return true;
}
else
{
result = DbConnectionStringDefaults.AttestationProtocol;
return false;
}
}

internal static bool IsValidAttestationProtocol(SqlConnectionAttestationProtocol value)
{
Debug.Assert(Enum.GetNames(typeof(SqlConnectionAttestationProtocol)).Length == 3, "SqlConnectionAttestationProtocol enum has changed, update needed");
return value == SqlConnectionAttestationProtocol.NotSpecified
|| value == SqlConnectionAttestationProtocol.HGS
|| value == SqlConnectionAttestationProtocol.AAS;

}

internal static string AttestationProtocolToString(SqlConnectionAttestationProtocol value)
{
Debug.Assert(IsValidAttestationProtocol(value), "value is not a valid attestation protocol");

switch (value)
{
case SqlConnectionAttestationProtocol.HGS:
return AttestationProtocolHGS;
case SqlConnectionAttestationProtocol.AAS:
return AttestationProtocolAAS;
default:
return null;
}
}

internal static SqlConnectionAttestationProtocol ConvertToAttestationProtocol(string keyword, object value)
{
if (null == value)
{
return DbConnectionStringDefaults.AttestationProtocol;
}

string sValue = (value as string);
SqlConnectionAttestationProtocol result;

if (null != sValue)
{
// try again after remove leading & trailing whitespaces.
sValue = sValue.Trim();
if (TryConvertToAttestationProtocol(sValue, out result))
{
return result;
}

// string values must be valid
throw ADP.InvalidConnectionOptionValue(keyword);
}
else
{
// the value is not string, try other options
SqlConnectionAttestationProtocol eValue;

if (value is SqlConnectionAttestationProtocol)
{
eValue = (SqlConnectionAttestationProtocol)value;
}
else if (value.GetType().IsEnum)
{
// explicitly block scenarios in which user tries to use wrong enum types, like:
// builder["SqlConnectionAttestationProtocol"] = EnvironmentVariableTarget.Process;
// workaround: explicitly cast non-SqlConnectionAttestationProtocol enums to int
throw ADP.ConvertFailed(value.GetType(), typeof(SqlConnectionAttestationProtocol), null);
}
else
{
try
{
// Enum.ToObject allows only integral and enum values (enums are blocked above), rasing ArgumentException for the rest
eValue = (SqlConnectionAttestationProtocol)Enum.ToObject(typeof(SqlConnectionAttestationProtocol), value);
}
catch (ArgumentException e)
{
// to be consistent with the messages we send in case of wrong type usage, replace
// the error with our exception, and keep the original one as inner one for troubleshooting
throw ADP.ConvertFailed(value.GetType(), typeof(SqlConnectionAttestationProtocol), e);
}
}

if (IsValidAttestationProtocol(eValue))
{
return eValue;
}
else
{
throw ADP.InvalidEnumerationValue(typeof(SqlConnectionAttestationProtocol), (int)eValue);
}
}
}

#endregion

internal static bool IsValidApplicationIntentValue(ApplicationIntent value)
{
Expand Down Expand Up @@ -524,6 +646,7 @@ internal static partial class DbConnectionStringDefaults
internal static readonly SqlAuthenticationMethod Authentication = SqlAuthenticationMethod.NotSpecified;
internal const SqlConnectionColumnEncryptionSetting ColumnEncryptionSetting = SqlConnectionColumnEncryptionSetting.Disabled;
internal const string EnclaveAttestationUrl = "";
internal const SqlConnectionAttestationProtocol AttestationProtocol = SqlConnectionAttestationProtocol.NotSpecified;
}


Expand Down Expand Up @@ -559,6 +682,7 @@ internal static partial class DbConnectionStringKeywords
internal const string Authentication = "Authentication";
internal const string ColumnEncryptionSetting = "Column Encryption Setting";
internal const string EnclaveAttestationUrl = "Enclave Attestation Url";
internal const string AttestationProtocol = "Attestation Protocol";

// common keywords (OleDb, OracleClient, SqlClient)
internal const string DataSource = "Data Source";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// 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;

namespace Microsoft.Data.SqlClient
{
internal class AlwaysEncryptedAttestationException : Exception
{
public AlwaysEncryptedAttestationException(string message, Exception innerException) : base(message, innerException) { }

public AlwaysEncryptedAttestationException(string message) : base(message) { }

public AlwaysEncryptedAttestationException() : base() { }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// 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.Linq;

namespace Microsoft.Data.SqlClient
{
internal class EnclavePublicKey
{
public byte[] PublicKey { get; set; }

public EnclavePublicKey(byte[] payload)
{
PublicKey = payload;
}
}

internal class EnclaveDiffieHellmanInfo
{
public int Size { get; private set; }

public byte[] PublicKey { get; private set; }

public byte[] PublicKeySignature { get; private set; }

public EnclaveDiffieHellmanInfo(byte[] payload)
{
Size = payload.Length;

int offset = 0;
int publicKeySize = BitConverter.ToInt32(payload, offset);
offset += sizeof(int);

int publicKeySignatureSize = BitConverter.ToInt32(payload, offset);
offset += sizeof(int);

PublicKey = payload.Skip(offset).Take(publicKeySize).ToArray();
offset += publicKeySize;

PublicKeySignature = payload.Skip(offset).Take(publicKeySignatureSize).ToArray();
offset += publicKeySignatureSize;
}
}

internal enum EnclaveType
{
None = 0,

Vbs = 1,

Sgx = 2
}
}
Loading

0 comments on commit d65dc86

Please sign in to comment.