From c83f380b8ef155dd4679254bf3acd70c95312551 Mon Sep 17 00:00:00 2001
From: Cheena Malhotra <13396919+cheenamalhotra@users.noreply.github.com>
Date: Tue, 28 Feb 2023 13:31:40 -0800
Subject: [PATCH] Improve secure enclaves error handling (#1880)
---
.../Connection/ConnectionService.cs | 32 +++++++++-
.../Connection/Contracts/ConnectionDetails.cs | 17 ++++++
.../Contracts/ConnectionDetailsExtensions.cs | 1 +
.../Localization/sr.cs | 30 ++++++++++
.../Localization/sr.resx | 17 +++++-
.../Localization/sr.strings | 10 +++-
.../Localization/sr.xlf | 24 ++++++--
.../Connection/ConnectionDetailsTests.cs | 3 +
.../Connection/ConnectionServiceTests.cs | 58 ++++++++++++++-----
.../Utility/SrTests.cs | 6 ++
10 files changed, 172 insertions(+), 26 deletions(-)
diff --git a/src/Microsoft.SqlTools.ServiceLayer/Connection/ConnectionService.cs b/src/Microsoft.SqlTools.ServiceLayer/Connection/ConnectionService.cs
index e56332c0..067feeff 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/Connection/ConnectionService.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/Connection/ConnectionService.cs
@@ -1349,9 +1349,24 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
throw new ArgumentException(SR.ConnectionServiceConnStringInvalidColumnEncryptionSetting(connectionDetails.ColumnEncryptionSetting));
}
}
+ if (!string.IsNullOrEmpty(connectionDetails.SecureEnclaves))
+ {
+ // Secure Enclaves is not mapped to SqlConnection, it's only used for throwing validation errors
+ // when Enclave Attestation Protocol is missing.
+ switch (connectionDetails.SecureEnclaves.ToUpper())
+ {
+ case "ENABLED":
+ break;
+ case "DISABLED":
+ break;
+ default:
+ throw new ArgumentException(SR.ConnectionServiceConnStringInvalidSecureEnclaves(connectionDetails.SecureEnclaves));
+ }
+ }
if (!string.IsNullOrEmpty(connectionDetails.EnclaveAttestationProtocol))
{
- if (string.IsNullOrEmpty(connectionDetails.ColumnEncryptionSetting) || connectionDetails.ColumnEncryptionSetting.ToUpper() == "DISABLED")
+ if (string.IsNullOrEmpty(connectionDetails.ColumnEncryptionSetting) || connectionDetails.ColumnEncryptionSetting.ToUpper() == "DISABLED"
+ || string.IsNullOrEmpty(connectionDetails.SecureEnclaves) || connectionDetails.SecureEnclaves.ToUpper() == "DISABLED")
{
throw new ArgumentException(SR.ConnectionServiceConnStringInvalidAlwaysEncryptedOptionCombination);
}
@@ -1364,7 +1379,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
case "HGS":
connectionBuilder.AttestationProtocol = SqlConnectionAttestationProtocol.HGS;
break;
- case "None":
+ case "NONE":
connectionBuilder.AttestationProtocol = SqlConnectionAttestationProtocol.None;
break;
default:
@@ -1373,13 +1388,24 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
}
if (!string.IsNullOrEmpty(connectionDetails.EnclaveAttestationUrl))
{
- if (string.IsNullOrEmpty(connectionDetails.ColumnEncryptionSetting) || connectionDetails.ColumnEncryptionSetting.ToUpper() == "DISABLED")
+ if (string.IsNullOrEmpty(connectionDetails.ColumnEncryptionSetting) || connectionDetails.ColumnEncryptionSetting.ToUpper() == "DISABLED"
+ || string.IsNullOrEmpty(connectionDetails.SecureEnclaves) || connectionDetails.SecureEnclaves.ToUpper() == "DISABLED")
{
throw new ArgumentException(SR.ConnectionServiceConnStringInvalidAlwaysEncryptedOptionCombination);
}
+ if(connectionBuilder.AttestationProtocol == SqlConnectionAttestationProtocol.None)
+ {
+ throw new ArgumentException(SR.ConnectionServiceConnStringInvalidAttestationProtocolNoneWithUrl);
+ }
+
connectionBuilder.EnclaveAttestationUrl = connectionDetails.EnclaveAttestationUrl;
}
+ else if (connectionBuilder.AttestationProtocol == SqlConnectionAttestationProtocol.AAS
+ || connectionBuilder.AttestationProtocol == SqlConnectionAttestationProtocol.HGS)
+ {
+ throw new ArgumentException(SR.ConnectionServiceConnStringMissingAttestationUrlWithAttestationProtocol);
+ }
if (!string.IsNullOrEmpty(connectionDetails.Encrypt))
{
diff --git a/src/Microsoft.SqlTools.ServiceLayer/Connection/Contracts/ConnectionDetails.cs b/src/Microsoft.SqlTools.ServiceLayer/Connection/Contracts/ConnectionDetails.cs
index 0c9ee098..0c6397f6 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/Connection/Contracts/ConnectionDetails.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/Connection/Contracts/ConnectionDetails.cs
@@ -116,6 +116,22 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection.Contracts
}
}
+ ///
+ /// Gets or sets a value that specifies that Always Encrypted with Secure Enclaves is enabled in a connection.
+ ///
+ public string SecureEnclaves
+ {
+ get
+ {
+ return GetOptionValue("secureEnclaves");
+ }
+
+ set
+ {
+ SetOptionValue("secureEnclaves", value);
+ }
+ }
+
///
/// Gets or sets a value for Attestation Protocol.
///
@@ -622,6 +638,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection.Contracts
&& string.Equals(AuthenticationType, other.AuthenticationType, System.StringComparison.InvariantCultureIgnoreCase)
&& string.Equals(AzureAccountToken, other.AzureAccountToken, System.StringComparison.InvariantCultureIgnoreCase)
&& string.Equals(ColumnEncryptionSetting, other.ColumnEncryptionSetting, System.StringComparison.InvariantCultureIgnoreCase)
+ && string.Equals(SecureEnclaves, other.SecureEnclaves, System.StringComparison.InvariantCultureIgnoreCase)
&& string.Equals(ConnectionString, other.ConnectionString, System.StringComparison.InvariantCultureIgnoreCase)
&& ConnectRetryCount == other.ConnectRetryCount
&& ConnectRetryInterval == other.ConnectRetryInterval
diff --git a/src/Microsoft.SqlTools.ServiceLayer/Connection/Contracts/ConnectionDetailsExtensions.cs b/src/Microsoft.SqlTools.ServiceLayer/Connection/Contracts/ConnectionDetailsExtensions.cs
index 390438f6..dd7794d9 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/Connection/Contracts/ConnectionDetailsExtensions.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/Connection/Contracts/ConnectionDetailsExtensions.cs
@@ -25,6 +25,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection.Contracts
Password = details.Password,
AuthenticationType = details.AuthenticationType,
ColumnEncryptionSetting = details.ColumnEncryptionSetting,
+ SecureEnclaves = details.SecureEnclaves,
EnclaveAttestationProtocol = details.EnclaveAttestationProtocol,
EnclaveAttestationUrl = details.EnclaveAttestationUrl,
Encrypt = details.Encrypt,
diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs
index 13e2fcb0..d626cd0d 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.cs
@@ -45,6 +45,14 @@ namespace Microsoft.SqlTools.ServiceLayer
}
}
+ public static string ConnectionServiceConnStringMissingAttestationUrlWithAttestationProtocol
+ {
+ get
+ {
+ return Keys.GetString(Keys.ConnectionServiceConnStringMissingAttestationUrlWithAttestationProtocol);
+ }
+ }
+
public static string ConnectionServiceConnStringInvalidAlwaysEncryptedOptionCombination
{
get
@@ -53,6 +61,14 @@ namespace Microsoft.SqlTools.ServiceLayer
}
}
+ public static string ConnectionServiceConnStringInvalidAttestationProtocolNoneWithUrl
+ {
+ get
+ {
+ return Keys.GetString(Keys.ConnectionServiceConnStringInvalidAttestationProtocolNoneWithUrl);
+ }
+ }
+
public static string ConnectionServiceConnectionCanceled
{
get
@@ -9713,6 +9729,11 @@ namespace Microsoft.SqlTools.ServiceLayer
return Keys.GetString(Keys.ConnectionServiceConnStringInvalidColumnEncryptionSetting, columnEncryptionSetting);
}
+ public static string ConnectionServiceConnStringInvalidSecureEnclaves(string secureEnclaves)
+ {
+ return Keys.GetString(Keys.ConnectionServiceConnStringInvalidSecureEnclaves, secureEnclaves);
+ }
+
public static string ConnectionServiceConnStringInvalidEncryptOption(string encrypt)
{
return Keys.GetString(Keys.ConnectionServiceConnStringInvalidEncryptOption, encrypt);
@@ -10139,15 +10160,24 @@ namespace Microsoft.SqlTools.ServiceLayer
public const string ConnectionServiceConnStringInvalidColumnEncryptionSetting = "ConnectionServiceConnStringInvalidColumnEncryptionSetting";
+ public const string ConnectionServiceConnStringInvalidSecureEnclaves = "ConnectionServiceConnStringInvalidSecureEnclaves";
+
+
public const string ConnectionServiceConnStringInvalidEncryptOption = "ConnectionServiceConnStringInvalidEncryptOption";
public const string ConnectionServiceConnStringInvalidEnclaveAttestationProtocol = "ConnectionServiceConnStringInvalidEnclaveAttestationProtocol";
+ public const string ConnectionServiceConnStringMissingAttestationUrlWithAttestationProtocol = "ConnectionServiceConnStringMissingAttestationUrlWithAttestationProtocol";
+
+
public const string ConnectionServiceConnStringInvalidAlwaysEncryptedOptionCombination = "ConnectionServiceConnStringInvalidAlwaysEncryptedOptionCombination";
+ public const string ConnectionServiceConnStringInvalidAttestationProtocolNoneWithUrl = "ConnectionServiceConnStringInvalidAttestationProtocolNoneWithUrl";
+
+
public const string ConnectionServiceConnStringInvalidIntent = "ConnectionServiceConnStringInvalidIntent";
diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx
index 5892faaa..a9fc61ba 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx
+++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.resx
@@ -144,6 +144,11 @@
Invalid value '{0}' for ComlumEncryption. Valid values are 'Enabled' and 'Disabled'..
Parameters: 0 - columnEncryptionSetting (string)
+
+
+ Invalid value '{0}' for SecureEnclaves. Valid values are 'Enabled' and 'Disabled'.
+ .
+ Parameters: 0 - secureEnclaves (string) Invalid value '{0}' for Encrypt. Valid values are 'Optional', 'Mandatory', 'Strict', 'True', 'False', 'Yes' and 'No'.
@@ -151,12 +156,20 @@
Parameters: 0 - encrypt (string)
- Invalid value '{0}' for EnclaveAttestationProtocol. Valid values are 'AAS' and 'HGS'.
+ Invalid value '{0}' for EnclaveAttestationProtocol. Valid values are 'AAS', 'HGS' and 'None'..
Parameters: 0 - enclaveAttestationProtocol (string)
+
+ Attestation URL cannot be empty with the selected value of Attestation Protocol.
+
+
- The Attestation Protocol and Enclave Attestation URL requires Always Encrypted to be set to Enabled.
+ The Attestation Protocol and Enclave Attestation URL requires Always Encrypted with Secure Enclaves to be set to Enabled.
+
+
+
+ The Enclave Attestation URL must not be specified with Attestation Protocol 'None'. Either set appropriate Attestation Protocol or remove Attestation URL from connection properties.
diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings
index cc33a7f3..830320bf 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings
+++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.strings
@@ -35,11 +35,17 @@ ConnectionServiceConnStringInvalidAuthType(string authType) = Invalid value '{0}
ConnectionServiceConnStringInvalidColumnEncryptionSetting(string columnEncryptionSetting) = Invalid value '{0}' for ComlumEncryption. Valid values are 'Enabled' and 'Disabled'.
+ConnectionServiceConnStringInvalidSecureEnclaves(string secureEnclaves) = Invalid value '{0}' for SecureEnclaves. Valid values are 'Enabled' and 'Disabled'.
+
ConnectionServiceConnStringInvalidEncryptOption(string encrypt) = Invalid value '{0}' for Encrypt. Valid values are 'Optional', 'Mandatory', 'Strict', 'True', 'False', 'Yes' and 'No'.
-ConnectionServiceConnStringInvalidEnclaveAttestationProtocol(string enclaveAttestationProtocol) = Invalid value '{0}' for EnclaveAttestationProtocol. Valid values are 'AAS' and 'HGS'.
+ConnectionServiceConnStringInvalidEnclaveAttestationProtocol(string enclaveAttestationProtocol) = Invalid value '{0}' for EnclaveAttestationProtocol. Valid values are 'AAS', 'HGS' and 'None'.
-ConnectionServiceConnStringInvalidAlwaysEncryptedOptionCombination = The Attestation Protocol and Enclave Attestation URL requires Always Encrypted to be set to Enabled.
+ConnectionServiceConnStringMissingAttestationUrlWithAttestationProtocol = Attestation URL cannot be empty with the selected value of Attestation Protocol.
+
+ConnectionServiceConnStringInvalidAlwaysEncryptedOptionCombination = The Attestation Protocol and Enclave Attestation URL requires Always Encrypted with Secure Enclaves to be set to Enabled.
+
+ConnectionServiceConnStringInvalidAttestationProtocolNoneWithUrl = The Enclave Attestation URL must not be specified with Attestation Protocol 'None'. Either set appropriate Attestation Protocol or remove Attestation URL from connection properties.
ConnectionServiceConnStringInvalidIntent(string intent) = Invalid value '{0}' for ApplicationIntent. Valid values are 'ReadWrite' and 'ReadOnly'.
diff --git a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf
index 6ae5190a..aa847071 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf
+++ b/src/Microsoft.SqlTools.ServiceLayer/Localization/sr.xlf
@@ -2042,14 +2042,14 @@
Parameters: 0 - encrypt (string)
- Invalid value '{0}' for EnclaveAttestationProtocol. Valid values are 'AAS' and 'HGS'.
- Invalid value '{0}' for EnclaveAttestationProtocol. Valid values are 'AAS' and 'HGS'.
+ Invalid value '{0}' for EnclaveAttestationProtocol. Valid values are 'AAS', 'HGS' and 'None'.
+ Invalid value '{0}' for EnclaveAttestationProtocol. Valid values are 'AAS', 'HGS' and 'None'..
Parameters: 0 - enclaveAttestationProtocol (string)
- The Attestation Protocol and Enclave Attestation URL requires Always Encrypted to be set to Enabled.
- The Attestation Protocol and Enclave Attestation URL requires Always Encrypted to be set to Enabled.
+ The Attestation Protocol and Enclave Attestation URL requires Always Encrypted with Secure Enclaves to be set to Enabled.
+ The Attestation Protocol and Enclave Attestation URL requires Always Encrypted with Secure Enclaves to be set to Enabled.
@@ -6550,6 +6550,22 @@ The Query Processor estimates that implementing the following index could improv
Built-in Schemas
+
+ Attestation URL cannot be empty with the selected value of Attestation Protocol.
+ Attestation URL cannot be empty with the selected value of Attestation Protocol.
+
+
+
+ Invalid value '{0}' for SecureEnclaves. Valid values are 'Enabled' and 'Disabled'.
+ Invalid value '{0}' for SecureEnclaves. Valid values are 'Enabled' and 'Disabled'.
+ .
+ Parameters: 0 - secureEnclaves (string)
+
+
+ The Enclave Attestation URL must not be specified with Attestation Protocol 'None'. Either set appropriate Attestation Protocol or remove Attestation URL from connection properties.
+ The Enclave Attestation URL must not be specified with Attestation Protocol 'None'. Either set appropriate Attestation Protocol or remove Attestation URL from connection properties.
+
+