From ce11bd786061f679fc07a928327af7e60e86ec5b Mon Sep 17 00:00:00 2001 From: David Engel Date: Fri, 1 Mar 2024 13:04:36 -0800 Subject: [PATCH 1/7] Remove test reference to deprecated ADAL library (#2360) --- .../ManualTests/DataCommon/AADUtility.cs | 14 ---- .../SqlClientCustomTokenCredential.cs | 67 ++++++------------- ....Data.SqlClient.ManualTesting.Tests.csproj | 2 - tools/props/Versions.props | 2 - 4 files changed, 20 insertions(+), 65 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/AADUtility.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/AADUtility.cs index 6abff25d13..7111ecbbc8 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/AADUtility.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/AADUtility.cs @@ -7,25 +7,11 @@ using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; -using Microsoft.IdentityModel.Clients.ActiveDirectory; namespace Microsoft.Data.SqlClient.ManualTesting.Tests { public static class AADUtility { - public static async Task AzureActiveDirectoryAuthenticationCallback(string authority, string resource, string scope) - { - var authContext = new AuthenticationContext(authority); - ClientCredential clientCred = new ClientCredential(DataTestUtility.AKVClientId, DataTestUtility.AKVClientSecret); - AuthenticationResult result = await authContext.AcquireTokenAsync(resource, clientCred); - if (result == null) - { - throw new Exception($"Failed to retrieve an access token for {resource}"); - } - - return result.AccessToken; - } - public static async Task GetManagedIdentityToken(string clientId = null) => await new MockManagedIdentityTokenProvider().AcquireTokenAsync(clientId).ConfigureAwait(false); diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/SqlClientCustomTokenCredential.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/SqlClientCustomTokenCredential.cs index 23ed76f81e..cfce5ae991 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/SqlClientCustomTokenCredential.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/SqlClientCustomTokenCredential.cs @@ -3,20 +3,21 @@ // See the LICENSE file in the project root for more information. using System; -using System.IdentityModel.Tokens.Jwt; +using System.Collections.Concurrent; using System.Linq; using System.Net.Http; using System.Threading; using System.Threading.Tasks; using Azure.Core; -using Microsoft.IdentityModel.Clients.ActiveDirectory; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; +using Azure.Identity; namespace Microsoft.Data.SqlClient.ManualTesting.Tests { public class SqlClientCustomTokenCredential : TokenCredential { + private const string DEFAULT_PREFIX = "/.default"; + private static readonly ConcurrentDictionary s_clientSecretCredentials = new(); + string _authority = ""; string _resource = ""; string _akvUrl = ""; @@ -70,40 +71,8 @@ private async Task AcquireTokenAsync() _akvUrl = DataTestUtility.AKVUrl; } - string strAccessToken = await AzureActiveDirectoryAuthenticationCallback(_authority, _resource); - DateTime expiryTime = InterceptAccessTokenForExpiry(strAccessToken); - return new AccessToken(strAccessToken, new DateTimeOffset(expiryTime)); - } - - private DateTime InterceptAccessTokenForExpiry(string accessToken) - { - if (null == accessToken) - { - throw new ArgumentNullException(accessToken); - } - - var jwtHandler = new JwtSecurityTokenHandler(); - var jwtOutput = string.Empty; - - // Check Token Format - if (!jwtHandler.CanReadToken(accessToken)) - throw new FormatException(accessToken); - - JwtSecurityToken token = jwtHandler.ReadJwtToken(accessToken); - - // Re-serialize the Token Headers to just Key and Values - var jwtHeader = JsonConvert.SerializeObject(token.Header.Select(h => new { h.Key, h.Value })); - jwtOutput = $"{{\r\n\"Header\":\r\n{JToken.Parse(jwtHeader)},"; - - // Re-serialize the Token Claims to just Type and Values - var jwtPayload = JsonConvert.SerializeObject(token.Claims.Select(c => new { c.Type, c.Value })); - jwtOutput += $"\r\n\"Payload\":\r\n{JToken.Parse(jwtPayload)}\r\n}}"; - - // Output the whole thing to pretty JSON object formatted. - string jToken = JToken.Parse(jwtOutput).ToString(Formatting.Indented); - JToken payload = JObject.Parse(jToken).GetValue("Payload"); - - return new DateTime(1970, 1, 1).AddSeconds((long)payload[4]["Value"]); + AccessToken accessToken = await AzureActiveDirectoryAuthenticationCallback(_authority, _resource); + return accessToken; } private static string ValidateChallenge(string challenge) @@ -127,16 +96,20 @@ private static string ValidateChallenge(string challenge) /// Authorization URL /// Resource /// - public static async Task AzureActiveDirectoryAuthenticationCallback(string authority, string resource) + public static async Task AzureActiveDirectoryAuthenticationCallback(string authority, string resource) { - var authContext = new AuthenticationContext(authority); - ClientCredential clientCred = new ClientCredential(DataTestUtility.AKVClientId, DataTestUtility.AKVClientSecret); - AuthenticationResult result = await authContext.AcquireTokenAsync(resource, clientCred); - if (result == null) - { - throw new InvalidOperationException($"Failed to retrieve an access token for {resource}"); - } - return result.AccessToken; + using CancellationTokenSource cts = new(); + cts.CancelAfter(30000); // Hard coded for tests + string[] scopes = new string[] { resource + DEFAULT_PREFIX }; + TokenRequestContext tokenRequestContext = new(scopes); + int separatorIndex = authority.LastIndexOf('/'); + string authorityHost = authority.Remove(separatorIndex + 1); + string audience = authority.Substring(separatorIndex + 1); + TokenCredentialOptions tokenCredentialOptions = new TokenCredentialOptions() { AuthorityHost = new Uri(authorityHost) }; + ClientSecretCredential clientSecretCredential = s_clientSecretCredentials.GetOrAdd(authority + "|--|" + resource, + new ClientSecretCredential(audience, DataTestUtility.AKVClientId, DataTestUtility.AKVClientSecret, tokenCredentialOptions)); + AccessToken accessToken = await clientSecretCredential.GetTokenAsync(tokenRequestContext, cts.Token).ConfigureAwait(false); + return accessToken; } } } diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj b/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj index ba5b44e1a0..bc5b324160 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj @@ -304,13 +304,11 @@ - - diff --git a/tools/props/Versions.props b/tools/props/Versions.props index b21b23d69c..fb63eb4aaf 100644 --- a/tools/props/Versions.props +++ b/tools/props/Versions.props @@ -60,7 +60,6 @@ 3.1.1 - 5.2.6 15.9.0 3.1.0 12.0.3 @@ -69,7 +68,6 @@ 4.5.0 4.6.0 4.3.0 - 6.8.0 2.4.1 5.0.0-beta.20206.4 2.0.8 From 63a61914ce3cb7b7609131196e1a74ae32b50d11 Mon Sep 17 00:00:00 2001 From: Javad Rahnama Date: Tue, 30 Apr 2024 11:00:01 -0700 Subject: [PATCH 2/7] Test | Updating tests to acquire token from user-assigned managed identity (#2473) --- BUILDGUIDE.md | 2 -- .../ManualTests/AlwaysEncrypted/AKVUnitTests.cs | 13 ++++--------- .../TestFixtures/Setup/CertificateUtility.cs | 3 +-- .../ManualTests/DataCommon/DataTestUtility.cs | 15 ++++++++++----- .../DataCommon/SqlClientCustomTokenCredential.cs | 4 +--- .../Config.cs | 2 -- .../config.default.json | 2 -- 7 files changed, 16 insertions(+), 25 deletions(-) diff --git a/BUILDGUIDE.md b/BUILDGUIDE.md index 45e971aab5..7e9e2d1e31 100644 --- a/BUILDGUIDE.md +++ b/BUILDGUIDE.md @@ -118,8 +118,6 @@ Manual Tests require the below setup to run: |AADSecurePrincipalSecret | (Optional) A Secret defined for a registered application which has been granted permission to the database defined in the AADPasswordConnectionString. | {Secret} | |AzureKeyVaultURL | (Optional) Azure Key Vault Identifier URL | `https://{keyvaultname}.vault.azure.net/` | |AzureKeyVaultTenantId | (Optional) The Azure Active Directory tenant (directory) Id of the service principal. | _{Tenant ID of Active Directory}_ | - |AzureKeyVaultClientId | (Optional) "Application (client) ID" of an Active Directory registered application, granted access to the Azure Key Vault specified in `AZURE_KEY_VAULT_URL`. Requires the key permissions Get, List, Import, Decrypt, Encrypt, Unwrap, Wrap, Verify, and Sign. | _{Client Application ID}_ | - |AzureKeyVaultClientSecret | (Optional) "Client Secret" of the Active Directory registered application, granted access to the Azure Key Vault specified in `AZURE_KEY_VAULT_URL` | _{Client Application Secret}_ | |LocalDbAppName | (Optional) If Local Db Testing is supported, this property configures the name of Local DB App instance available in client environment. Empty string value disables Local Db testing. | Name of Local Db App to connect to.| |SupportsIntegratedSecurity | (Optional) Whether or not the USER running tests has integrated security access to the target SQL Server.| `true` OR `false`| |SupportsFileStream | (Optional) Whether or not FileStream is enabled on SQL Server| `true` OR `false`| diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/AKVUnitTests.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/AKVUnitTests.cs index 7b509d6902..9b9f16d1b9 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/AKVUnitTests.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/AKVUnitTests.cs @@ -3,12 +3,10 @@ // See the LICENSE file in the project root for more information. using Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider; -using Azure.Identity; using Xunit; using Azure.Security.KeyVault.Keys; using System.Reflection; using System; -using System.Linq; using System.Collections.Generic; using System.Threading; @@ -35,8 +33,7 @@ public static void LegacyAuthenticationCallbackTest() [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.IsAKVSetupAvailable))] public static void TokenCredentialTest() { - ClientSecretCredential clientSecretCredential = new ClientSecretCredential(DataTestUtility.AKVTenantId, DataTestUtility.AKVClientId, DataTestUtility.AKVClientSecret); - SqlColumnEncryptionAzureKeyVaultProvider akvProvider = new SqlColumnEncryptionAzureKeyVaultProvider(clientSecretCredential); + SqlColumnEncryptionAzureKeyVaultProvider akvProvider = new SqlColumnEncryptionAzureKeyVaultProvider(DataTestUtility.GetTokenCredential()); byte[] encryptedCek = akvProvider.EncryptColumnEncryptionKey(DataTestUtility.AKVUrl, EncryptionAlgorithm, s_columnEncryptionKey); byte[] decryptedCek = akvProvider.DecryptColumnEncryptionKey(DataTestUtility.AKVUrl, EncryptionAlgorithm, encryptedCek); @@ -49,8 +46,7 @@ public static void TokenCredentialRotationTest() // SqlClientCustomTokenCredential implements a legacy authentication callback to request the access token from the client-side. SqlColumnEncryptionAzureKeyVaultProvider oldAkvProvider = new SqlColumnEncryptionAzureKeyVaultProvider(new SqlClientCustomTokenCredential()); - ClientSecretCredential clientSecretCredential = new ClientSecretCredential(DataTestUtility.AKVTenantId, DataTestUtility.AKVClientId, DataTestUtility.AKVClientSecret); - SqlColumnEncryptionAzureKeyVaultProvider newAkvProvider = new SqlColumnEncryptionAzureKeyVaultProvider(clientSecretCredential); + SqlColumnEncryptionAzureKeyVaultProvider newAkvProvider = new SqlColumnEncryptionAzureKeyVaultProvider(DataTestUtility.GetTokenCredential()); byte[] encryptedCekWithNewProvider = newAkvProvider.EncryptColumnEncryptionKey(DataTestUtility.AKVUrl, EncryptionAlgorithm, s_columnEncryptionKey); byte[] decryptedCekWithOldProvider = oldAkvProvider.DecryptColumnEncryptionKey(DataTestUtility.AKVUrl, EncryptionAlgorithm, encryptedCekWithNewProvider); @@ -72,15 +68,14 @@ public static void ReturnSpecifiedVersionOfKeyWhenItIsNotTheMostRecentVersion() { string keyName = keyPathUri.Segments[2]; string keyVersion = keyPathUri.Segments[3]; - ClientSecretCredential clientSecretCredential = new ClientSecretCredential(DataTestUtility.AKVTenantId, DataTestUtility.AKVClientId, DataTestUtility.AKVClientSecret); - KeyClient keyClient = new KeyClient(vaultUri, clientSecretCredential); + KeyClient keyClient = new KeyClient(vaultUri, DataTestUtility.GetTokenCredential()); KeyVaultKey currentVersionKey = keyClient.GetKey(keyName); KeyVaultKey specifiedVersionKey = keyClient.GetKey(keyName, keyVersion); //If specified versioned key is the most recent version of the key then we cannot test. if (!KeyIsLatestVersion(specifiedVersionKey, currentVersionKey)) { - SqlColumnEncryptionAzureKeyVaultProvider azureKeyProvider = new SqlColumnEncryptionAzureKeyVaultProvider(clientSecretCredential); + SqlColumnEncryptionAzureKeyVaultProvider azureKeyProvider = new SqlColumnEncryptionAzureKeyVaultProvider(DataTestUtility.GetTokenCredential()); // Perform an operation to initialize the internal caches azureKeyProvider.EncryptColumnEncryptionKey(DataTestUtility.AKVOriginalUrl, EncryptionAlgorithm, s_columnEncryptionKey); diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/TestFixtures/Setup/CertificateUtility.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/TestFixtures/Setup/CertificateUtility.cs index 1c054f3769..3d3c717b31 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/TestFixtures/Setup/CertificateUtility.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/TestFixtures/Setup/CertificateUtility.cs @@ -141,8 +141,7 @@ internal static X509Certificate2 CreateCertificate() private static async Task SetupAKVKeysAsync() { - ClientSecretCredential clientSecretCredential = new ClientSecretCredential(DataTestUtility.AKVTenantId, DataTestUtility.AKVClientId, DataTestUtility.AKVClientSecret); - KeyClient keyClient = new KeyClient(DataTestUtility.AKVBaseUri, clientSecretCredential); + KeyClient keyClient = new KeyClient(DataTestUtility.AKVBaseUri, DataTestUtility.GetTokenCredential()); AsyncPageable keys = keyClient.GetPropertiesOfKeysAsync(); IAsyncEnumerator enumerator = keys.GetAsyncEnumerator(); diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs index 8d2e7a7940..38faa25e3b 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs @@ -18,6 +18,8 @@ using Microsoft.Identity.Client; using Microsoft.Data.SqlClient.TestUtilities; using Xunit; +using Azure.Identity; +using Azure.Core; namespace Microsoft.Data.SqlClient.ManualTesting.Tests { @@ -37,8 +39,6 @@ public static class DataTestUtility public static readonly string AKVUrl = null; public static readonly string AKVOriginalUrl = null; public static readonly string AKVTenantId = null; - public static readonly string AKVClientId = null; - public static readonly string AKVClientSecret = null; public static readonly string LocalDbAppName = null; public static List AEConnStrings = new List(); public static List AEConnStringsSetup = new List(); @@ -122,8 +122,6 @@ static DataTestUtility() } AKVTenantId = c.AzureKeyVaultTenantId; - AKVClientId = c.AzureKeyVaultClientId; - AKVClientSecret = c.AzureKeyVaultClientSecret; if (EnclaveEnabled) { @@ -316,7 +314,14 @@ public static bool IsNotAzureServer() // Ref: https://feedback.azure.com/forums/307516-azure-synapse-analytics/suggestions/17858869-support-always-encrypted-in-sql-data-warehouse public static bool IsAKVSetupAvailable() { - return !string.IsNullOrEmpty(AKVUrl) && !string.IsNullOrEmpty(AKVClientId) && !string.IsNullOrEmpty(AKVClientSecret) && !string.IsNullOrEmpty(AKVTenantId) && IsNotAzureSynapse(); + return !string.IsNullOrEmpty(AKVUrl) && !string.IsNullOrEmpty(UserManagedIdentityClientId) && !string.IsNullOrEmpty(AKVTenantId) && IsNotAzureSynapse(); + } + + private static readonly DefaultAzureCredential s_defaultCredential = new(new DefaultAzureCredentialOptions { ManagedIdentityClientId = UserManagedIdentityClientId }); + + public static TokenCredential GetTokenCredential() + { + return s_defaultCredential; } public static bool IsUsingManagedSNI() => UseManagedSNIOnWindows; diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/SqlClientCustomTokenCredential.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/SqlClientCustomTokenCredential.cs index cfce5ae991..3e805ee3ca 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/SqlClientCustomTokenCredential.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/SqlClientCustomTokenCredential.cs @@ -106,9 +106,7 @@ public static async Task AzureActiveDirectoryAuthenticationCallback string authorityHost = authority.Remove(separatorIndex + 1); string audience = authority.Substring(separatorIndex + 1); TokenCredentialOptions tokenCredentialOptions = new TokenCredentialOptions() { AuthorityHost = new Uri(authorityHost) }; - ClientSecretCredential clientSecretCredential = s_clientSecretCredentials.GetOrAdd(authority + "|--|" + resource, - new ClientSecretCredential(audience, DataTestUtility.AKVClientId, DataTestUtility.AKVClientSecret, tokenCredentialOptions)); - AccessToken accessToken = await clientSecretCredential.GetTokenAsync(tokenRequestContext, cts.Token).ConfigureAwait(false); + AccessToken accessToken = await DataTestUtility.GetTokenCredential().GetTokenAsync(tokenRequestContext, cts.Token).ConfigureAwait(false); return accessToken; } } diff --git a/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/Config.cs b/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/Config.cs index e4c3796cff..7d7844e7d4 100644 --- a/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/Config.cs +++ b/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/Config.cs @@ -22,8 +22,6 @@ public class Config public string AADServicePrincipalSecret = null; public string AzureKeyVaultURL = null; public string AzureKeyVaultTenantId = null; - public string AzureKeyVaultClientId = null; - public string AzureKeyVaultClientSecret = null; public string LocalDbAppName = null; public bool EnclaveEnabled = false; public bool TracingEnabled = false; diff --git a/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/config.default.json b/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/config.default.json index 142d399e7f..8f3f2dc987 100644 --- a/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/config.default.json +++ b/src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/config.default.json @@ -13,8 +13,6 @@ "AADServicePrincipalSecret": "", "AzureKeyVaultURL": "", "AzureKeyVaultTenantId": "", - "AzureKeyVaultClientId": "", - "AzureKeyVaultClientSecret": "", "SupportsIntegratedSecurity": true, "LocalDbAppName": "", "SupportsFileStream": false, From ae31debef8e9a59282685c240099a40047e17af9 Mon Sep 17 00:00:00 2001 From: dauinsight <145612907+dauinsight@users.noreply.github.com> Date: Fri, 3 May 2024 08:32:33 -0700 Subject: [PATCH 3/7] Remove unreferenced variable Co-authored-by: David Engel --- .../ManualTests/DataCommon/SqlClientCustomTokenCredential.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/SqlClientCustomTokenCredential.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/SqlClientCustomTokenCredential.cs index 3e805ee3ca..977bc53257 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/SqlClientCustomTokenCredential.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/SqlClientCustomTokenCredential.cs @@ -16,7 +16,6 @@ namespace Microsoft.Data.SqlClient.ManualTesting.Tests public class SqlClientCustomTokenCredential : TokenCredential { private const string DEFAULT_PREFIX = "/.default"; - private static readonly ConcurrentDictionary s_clientSecretCredentials = new(); string _authority = ""; string _resource = ""; From 43519b77b4382494749bebf6e39af2a88b7b5e3c Mon Sep 17 00:00:00 2001 From: Aris Rellegue <134557572+arellegue@users.noreply.github.com> Date: Mon, 1 Apr 2024 07:47:03 -0700 Subject: [PATCH 4/7] Fix | Suppress CodeQL warning for usage of deprecated Ssl2. (#2428) --- .../Microsoft/Data/SqlClient/TdsParserHelperClasses.cs | 10 ++++++---- .../Data/SqlClient/TdsParserStateObjectNative.cs | 5 +++-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserHelperClasses.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserHelperClasses.cs index 85327b3f97..9a24c16064 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserHelperClasses.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserHelperClasses.cs @@ -1001,13 +1001,14 @@ private static string ToFriendlyName(this SslProtocols protocol) { name = "TLS 1.0"; } -#pragma warning disable CS0618 // Type or member is obsolete: SSL is depricated +// SSL 2.0 and 3.0 are only referenced to log a warning, not explicitly used for connections +#pragma warning disable CS0618, CA5397 else if ((protocol & SslProtocols.Ssl3) == SslProtocols.Ssl3) { name = "SSL 3.0"; } else if ((protocol & SslProtocols.Ssl2) == SslProtocols.Ssl2) -#pragma warning restore CS0618 // Type or member is obsolete: SSL is depricated +#pragma warning restore CS0618, CA5397 { name = "SSL 2.0"; } @@ -1027,9 +1028,10 @@ private static string ToFriendlyName(this SslProtocols protocol) public static string GetProtocolWarning(this SslProtocols protocol) { string message = string.Empty; -#pragma warning disable CS0618 // Type or member is obsolete : SSL is depricated +// SSL 2.0 and 3.0 are only referenced to log a warning, not explicitly used for connections +#pragma warning disable CS0618, CA5397 if ((protocol & (SslProtocols.Ssl2 | SslProtocols.Ssl3 | SslProtocols.Tls | SslProtocols.Tls11)) != SslProtocols.None) -#pragma warning restore CS0618 // Type or member is obsolete : SSL is depricated +#pragma warning restore CS0618, CA5397 { message = StringsHelper.Format(Strings.SEC_ProtocolWarning, protocol.ToFriendlyName()); } diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectNative.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectNative.cs index ecb6e0bb43..8be64a69d2 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectNative.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectNative.cs @@ -413,13 +413,14 @@ internal override uint WaitForSSLHandShakeToComplete(out int protocolVersion) } else if (nativeProtocol.HasFlag(NativeProtocols.SP_PROT_SSL3_CLIENT) || nativeProtocol.HasFlag(NativeProtocols.SP_PROT_SSL3_SERVER)) { -#pragma warning disable CS0618 // Type or member is obsolete : SSL is depricated +// SSL 2.0 and 3.0 are only referenced to log a warning, not explicitly used for connections +#pragma warning disable CS0618, CA5397 protocolVersion = (int)SslProtocols.Ssl3; } else if (nativeProtocol.HasFlag(NativeProtocols.SP_PROT_SSL2_CLIENT) || nativeProtocol.HasFlag(NativeProtocols.SP_PROT_SSL2_SERVER)) { protocolVersion = (int)SslProtocols.Ssl2; -#pragma warning restore CS0618 // Type or member is obsolete : SSL is depricated +#pragma warning restore CS0618, CA5397 } else if (nativeProtocol.HasFlag(NativeProtocols.SP_PROT_NONE)) { From 3b2c9ddc3acd416714708aa15d9acab54962481c Mon Sep 17 00:00:00 2001 From: Aris Rellegue <134557572+arellegue@users.noreply.github.com> Date: Mon, 1 Apr 2024 07:42:04 -0700 Subject: [PATCH 5/7] Fix | Suppress CodeQL X509RevocationMode warning. (#2432) --- .../Data/SqlClient/VirtualSecureModeEnclaveProviderBase.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProviderBase.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProviderBase.cs index 8a85725139..3ff8026f3e 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProviderBase.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProviderBase.cs @@ -243,6 +243,10 @@ private bool VerifyHealthReportAgainstRootCertificate(X509Certificate2Collection chain.ChainPolicy.ExtraStore.Add(cert); } + // An Always Encrypted-enabled driver doesn't verify an expiration date or a certificate authority chain. + // A certificate is simply used as a key pair consisting of a public and private key. This is by design. + + // CodeQL [SM00395] By design. Always Encrypted certificates should not be checked. chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; if (!chain.Build(healthReportCert)) From 6da99639b28c8cd0513b30ef193efcee6a11c9c9 Mon Sep 17 00:00:00 2001 From: dauinsight Date: Fri, 17 May 2024 10:22:42 -0700 Subject: [PATCH 6/7] Revert "Fix | Suppress CodeQL warning for usage of deprecated Ssl2. (#2428)" This reverts commit 43519b77b4382494749bebf6e39af2a88b7b5e3c. --- .../Microsoft/Data/SqlClient/TdsParserHelperClasses.cs | 10 ++++------ .../Data/SqlClient/TdsParserStateObjectNative.cs | 5 ++--- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserHelperClasses.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserHelperClasses.cs index 9a24c16064..85327b3f97 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserHelperClasses.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserHelperClasses.cs @@ -1001,14 +1001,13 @@ private static string ToFriendlyName(this SslProtocols protocol) { name = "TLS 1.0"; } -// SSL 2.0 and 3.0 are only referenced to log a warning, not explicitly used for connections -#pragma warning disable CS0618, CA5397 +#pragma warning disable CS0618 // Type or member is obsolete: SSL is depricated else if ((protocol & SslProtocols.Ssl3) == SslProtocols.Ssl3) { name = "SSL 3.0"; } else if ((protocol & SslProtocols.Ssl2) == SslProtocols.Ssl2) -#pragma warning restore CS0618, CA5397 +#pragma warning restore CS0618 // Type or member is obsolete: SSL is depricated { name = "SSL 2.0"; } @@ -1028,10 +1027,9 @@ private static string ToFriendlyName(this SslProtocols protocol) public static string GetProtocolWarning(this SslProtocols protocol) { string message = string.Empty; -// SSL 2.0 and 3.0 are only referenced to log a warning, not explicitly used for connections -#pragma warning disable CS0618, CA5397 +#pragma warning disable CS0618 // Type or member is obsolete : SSL is depricated if ((protocol & (SslProtocols.Ssl2 | SslProtocols.Ssl3 | SslProtocols.Tls | SslProtocols.Tls11)) != SslProtocols.None) -#pragma warning restore CS0618, CA5397 +#pragma warning restore CS0618 // Type or member is obsolete : SSL is depricated { message = StringsHelper.Format(Strings.SEC_ProtocolWarning, protocol.ToFriendlyName()); } diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectNative.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectNative.cs index 8be64a69d2..ecb6e0bb43 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectNative.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectNative.cs @@ -413,14 +413,13 @@ internal override uint WaitForSSLHandShakeToComplete(out int protocolVersion) } else if (nativeProtocol.HasFlag(NativeProtocols.SP_PROT_SSL3_CLIENT) || nativeProtocol.HasFlag(NativeProtocols.SP_PROT_SSL3_SERVER)) { -// SSL 2.0 and 3.0 are only referenced to log a warning, not explicitly used for connections -#pragma warning disable CS0618, CA5397 +#pragma warning disable CS0618 // Type or member is obsolete : SSL is depricated protocolVersion = (int)SslProtocols.Ssl3; } else if (nativeProtocol.HasFlag(NativeProtocols.SP_PROT_SSL2_CLIENT) || nativeProtocol.HasFlag(NativeProtocols.SP_PROT_SSL2_SERVER)) { protocolVersion = (int)SslProtocols.Ssl2; -#pragma warning restore CS0618, CA5397 +#pragma warning restore CS0618 // Type or member is obsolete : SSL is depricated } else if (nativeProtocol.HasFlag(NativeProtocols.SP_PROT_NONE)) { From 277439e26cf11f6f23d400e06f68f6085d92953c Mon Sep 17 00:00:00 2001 From: dauinsight Date: Fri, 17 May 2024 10:22:55 -0700 Subject: [PATCH 7/7] Revert "Fix | Suppress CodeQL X509RevocationMode warning. (#2432)" This reverts commit 3b2c9ddc3acd416714708aa15d9acab54962481c. --- .../Data/SqlClient/VirtualSecureModeEnclaveProviderBase.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProviderBase.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProviderBase.cs index 3ff8026f3e..8a85725139 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProviderBase.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/VirtualSecureModeEnclaveProviderBase.cs @@ -243,10 +243,6 @@ private bool VerifyHealthReportAgainstRootCertificate(X509Certificate2Collection chain.ChainPolicy.ExtraStore.Add(cert); } - // An Always Encrypted-enabled driver doesn't verify an expiration date or a certificate authority chain. - // A certificate is simply used as a key pair consisting of a public and private key. This is by design. - - // CodeQL [SM00395] By design. Always Encrypted certificates should not be checked. chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; if (!chain.Build(healthReportCert))