diff --git a/eng/pipelines/common/templates/steps/publish-test-results-step.yml b/eng/pipelines/common/templates/steps/publish-test-results-step.yml index 791a8201b2..de1048580b 100644 --- a/eng/pipelines/common/templates/steps/publish-test-results-step.yml +++ b/eng/pipelines/common/templates/steps/publish-test-results-step.yml @@ -38,6 +38,7 @@ steps: TestResults/*.trx TestResults/**/*.coverage testRunTitle: 'Linux Tests' + condition: succeededOrFailed() - powershell: | cd TestResults diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj index 9dae90ffd0..649c2c8c96 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj @@ -567,6 +567,9 @@ Microsoft\Data\SqlClient\SqlCollation.cs + + Microsoft\Data\SqlClient\SqlColumnEncryptionCertificateStoreProvider.cs + Microsoft\Data\SqlClient\SqlColumnEncryptionEnclaveProvider.cs @@ -950,9 +953,6 @@ Microsoft\Data\SqlClient\SSPI\NativeSspiContextProvider.cs - - Microsoft\Data\SqlClient\SqlColumnEncryptionCertificateStoreProvider.Windows.cs - Microsoft\Data\SqlClient\TdsParserSafeHandles.Windows.cs @@ -988,9 +988,6 @@ Microsoft\Data\SqlClient\SessionHandle.netcore.Unix.cs - - Microsoft\Data\SqlClinet\SqlColumnEncryptionCertificateStoreProvider.netcore.Unix.cs - Microsoft\Data\SqlClinet\SqlColumnEncryptionCngProvider.netcore.Unix.cs diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj index 9ce3b09334..5a05345f34 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj @@ -678,7 +678,7 @@ Microsoft\Data\SqlClient\SqlCollation.cs - + Microsoft\Data\SqlClient\SqlColumnEncryptionCertificateStoreProvider.cs diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlColumnEncryptionCertificateStoreProvider.Windows.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlColumnEncryptionCertificateStoreProvider.cs similarity index 98% rename from src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlColumnEncryptionCertificateStoreProvider.Windows.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlColumnEncryptionCertificateStoreProvider.cs index 9960447465..73e8584b20 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlColumnEncryptionCertificateStoreProvider.Windows.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlColumnEncryptionCertificateStoreProvider.cs @@ -324,7 +324,9 @@ private void ValidateCertificatePathLength(string masterKeyPath, bool isSystemOp /// private string[] GetValidCertificateLocations() { - return new string[2] { CertLocationLocalMachine, CertLocationCurrentUser }; + return Environment.OSVersion.Platform == PlatformID.Win32NT + ? new string[2] { CertLocationLocalMachine, CertLocationCurrentUser } + : new string[1] { CertLocationCurrentUser }; } /// @@ -372,7 +374,8 @@ private X509Certificate2 GetCertificateByPath(string keyPath, bool isSystemOp) // Extract the store location where the cert is stored if (certParts.Length > 2) { - if (string.Equals(certParts[0], CertLocationLocalMachine, StringComparison.OrdinalIgnoreCase) == true) + if (string.Equals(certParts[0], CertLocationLocalMachine, StringComparison.OrdinalIgnoreCase) == true + && Environment.OSVersion.Platform == PlatformID.Win32NT) { storeLocation = StoreLocation.LocalMachine; } diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlColumnEncryptionCertificateStoreProvider.netcore.Unix.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlColumnEncryptionCertificateStoreProvider.netcore.Unix.cs deleted file mode 100644 index 598385851c..0000000000 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlColumnEncryptionCertificateStoreProvider.netcore.Unix.cs +++ /dev/null @@ -1,72 +0,0 @@ -// 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. - -#if NET - -using System; - -namespace Microsoft.Data.SqlClient -{ - /// - public class SqlColumnEncryptionCertificateStoreProvider : SqlColumnEncryptionKeyStoreProvider - { - /// - /// Name for the certificate key store provider. - /// - public const string ProviderName = @"MSSQL_CERTIFICATE_STORE"; - - /// - /// This function uses a certificate specified by the key path - /// and decrypts an encrypted CEK with RSA encryption algorithm. - /// - /// Complete path of a certificate - /// Asymmetric Key Encryption Algorithm - /// Encrypted Column Encryption Key - /// Plain text column encryption key - public override byte[] DecryptColumnEncryptionKey(string masterKeyPath, string encryptionAlgorithm, byte[] encryptedColumnEncryptionKey) - { - throw new PlatformNotSupportedException(); - } - - /// - /// This function uses a certificate specified by the key path - /// and encrypts CEK with RSA encryption algorithm. - /// - /// Complete path of a certificate - /// Asymmetric Key Encryption Algorithm - /// The plaintext column encryption key - /// Encrypted column encryption key - public override byte[] EncryptColumnEncryptionKey(string masterKeyPath, string encryptionAlgorithm, byte[] columnEncryptionKey) - { - throw new PlatformNotSupportedException(); - } - - /// - /// This function must be implemented by the corresponding Key Store providers. This function should use an asymmetric key identified by a key path - /// and sign the masterkey metadata consisting of (masterKeyPath, allowEnclaveComputations bit, providerName). - /// - /// Complete path of an asymmetric key. Path format is specific to a key store provider. - /// Boolean indicating whether this key can be sent to trusted enclave - /// Signature for master key metadata - public override byte[] SignColumnMasterKeyMetadata(string masterKeyPath, bool allowEnclaveComputations) - { - throw new PlatformNotSupportedException(); - } - - /// - /// This function must be implemented by the corresponding Key Store providers. This function should use an asymmetric key identified by a key path - /// and verify the masterkey metadata consisting of (masterKeyPath, allowEnclaveComputations bit, providerName). - /// - /// Complete path of an asymmetric key. Path format is specific to a key store provider. - /// Boolean indicating whether this key can be sent to trusted enclave - /// Signature for the master key metadata - /// Boolean indicating whether the master key metadata can be verified based on the provided signature - public override bool VerifyColumnMasterKeyMetadata(string masterKeyPath, bool allowEnclaveComputations, byte[] signature) - { - throw new PlatformNotSupportedException(); - } - } -} - -#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlUtil.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlUtil.cs index 06564633e8..35e4ebb356 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlUtil.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlUtil.cs @@ -1683,14 +1683,29 @@ internal static Exception LargeCertificatePathLength(int actualLength, int maxLe internal static Exception NullCertificatePath(string[] validLocations, bool isSystemOp) { - Debug.Assert(2 == validLocations.Length); - if (isSystemOp) + if (Environment.OSVersion.Platform == PlatformID.Win32NT) { - return ADP.ArgumentNull(TdsEnums.TCE_PARAM_MASTERKEY_PATH, StringsHelper.GetString(Strings.TCE_NullCertificatePathSysErr, validLocations[0], validLocations[1], @"/")); + Debug.Assert(validLocations.Length == 2); + if (isSystemOp) + { + return ADP.ArgumentNull(TdsEnums.TCE_PARAM_MASTERKEY_PATH, StringsHelper.GetString(Strings.TCE_NullCertificatePathSysErr, validLocations[0], validLocations[1], @"/")); + } + else + { + return ADP.ArgumentNull(TdsEnums.TCE_PARAM_MASTERKEY_PATH, StringsHelper.GetString(Strings.TCE_NullCertificatePath, validLocations[0], validLocations[1], @"/")); + } } else { - return ADP.ArgumentNull(TdsEnums.TCE_PARAM_MASTERKEY_PATH, StringsHelper.GetString(Strings.TCE_NullCertificatePath, validLocations[0], validLocations[1], @"/")); + Debug.Assert(validLocations.Length == 1); + if (isSystemOp) + { + return ADP.ArgumentNull(TdsEnums.TCE_PARAM_MASTERKEY_PATH, StringsHelper.GetString(Strings.TCE_NullCertificatePathSysErr_Unix, validLocations[0], @"/")); + } + else + { + return ADP.ArgumentNull(TdsEnums.TCE_PARAM_MASTERKEY_PATH, StringsHelper.GetString(Strings.TCE_NullCertificatePath_Unix, validLocations[0], @"/")); + } } } @@ -1720,14 +1735,29 @@ internal static Exception NullCngKeyPath(bool isSystemOp) internal static Exception InvalidCertificatePath(string actualCertificatePath, string[] validLocations, bool isSystemOp) { - Debug.Assert(2 == validLocations.Length); - if (isSystemOp) + if (Environment.OSVersion.Platform == PlatformID.Win32NT) { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCertificatePathSysErr, actualCertificatePath, validLocations[0], validLocations[1], @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); + Debug.Assert(validLocations.Length == 2); + if (isSystemOp) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCertificatePathSysErr, actualCertificatePath, validLocations[0], validLocations[1], @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); + } + else + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCertificatePath, actualCertificatePath, validLocations[0], validLocations[1], @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); + } } else { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCertificatePath, actualCertificatePath, validLocations[0], validLocations[1], @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); + Debug.Assert(validLocations.Length == 1); + if (isSystemOp) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCertificatePathSysErr_Unix, actualCertificatePath, validLocations[0], @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); + } + else + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCertificatePath_Unix, actualCertificatePath, validLocations[0], @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); + } } } @@ -1841,17 +1871,29 @@ internal static Exception InvalidCngKey(string masterKeyPath, string cngProvider internal static Exception InvalidCertificateLocation(string certificateLocation, string certificatePath, string[] validLocations, bool isSystemOp) { - -#if NETFRAMEWORK - Debug.Assert(2 == validLocations.Length); -#endif - if (isSystemOp) + if (Environment.OSVersion.Platform == PlatformID.Win32NT) { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCertificateLocationSysErr, certificateLocation, certificatePath, validLocations[0], validLocations[1], @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); + Debug.Assert(validLocations.Length == 2); + if (isSystemOp) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCertificateLocationSysErr, certificateLocation, certificatePath, validLocations[0], validLocations[1], @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); + } + else + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCertificateLocation, certificateLocation, certificatePath, validLocations[0], validLocations[1], @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); + } } else { - return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCertificateLocation, certificateLocation, certificatePath, validLocations[0], validLocations[1], @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); + Debug.Assert(validLocations.Length == 1); + if (isSystemOp) + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCertificateLocationSysErr_Unix, certificateLocation, certificatePath, validLocations[0], @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); + } + else + { + return ADP.Argument(StringsHelper.GetString(Strings.TCE_InvalidCertificateLocation_Unix, certificateLocation, certificatePath, validLocations[0], @"/"), TdsEnums.TCE_PARAM_MASTERKEY_PATH); + } } } diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Strings.Designer.cs b/src/Microsoft.Data.SqlClient/src/Resources/Strings.Designer.cs index b41b331db7..d056631873 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Strings.Designer.cs +++ b/src/Microsoft.Data.SqlClient/src/Resources/Strings.Designer.cs @@ -12818,7 +12818,18 @@ internal static string TCE_InvalidCertificateLocation { return ResourceManager.GetString("TCE_InvalidCertificateLocation", resourceCulture); } } - + + /// + /// Looks up a localized string similar to Invalid certificate location '{0}' in certificate path '{1}'. Use the following format: <certificate location>{3}<certificate store>{3}<certificate thumbprint>, where <certificate location> is '{2}'.. + /// + internal static string TCE_InvalidCertificateLocation_Unix + { + get + { + return ResourceManager.GetString("TCE_InvalidCertificateLocation_Unix", resourceCulture); + } + } + /// /// Looks up a localized string similar to Internal error. Invalid certificate location '{0}' in certificate path '{1}'. Use the following format: <certificate location>{4}<certificate store>{4}<certificate thumbprint>, where <certificate location> is either '{2}' or '{3}'.. /// @@ -12827,7 +12838,18 @@ internal static string TCE_InvalidCertificateLocationSysErr { return ResourceManager.GetString("TCE_InvalidCertificateLocationSysErr", resourceCulture); } } - + + /// + /// Looks up a localized string similar to Internal error. Invalid certificate location '{0}' in certificate path '{1}'. Use the following format: <certificate location>{3}<certificate store>{3}<certificate thumbprint>, where <certificate location> is '{2}'.. + /// + internal static string TCE_InvalidCertificateLocationSysErr_Unix + { + get + { + return ResourceManager.GetString("TCE_InvalidCertificateLocationSysErr_Unix", resourceCulture); + } + } + /// /// Looks up a localized string similar to Invalid certificate path: '{0}'. Use the following format: <certificate location>{3}<certificate store>{3}<certificate thumbprint>, where <certificate location> is either '{1}' or '{2}'.. /// @@ -12836,7 +12858,18 @@ internal static string TCE_InvalidCertificatePath { return ResourceManager.GetString("TCE_InvalidCertificatePath", resourceCulture); } } - + + /// + /// Looks up a localized string similar to Invalid certificate path: '{0}'. Use the following format: <certificate location>{2}<certificate store>{2}<certificate thumbprint>, where <certificate location> is '{1}'.. + /// + internal static string TCE_InvalidCertificatePath_Unix + { + get + { + return ResourceManager.GetString("TCE_InvalidCertificatePath_Unix", resourceCulture); + } + } + /// /// Looks up a localized string similar to Internal error. Invalid certificate path: '{0}'. Use the following format: <certificate location>{3}<certificate store>{3}<certificate thumbprint>, where <certificate location> is either '{1}' or '{2}'.. /// @@ -12845,7 +12878,18 @@ internal static string TCE_InvalidCertificatePathSysErr { return ResourceManager.GetString("TCE_InvalidCertificatePathSysErr", resourceCulture); } } - + + /// + /// Looks up a localized string similar to Internal error. Invalid certificate path: '{0}'. Use the following format: <certificate location>{2}<certificate store>{2}<certificate thumbprint>, where <certificate location> is '{1}'.. + /// + internal static string TCE_InvalidCertificatePathSysErr_Unix + { + get + { + return ResourceManager.GetString("TCE_InvalidCertificatePathSysErr_Unix", resourceCulture); + } + } + /// /// Looks up a localized string similar to The specified encrypted column encryption key signature does not match the signature computed with the column master key (certificate) in '{0}'. The encrypted column encryption key may be corrupt, or the specified path may be incorrect.. /// @@ -13223,7 +13267,18 @@ internal static string TCE_NullCertificatePath { return ResourceManager.GetString("TCE_NullCertificatePath", resourceCulture); } } - + + /// + /// Looks up a localized string similar to Certificate path cannot be null. Use the following format: <certificate location>{1}<certificate store>{1}<certificate thumbprint>, where <certificate location> is '{0}'.. + /// + internal static string TCE_NullCertificatePath_Unix + { + get + { + return ResourceManager.GetString("TCE_NullCertificatePath_Unix", resourceCulture); + } + } + /// /// Looks up a localized string similar to Internal error. Certificate path cannot be null. Use the following format: <certificate location>{2}<certificate store>{2}<certificate thumbprint>, where <certificate location> is either '{0}' or '{1}'.. /// @@ -13232,7 +13287,18 @@ internal static string TCE_NullCertificatePathSysErr { return ResourceManager.GetString("TCE_NullCertificatePathSysErr", resourceCulture); } } - + + /// + /// Looks up a localized string similar to Internal error. Certificate path cannot be null. Use the following format: <certificate location>{1}<certificate store>{1}<certificate thumbprint>, where <certificate location> is '{0}'.. + /// + internal static string TCE_NullCertificatePathSysErr_Unix + { + get + { + return ResourceManager.GetString("TCE_NullCertificatePathSysErr_Unix", resourceCulture); + } + } + /// /// Looks up a localized string similar to Internal error. Ciphertext value cannot be null.. /// diff --git a/src/Microsoft.Data.SqlClient/src/Resources/Strings.resx b/src/Microsoft.Data.SqlClient/src/Resources/Strings.resx index 90a157876a..a343856cdd 100644 --- a/src/Microsoft.Data.SqlClient/src/Resources/Strings.resx +++ b/src/Microsoft.Data.SqlClient/src/Resources/Strings.resx @@ -4032,9 +4032,15 @@ Certificate path cannot be null. Use the following format: <certificate location>{2}<certificate store>{2}<certificate thumbprint>, where <certificate location> is either '{0}' or '{1}'. + + Certificate path cannot be null. Use the following format: <certificate location>{1}<certificate store>{1}<certificate thumbprint>, where <certificate location> is '{0}'. + Internal error. Certificate path cannot be null. Use the following format: <certificate location>{2}<certificate store>{2}<certificate thumbprint>, where <certificate location> is either '{0}' or '{1}'. + + Internal error. Certificate path cannot be null. Use the following format: <certificate location>{1}<certificate store>{1}<certificate thumbprint>, where <certificate location> is '{0}'. + Column master key path cannot be null. Use the following format for a key stored in a Microsoft cryptographic service provider (CSP): <CSP Provider Name>{0}<Key Identifier>. @@ -4050,9 +4056,15 @@ Invalid certificate path: '{0}'. Use the following format: <certificate location>{3}<certificate store>{3}<certificate thumbprint>, where <certificate location> is either '{1}' or '{2}'. + + Invalid certificate path: '{0}'. Use the following format: <certificate location>{2}<certificate store>{2}<certificate thumbprint>, where <certificate location> is '{1}'. + Internal error. Invalid certificate path: '{0}'. Use the following format: <certificate location>{3}<certificate store>{3}<certificate thumbprint>, where <certificate location> is either '{1}' or '{2}'. + + Internal error. Invalid certificate path: '{0}'. Use the following format: <certificate location>{2}<certificate store>{2}<certificate thumbprint>, where <certificate location> is '{1}'. + Invalid column master key path: '{0}'. Use the following format for a key stored in a Microsoft cryptographic service provider (CSP): <CSP Provider Name>{1}<Key Identifier>. @@ -4068,9 +4080,15 @@ Invalid certificate location '{0}' in certificate path '{1}'. Use the following format: <certificate location>{4}<certificate store>{4}<certificate thumbprint>, where <certificate location> is either '{2}' or '{3}'. + + Invalid certificate location '{0}' in certificate path '{1}'. Use the following format: <certificate location>{3}<certificate store>{3}<certificate thumbprint>, where <certificate location> is '{2}'. + Internal error. Invalid certificate location '{0}' in certificate path '{1}'. Use the following format: <certificate location>{4}<certificate store>{4}<certificate thumbprint>, where <certificate location> is either '{2}' or '{3}'. + + Internal error. Invalid certificate location '{0}' in certificate path '{1}'. Use the following format: <certificate location>{3}<certificate store>{3}<certificate thumbprint>, where <certificate location> is '{2}'. + Invalid certificate store '{0}' specified in certificate path '{1}'. Expected value: '{2}'. diff --git a/src/Microsoft.Data.SqlClient/tests/Common/Fixtures/CertificateFixtureBase.cs b/src/Microsoft.Data.SqlClient/tests/Common/Fixtures/CertificateFixtureBase.cs index 9007796013..f97aedfe4e 100644 --- a/src/Microsoft.Data.SqlClient/tests/Common/Fixtures/CertificateFixtureBase.cs +++ b/src/Microsoft.Data.SqlClient/tests/Common/Fixtures/CertificateFixtureBase.cs @@ -59,7 +59,7 @@ protected X509Certificate2 CreateCertificate(string subjectName, IEnumerable + public class SqlColumnEncryptionCertificateStoreProviderShould : IClassFixture { private const string PRIMARY_CERTIFICATE_PATH = "CurrentUser/My/{primary_thumbprint}"; private const string SECONDARY_CERTIFICATE_PATH = "CurrentUser/My/{secondary_thumbprint}"; @@ -97,7 +97,7 @@ public class SqlColumnEncryptionCertificateStoreProviderWindowsShould : IClassFi private readonly ColumnEncryptionCertificateFixture _certFixture; - public SqlColumnEncryptionCertificateStoreProviderWindowsShould(ColumnEncryptionCertificateFixture certFixture) + public SqlColumnEncryptionCertificateStoreProviderShould(ColumnEncryptionCertificateFixture certFixture) { _certFixture = certFixture; @@ -107,7 +107,6 @@ public SqlColumnEncryptionCertificateStoreProviderWindowsShould(ColumnEncryption [Theory] [InvalidDecryptionParameters] - [PlatformSpecific(TestPlatforms.Windows)] public void ThrowExceptionWithInvalidParameterWhileDecryptingColumnEncryptionKey(string errorMsg, Type exceptionType, string masterKeyPath, string encryptionAlgorithm, byte[] bytes) { var provider = new SqlColumnEncryptionCertificateStoreProvider(); @@ -118,7 +117,6 @@ public void ThrowExceptionWithInvalidParameterWhileDecryptingColumnEncryptionKey [Theory] [InvalidEncryptionParameters] - [PlatformSpecific(TestPlatforms.Windows)] public void ThrowExceptionWithInvalidParameterWhileEncryptingColumnEncryptionKey(string errorMsg, Type exceptionType, string masterKeyPath, string encryptionAlgorithm, byte[] bytes) { var provider = new SqlColumnEncryptionCertificateStoreProvider(); @@ -128,7 +126,6 @@ public void ThrowExceptionWithInvalidParameterWhileEncryptingColumnEncryptionKey [Theory] [InvalidSigningParameters] - [PlatformSpecific(TestPlatforms.Windows)] public void ThrowExceptionWithInvalidParameterWhileSigningColumnMasterKeyMetadata(string errorMsg, Type exceptionType, string masterKeyPath) { var provider = new SqlColumnEncryptionCertificateStoreProvider(); @@ -140,7 +137,6 @@ public void ThrowExceptionWithInvalidParameterWhileSigningColumnMasterKeyMetadat [InlineData("CurrentUser/My/{primary_thumbprint}")] [InlineData("CURRENTUSER/My/{primary_thumbprint}")] [InlineData("currentuser/My/{primary_thumbprint}")] - [PlatformSpecific(TestPlatforms.Windows)] public void SetStoreLocationAppropriatelyFromMasterKeyPathRegardlessOfCase(string masterKeyPath) { var provider = new SqlColumnEncryptionCertificateStoreProvider(); @@ -152,7 +148,6 @@ public void SetStoreLocationAppropriatelyFromMasterKeyPathRegardlessOfCase(strin [InlineData("CurrentUser/my/{primary_thumbprint}")] [InlineData("CurrentUser/MY/{primary_thumbprint}")] [InlineData("CurrentUser/My/{primary_thumbprint}")] - [PlatformSpecific(TestPlatforms.Windows)] public void SetStoreNameAppropriatelyFromMasterKeyPathRegardlessOfCase(string masterKeyPath) { var provider = new SqlColumnEncryptionCertificateStoreProvider(); @@ -164,7 +159,6 @@ public void SetStoreNameAppropriatelyFromMasterKeyPathRegardlessOfCase(string ma [InlineData("RSA_OAEP")] [InlineData("rsa_oaep")] [InlineData("RsA_oAeP")] - [PlatformSpecific(TestPlatforms.Windows)] public void AcceptEncryptionAlgorithmRegardlessOfCase(string algorithm) { var provider = new SqlColumnEncryptionCertificateStoreProvider(); @@ -176,7 +170,6 @@ public void AcceptEncryptionAlgorithmRegardlessOfCase(string algorithm) [InlineData(32)] [InlineData(64)] [InlineData(128)] - [PlatformSpecific(TestPlatforms.Windows)] public void EncryptKeyAndThenDecryptItSuccessfully(int dataSize) { var provider = new SqlColumnEncryptionCertificateStoreProvider(); @@ -192,7 +185,6 @@ public void EncryptKeyAndThenDecryptItSuccessfully(int dataSize) [Theory] [InlineData(true)] [InlineData(false)] - [PlatformSpecific(TestPlatforms.Windows)] public void SignAndVerifyColumnMasterKeyMetadataSuccessfully(bool allowEnclaveComputations) { var provider = new SqlColumnEncryptionCertificateStoreProvider(); @@ -205,7 +197,6 @@ public void SignAndVerifyColumnMasterKeyMetadataSuccessfully(bool allowEnclaveCo [Theory] [InlineData(true)] [InlineData(false)] - [PlatformSpecific(TestPlatforms.Windows)] public void FailToVerifyColumnMasterKeyMetadataWithWrongCertificate(bool allowEnclaveComputations) { var provider = new SqlColumnEncryptionCertificateStoreProvider(); @@ -217,7 +208,6 @@ public void FailToVerifyColumnMasterKeyMetadataWithWrongCertificate(bool allowEn } [Fact] - [PlatformSpecific(TestPlatforms.Windows)] public void EncryptAndDecryptDataSuccessfully() { var input = new byte[] { 1, 2, 3, 4, 5 }; @@ -240,7 +230,6 @@ public void EncryptAndDecryptDataSuccessfully() , DisableDiscoveryEnumeration = true #endif )] - [PlatformSpecific(TestPlatforms.Windows)] public void TestCEKEncryptionReversal(StoreLocation certificateStoreLocation, String certificateStoreNameAndLocation) { Assert.True(!string.IsNullOrWhiteSpace(certificateStoreNameAndLocation)); @@ -304,7 +293,6 @@ private void TestEncryptionReversalUsingAead(byte[] plainTextInBytes, byte[] roo } [Theory] - [PlatformSpecific(TestPlatforms.Windows)] [AeadEncryptionParameters] public void TestAeadEncryptionReversal(string dataType, object data, Utility.CColumnEncryptionType encType) { @@ -339,7 +327,6 @@ public void TestAeadEncryptionReversal(string dataType, object data, Utility.CCo } [Fact] - [PlatformSpecific(TestPlatforms.Windows)] public void TestCustomKeyProviderListSetter() { lock (Utility.ClearSqlConnectionGlobalProvidersLock) @@ -396,7 +383,6 @@ public void TestCustomKeyProviderListSetter() , DisableDiscoveryEnumeration = true #endif )] - [PlatformSpecific(TestPlatforms.Windows)] public void TestValidCertificatePaths(string certificateStoreNameAndLocation, object location) { StoreLocation certificateStoreLocation; @@ -411,7 +397,9 @@ public void TestValidCertificatePaths(string certificateStoreNameAndLocation, ob } else { - certificateStoreLocation = StoreLocation.CurrentUser; + certificateStoreLocation = Environment.OSVersion.Platform == PlatformID.Win32NT + ? StoreLocation.LocalMachine + : StoreLocation.CurrentUser; } // Fetch the newly created cert. @@ -436,7 +424,6 @@ public void TestValidCertificatePaths(string certificateStoreNameAndLocation, ob } [Theory] - [PlatformSpecific(TestPlatforms.Windows)] [InlineData(new object[3] { @"iv", Utility.CColumnEncryptionType.Randomized, @"Specified ciphertext has an invalid authentication tag.\s+\(?Parameter (name: )?'?cipherText('\))?" })] [InlineData(new object[3] { @"tag", Utility.CColumnEncryptionType.Randomized, @"Specified ciphertext has an invalid authentication tag.\s+\(?Parameter (name: )?'?cipherText('\))?" })] [InlineData(new object[3] { @"cipher", Utility.CColumnEncryptionType.Randomized, @"Specified ciphertext has an invalid authentication tag.\s+\(?Parameter (name: )?'?cipherText('\))?" })] @@ -532,26 +519,35 @@ public static IEnumerable CEKEncryptionReversalData() public static IEnumerable ValidCertificatePathsData() { yield return new object[2] { CurrentUserMyPathPrefix, StoreLocation.CurrentUser }; - // use localmachine cert path (or an incomplete path, which defaults to localmachine) only when current user is Admin. - if (ColumnEncryptionCertificateFixture.IsAdmin) + + // use localmachine cert path (or a location in the cert path which defaults to localmachine) only when current user is Admin. + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - yield return new object[2] { MyPathPrefix, StoreLocation.LocalMachine }; - yield return new object[2] { @"", StoreLocation.LocalMachine }; - yield return new object[2] { LocalMachineMyPathPrefix, StoreLocation.LocalMachine }; + yield return new object[2] { @"", null }; + yield return new object[2] { MyPathPrefix, null }; + + if (ColumnEncryptionCertificateFixture.IsAdmin) + { + yield return new object[2] { LocalMachineMyPathPrefix, StoreLocation.LocalMachine }; + } } } public class InvalidDecryptionParameters : DataAttribute { - private const string TCE_NullCertificatePath = @"Internal error. Certificate path cannot be null. Use the following format: //, where is either 'LocalMachine' or 'CurrentUser'.\s+\(?Parameter (name: )?'?masterKeyPath('\))?"; - private const string TCE_EmptyCertificatePath = @"Internal error. Invalid certificate path: ''. Use the following format: //, where is either 'LocalMachine' or 'CurrentUser'.\s+\(?Parameter (name: )?'?masterKeyPath('\))?"; + private const string TCE_NullCertificatePath_Windows = @"Internal error. Certificate path cannot be null. Use the following format: //, where is either 'LocalMachine' or 'CurrentUser'.\s+\(?Parameter (name: )?'?masterKeyPath('\))?"; + private const string TCE_NullCertificatePath_Unix = @"Internal error. Certificate path cannot be null. Use the following format: //, where is 'CurrentUser'.\s+\(?Parameter (name: )?'?masterKeyPath('\))?"; + private const string TCE_EmptyCertificatePath_Windows = @"Internal error. Invalid certificate path: ''. Use the following format: //, where is either 'LocalMachine' or 'CurrentUser'.\s+\(?Parameter (name: )?'?masterKeyPath('\))?"; + private const string TCE_EmptyCertificatePath_Unix = @"Internal error. Invalid certificate path: ''. Use the following format: //, where is 'CurrentUser'.\s+\(?Parameter (name: )?'?masterKeyPath('\))?"; private const string TCE_NullEncryptedColumnEncryptionKey = @"Internal error. Encrypted column encryption key cannot be null.\s+\(?Parameter (name: )?'?encryptedColumnEncryptionKey('\))?"; private const string TCE_EmptyEncryptedColumnEncryptionKey = @"Internal error. Empty encrypted column encryption key specified.\s+\(?Parameter (name: )?'?encryptedColumnEncryptionKey('\))?"; private const string TCE_NullKeyEncryptionAlgorithm = @"Internal error. Key encryption algorithm cannot be null.\s+\(?Parameter (name: )?'?encryptionAlgorithm('\))?"; private const string TCE_InvalidKeyEncryptionAlgorithm = @"Internal error. Invalid key encryption algorithm specified: ''. Expected value: 'RSA_OAEP'.\s+\(?Parameter (name: )?'?encryptionAlgorithm('\))?"; private const string TCE_LargeCertificatePathLength = @"Internal error. Specified certificate path has 32768 bytes, which exceeds maximum length of 32767 bytes.\s+\(?Parameter (name: )?'?masterKeyPath('\))?"; - private const string TCE_InvalidCertificatePath = @"Internal error. Invalid certificate path: 'CurrentUser/My/Thumbprint/extra'. Use the following format: //, where is either 'LocalMachine' or 'CurrentUser'.\s+\(?Parameter (name: )?'?masterKeyPath('\))?"; - private const string TCE_InvalidCertificateLocation = @"Internal error. Invalid certificate location 'Invalid' in certificate path 'Invalid/My/Thumbprint'. Use the following format: //, where is either 'LocalMachine' or 'CurrentUser'.\s+\(?Parameter (name: )?'?masterKeyPath('\))?"; + private const string TCE_InvalidCertificatePath_Windows = @"Internal error. Invalid certificate path: 'CurrentUser/My/Thumbprint/extra'. Use the following format: //, where is either 'LocalMachine' or 'CurrentUser'.\s+\(?Parameter (name: )?'?masterKeyPath('\))?"; + private const string TCE_InvalidCertificatePath_Unix = @"Internal error. Invalid certificate path: 'CurrentUser/My/Thumbprint/extra'. Use the following format: //, where is 'CurrentUser'.\s+\(?Parameter (name: )?'?masterKeyPath('\))?"; + private const string TCE_InvalidCertificateLocation_Windows = @"Internal error. Invalid certificate location 'Invalid' in certificate path 'Invalid/My/Thumbprint'. Use the following format: //, where is either 'LocalMachine' or 'CurrentUser'.\s+\(?Parameter (name: )?'?masterKeyPath('\))?"; + private const string TCE_InvalidCertificateLocation_Unix = @"Internal error. Invalid certificate location 'Invalid' in certificate path 'Invalid/My/Thumbprint'. Use the following format: //, where is 'CurrentUser'.\s+\(?Parameter (name: )?'?masterKeyPath('\))?"; private const string TCE_InvalidCertificateStore = @"Internal error. Invalid certificate store 'Invalid' specified in certificate path 'CurrentUser/Invalid/Thumbprint'. Expected value: 'My'.\s+\(?Parameter (name: )?'?masterKeyPath('\))?"; private const string TCE_CertificateNotFound = @"Certificate with thumbprint 'JunkThumbprint' not found in certificate store 'My' in certificate location 'CurrentUser'. Verify the certificate path in the column master key definition in the database is correct, and the certificate has been imported correctly into the certificate location/store.\s+\(?Parameter (name: )?'?masterKeyPath('\))?"; private const string TCE_CertificateWithNoPrivateKey = @"Certificate specified in key path 'CurrentUser/My/{npk_thumbprint}' does not have a private key to decrypt a column encryption key. Verify the certificate is imported correctly.\s+\(?Parameter (name: )?'?masterKeyPath('\))?"; @@ -561,6 +557,11 @@ public class InvalidDecryptionParameters : DataAttribute private const string TCE_InvalidSignatureInEncryptedCEK = @"The specified encrypted column encryption key's signature length: 128 does not match the signature length: 256 when using column master key \(certificate\) in 'CurrentUser/My/{primary_thumbprint}'. The encrypted column encryption key may be corrupt, or the specified certificate path may be incorrect.\s+\(?Parameter (name: )?'?encryptedColumnEncryptionKey('\))?"; private const string TCE_InvalidSignature = @"The specified encrypted column encryption key signature does not match the signature computed with the column master key \(certificate\) in 'CurrentUser/My/{primary_thumbprint}'. The encrypted column encryption key may be corrupt, or the specified path may be incorrect.\s+\(?Parameter (name: )?'?encryptedColumnEncryptionKey('\))?"; + private static readonly string TCE_NullCertificatePath = Environment.OSVersion.Platform == PlatformID.Win32NT ? TCE_NullCertificatePath_Windows : TCE_NullCertificatePath_Unix; + private static readonly string TCE_EmptyCertificatePath = Environment.OSVersion.Platform == PlatformID.Win32NT ? TCE_EmptyCertificatePath_Windows : TCE_EmptyCertificatePath_Unix; + private static readonly string TCE_InvalidCertificatePath = Environment.OSVersion.Platform == PlatformID.Win32NT ? TCE_InvalidCertificatePath_Windows : TCE_InvalidCertificatePath_Unix; + private static readonly string TCE_InvalidCertificateLocation = Environment.OSVersion.Platform == PlatformID.Win32NT ? TCE_InvalidCertificateLocation_Windows : TCE_InvalidCertificateLocation_Unix; + public override IEnumerable GetData(MethodInfo testMethod) { yield return new Object[] { TCE_NullCertificatePath, typeof(ArgumentNullException), null, ENCRYPTION_ALGORITHM, GenerateTestEncryptedBytes(1, 0, 256, 256) }; @@ -585,20 +586,29 @@ public override IEnumerable GetData(MethodInfo testMethod) public class InvalidEncryptionParameters : DataAttribute { - private const string TCE_NullCertificatePath = @"Certificate path cannot be null. Use the following format: //, where is either 'LocalMachine' or 'CurrentUser'.\s+\(?Parameter (name: )?'?masterKeyPath('\))?"; - private const string TCE_EmptyCertificatePath = @"Invalid certificate path: ''. Use the following format: //, where is either 'LocalMachine' or 'CurrentUser'.\s+\(?Parameter (name: )?'?masterKeyPath('\))?"; + private const string TCE_NullCertificatePath_Windows = @"Certificate path cannot be null. Use the following format: //, where is either 'LocalMachine' or 'CurrentUser'.\s+\(?Parameter (name: )?'?masterKeyPath('\))?"; + private const string TCE_NullCertificatePath_Unix = @"Certificate path cannot be null. Use the following format: //, where is 'CurrentUser'.\s+\(?Parameter (name: )?'?masterKeyPath('\))?"; + private const string TCE_EmptyCertificatePath_Windows = @"Invalid certificate path: ''. Use the following format: //, where is either 'LocalMachine' or 'CurrentUser'.\s+\(?Parameter (name: )?'?masterKeyPath('\))?"; + private const string TCE_EmptyCertificatePath_Unix = @"Invalid certificate path: ''. Use the following format: //, where is 'CurrentUser'.\s+\(?Parameter (name: )?'?masterKeyPath('\))?"; private const string TCE_NullEncryptedColumnEncryptionKey = @"Column encryption key cannot be null.\s+\(?Parameter (name: )?'?columnEncryptionKey('\))?"; private const string TCE_EmptyEncryptedColumnEncryptionKey = @"Empty column encryption key specified.\s+\(?Parameter (name: )?'?columnEncryptionKey('\))?"; private const string TCE_NullKeyEncryptionAlgorithm = @"Key encryption algorithm cannot be null.\s+\(?Parameter (name: )?'?encryptionAlgorithm('\))?"; private const string TCE_InvalidKeyEncryptionAlgorithm = @"Invalid key encryption algorithm specified: ''. Expected value: 'RSA_OAEP'.\s+\(?Parameter (name: )?'?encryptionAlgorithm('\))?"; private const string TCE_LargeCertificatePathLength = @"Specified certificate path has 32768 bytes, which exceeds maximum length of 32767 bytes.\s+\(?Parameter (name: )?'?masterKeyPath('\))?"; - private const string TCE_InvalidCertificatePath = @"Invalid certificate path: 'CurrentUser/My/Thumbprint/extra'. Use the following format: //, where is either 'LocalMachine' or 'CurrentUser'.\s+\(?Parameter (name: )?'?masterKeyPath('\))?"; - private const string TCE_InvalidCertificateLocation = @"Invalid certificate location 'Invalid' in certificate path 'Invalid/My/Thumbprint'. Use the following format: //, where is either 'LocalMachine' or 'CurrentUser'.\s+\(?Parameter (name: )?'?masterKeyPath('\))?"; + private const string TCE_InvalidCertificatePath_Windows = @"Invalid certificate path: 'CurrentUser/My/Thumbprint/extra'. Use the following format: //, where is either 'LocalMachine' or 'CurrentUser'.\s+\(?Parameter (name: )?'?masterKeyPath('\))?"; + private const string TCE_InvalidCertificatePath_Unix = @"Invalid certificate path: 'CurrentUser/My/Thumbprint/extra'. Use the following format: //, where is 'CurrentUser'.\s+\(?Parameter (name: )?'?masterKeyPath('\))?"; + private const string TCE_InvalidCertificateLocation_Windows = @"Invalid certificate location 'Invalid' in certificate path 'Invalid/My/Thumbprint'. Use the following format: //, where is either 'LocalMachine' or 'CurrentUser'.\s+\(?Parameter (name: )?'?masterKeyPath('\))?"; + private const string TCE_InvalidCertificateLocation_Unix = @"Invalid certificate location 'Invalid' in certificate path 'Invalid/My/Thumbprint'. Use the following format: //, where is 'CurrentUser'.\s+\(?Parameter (name: )?'?masterKeyPath('\))?"; private const string TCE_InvalidCertificateStore = @"Invalid certificate store 'Invalid' specified in certificate path 'CurrentUser/Invalid/Thumbprint'. Expected value: 'My'.\s+\(?Parameter (name: )?'?masterKeyPath('\))?"; private const string TCE_CertificateNotFound = @"Certificate with thumbprint 'JunkThumbprint' not found in certificate store 'My' in certificate location 'CurrentUser'.\s+\(?Parameter (name: )?'?masterKeyPath('\))?"; private const string TCE_CertificateWithNoPrivateKey = @"Certificate specified in key path 'CurrentUser/My/{npk_thumbprint}' does not have a private key to encrypt a column encryption key. Verify the certificate is imported correctly.\s+\(?Parameter (name: )?'?masterKeyPath('\))?"; private const string TCE_InvalidCertificateSignature = @"Empty certificate thumbprint specified in certificate path 'CurrentUser/My/'.\s+\(?Parameter (name: )?'?masterKeyPath('\))?"; + private static readonly string TCE_NullCertificatePath = Environment.OSVersion.Platform == PlatformID.Win32NT ? TCE_NullCertificatePath_Windows : TCE_NullCertificatePath_Unix; + private static readonly string TCE_EmptyCertificatePath = Environment.OSVersion.Platform == PlatformID.Win32NT ? TCE_EmptyCertificatePath_Windows : TCE_EmptyCertificatePath_Unix; + private static readonly string TCE_InvalidCertificatePath = Environment.OSVersion.Platform == PlatformID.Win32NT ? TCE_InvalidCertificatePath_Windows : TCE_InvalidCertificatePath_Unix; + private static readonly string TCE_InvalidCertificateLocation = Environment.OSVersion.Platform == PlatformID.Win32NT ? TCE_InvalidCertificateLocation_Windows : TCE_InvalidCertificateLocation_Unix; + public override IEnumerable GetData(MethodInfo testMethod) { yield return new Object[] { TCE_NullCertificatePath, typeof(ArgumentNullException), null, ENCRYPTION_ALGORITHM, GenerateTestEncryptedBytes(1, 0, 256, 256) }; @@ -619,10 +629,15 @@ public override IEnumerable GetData(MethodInfo testMethod) public class InvalidSigningParameters : DataAttribute { - private const string TCE_NullCertificatePath = @"Certificate path cannot be null. Use the following format: //, where is either 'LocalMachine' or 'CurrentUser'.\s+\(?Parameter (name: )?'?masterKeyPath('\))?"; - private const string TCE_EmptyCertificatePath = @"Invalid certificate path: ''. Use the following format: //, where is either 'LocalMachine' or 'CurrentUser'.\s+\(?Parameter (name: )?'?masterKeyPath('\))?"; + private const string TCE_NullCertificatePath_Windows = @"Certificate path cannot be null. Use the following format: //, where is either 'LocalMachine' or 'CurrentUser'.\s+\(?Parameter (name: )?'?masterKeyPath('\))?"; + private const string TCE_NullCertificatePath_Unix = @"Certificate path cannot be null. Use the following format: //, where is 'CurrentUser'.\s+\(?Parameter (name: )?'?masterKeyPath('\))?"; + private const string TCE_EmptyCertificatePath_Windows = @"Invalid certificate path: ''. Use the following format: //, where is either 'LocalMachine' or 'CurrentUser'.\s+\(?Parameter (name: )?'?masterKeyPath('\))?"; + private const string TCE_EmptyCertificatePath_Unix = @"Invalid certificate path: ''. Use the following format: //, where is 'CurrentUser'.\s+\(?Parameter (name: )?'?masterKeyPath('\))?"; private const string TCE_LargeCertificatePathLength = @"Specified certificate path has 32768 bytes, which exceeds maximum length of 32767 bytes.\s+\(?Parameter (name: )?'?masterKeyPath('\))?"; + private static readonly string TCE_NullCertificatePath = Environment.OSVersion.Platform == PlatformID.Win32NT ? TCE_NullCertificatePath_Windows : TCE_NullCertificatePath_Unix; + private static readonly string TCE_EmptyCertificatePath = Environment.OSVersion.Platform == PlatformID.Win32NT ? TCE_EmptyCertificatePath_Windows : TCE_EmptyCertificatePath_Unix; + public override IEnumerable GetData(MethodInfo testMethod) { yield return new Object[] { TCE_NullCertificatePath, typeof(ArgumentNullException), null }; @@ -644,18 +659,4 @@ public static string GenerateString(int length) return s.ToString(); } } - - public class SqlColumnEncryptionCertificateStoreProviderUnixShould - { - [Fact] - [PlatformSpecific(TestPlatforms.AnyUnix)] - public void ThrowPlatformNotSupportedExceptionInUnix() - { - var provider = new SqlColumnEncryptionCertificateStoreProvider(); - Assert.Throws(() => provider.EncryptColumnEncryptionKey("", "", new byte[] { })); - Assert.Throws(() => provider.DecryptColumnEncryptionKey("", "", new byte[] { })); - Assert.Throws(() => provider.SignColumnMasterKeyMetadata("", false)); - Assert.Throws(() => provider.VerifyColumnMasterKeyMetadata("", false, new byte[] { })); - } - } } diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/AKVTests.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/AKVTests.cs index 78fa0a9001..8a56a7690c 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/AKVTests.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/AKVTests.cs @@ -130,7 +130,6 @@ public void ForcedColumnDecryptErrorTestShouldFail() } [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.IsAKVSetupAvailable))] - [PlatformSpecific(TestPlatforms.Windows)] public void TestRoundTripWithAKVAndCertStoreProvider() { SqlColumnEncryptionCertificateStoreProvider certStoreProvider = new SqlColumnEncryptionCertificateStoreProvider(); diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/ApiShould.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/ApiShould.cs index 184b5465ec..d82aaf3131 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/ApiShould.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/ApiShould.cs @@ -21,7 +21,7 @@ namespace Microsoft.Data.SqlClient.ManualTesting.Tests.AlwaysEncrypted /// /// Always Encrypted public API Manual tests. /// - public sealed class ApiShould : IClassFixture, IDisposable + public sealed class ApiShould : IClassFixture, IDisposable { private SQLSetupStrategy _fixture; @@ -45,9 +45,9 @@ public sealed class ApiShould : IClassFixture, IDis "'MSSQL_CERTIFICATE_STORE', 'MSSQL_CNG_STORE', 'MSSQL_CSP_PROVIDER'", $"'{NotRequiredProviderName}'"); - public ApiShould(PlatformSpecificTestContext context) + public ApiShould(SQLSetupStrategyCertStoreProvider context) { - _fixture = context.Fixture; + _fixture = context; _tableName = _fixture.ApiTestTable.Name; ApiTestTable _customKeyStoreProviderTable = _fixture.CustomKeyStoreProviderTestTable as ApiTestTable; diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/BulkCopyAE.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/BulkCopyAE.cs index 20cd452286..c0b80fe977 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/BulkCopyAE.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/BulkCopyAE.cs @@ -12,15 +12,15 @@ namespace Microsoft.Data.SqlClient.ManualTesting.Tests.AlwaysEncrypted /// /// Always Encrypted public API Manual tests. /// - public sealed class BulkCopyAE : IClassFixture, IDisposable + public sealed class BulkCopyAE : IClassFixture, IDisposable { private SQLSetupStrategy fixture; private readonly string tableName; - public BulkCopyAE(PlatformSpecificTestContext context) + public BulkCopyAE(SQLSetupStrategyCertStoreProvider context) { - fixture = context.Fixture; + fixture = context; tableName = fixture.BulkCopyAETestTable.Name; } diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/BulkCopyAEErrorMessage.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/BulkCopyAEErrorMessage.cs index 9d6080b24f..a824575f6f 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/BulkCopyAEErrorMessage.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/BulkCopyAEErrorMessage.cs @@ -11,16 +11,16 @@ namespace Microsoft.Data.SqlClient.ManualTesting.Tests.AlwaysEncrypted /// /// Always Encrypted public API Manual tests. /// - public class BulkCopyAEErrorMessage : IClassFixture + public class BulkCopyAEErrorMessage : IClassFixture { private SQLSetupStrategy _fixture; private readonly string _tableName; private readonly string _columnName; - public BulkCopyAEErrorMessage(PlatformSpecificTestContext context) + public BulkCopyAEErrorMessage(SQLSetupStrategyCertStoreProvider context) { - _fixture = context.Fixture; + _fixture = context; _tableName = _fixture.BulkCopyAEErrorMessageTestTable.Name; _columnName = "c1"; } diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/ConversionTests.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/ConversionTests.cs index 216db7e0c3..f54609e2c0 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/ConversionTests.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/ConversionTests.cs @@ -18,7 +18,6 @@ namespace Microsoft.Data.SqlClient.ManualTesting.Tests.AlwaysEncrypted { - [PlatformSpecific(TestPlatforms.Windows)] public sealed class ConversionTests : IDisposable, IClassFixture { diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/CoreCryptoTests.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/CoreCryptoTests.cs index 82456e8636..245e1cbd67 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/CoreCryptoTests.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/CoreCryptoTests.cs @@ -13,7 +13,6 @@ public class CoreCryptoTests : IClassFixture { // Synapse: Always Encrypted not supported in Azure Synapse. [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureSynapse))] - [PlatformSpecific(TestPlatforms.Windows)] public void TestAeadCryptoWithNativeBaseline() { // Initialize the reader for resource text file which has the native code generated baseline. @@ -48,7 +47,6 @@ public void TestAeadCryptoWithNativeBaseline() // Synapse: Always Encrypted not supported in Azure Synapse. [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureSynapse))] - [PlatformSpecific(TestPlatforms.Windows)] public void TestRsaCryptoWithNativeBaseline() { // Initialize the reader for resource text file which has the native code generated baseline. diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/DateOnlyReadTests.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/DateOnlyReadTests.cs index a211fe6343..2cd1e18019 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/DateOnlyReadTests.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/DateOnlyReadTests.cs @@ -10,15 +10,15 @@ namespace Microsoft.Data.SqlClient.ManualTesting.Tests.AlwaysEncrypted { - public sealed class DateOnlyReadTests : IClassFixture, IDisposable + public sealed class DateOnlyReadTests : IClassFixture, IDisposable { private SQLSetupStrategy fixture; private readonly string tableName; - public DateOnlyReadTests(PlatformSpecificTestContext context) + public DateOnlyReadTests(SQLSetupStrategyCertStoreProvider context) { - fixture = context.Fixture; + fixture = context; tableName = fixture.DateOnlyTestTable.Name; } diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/End2EndSmokeTests.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/End2EndSmokeTests.cs index 874c225d9f..a9c30646ae 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/End2EndSmokeTests.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/End2EndSmokeTests.cs @@ -11,15 +11,15 @@ namespace Microsoft.Data.SqlClient.ManualTesting.Tests.AlwaysEncrypted { - public sealed class End2EndSmokeTests : IClassFixture, IDisposable + public sealed class End2EndSmokeTests : IClassFixture, IDisposable { private SQLSetupStrategy fixture; private readonly string tableName; - public End2EndSmokeTests(PlatformSpecificTestContext context) + public End2EndSmokeTests(SQLSetupStrategyCertStoreProvider context) { - fixture = context.Fixture; + fixture = context; tableName = fixture.End2EndSmokeTable.Name; } diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/SqlBulkCopyTruncation.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/SqlBulkCopyTruncation.cs index e5c4429752..0bc6d63545 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/SqlBulkCopyTruncation.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/SqlBulkCopyTruncation.cs @@ -11,15 +11,15 @@ namespace Microsoft.Data.SqlClient.ManualTesting.Tests.AlwaysEncrypted { - public class SqlBulkCopyTruncation : IClassFixture + public class SqlBulkCopyTruncation : IClassFixture { private SQLSetupStrategy _fixture; private readonly Dictionary tableNames = new Dictionary(); - public SqlBulkCopyTruncation(PlatformSpecificTestContext context) + public SqlBulkCopyTruncation(SQLSetupStrategyCertStoreProvider context) { - _fixture = context.Fixture; + _fixture = context; tableNames = _fixture.sqlBulkTruncationTableNames; } diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/SqlNullValues.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/SqlNullValues.cs index ed3d9797dd..c69a3cc314 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/SqlNullValues.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/SqlNullValues.cs @@ -11,16 +11,16 @@ namespace Microsoft.Data.SqlClient.ManualTesting.Tests.AlwaysEncrypted { - public sealed class SqlNullValuesTests : IClassFixture, IDisposable + public sealed class SqlNullValuesTests : IClassFixture, IDisposable { private SQLSetupStrategy fixture; private readonly string tableName; private string UdfName = DatabaseHelper.GenerateUniqueName("SqlNullValuesRetVal"); private string UdfNameNotNull = DatabaseHelper.GenerateUniqueName("SqlNullValuesRetValNotNull"); - public SqlNullValuesTests(PlatformSpecificTestContext context) + public SqlNullValuesTests(SQLSetupStrategyCertStoreProvider context) { - fixture = context.Fixture; + fixture = context; tableName = fixture.SqlNullValuesTable.Name; // Disable the cache to avoid false failures. SqlConnection.ColumnEncryptionQueryMetadataCacheEnabled = false; diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/TestFixtures/SQLSetupStrategy.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/TestFixtures/SQLSetupStrategy.cs index d08d2a86be..ad9181736f 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/TestFixtures/SQLSetupStrategy.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/TestFixtures/SQLSetupStrategy.cs @@ -287,47 +287,4 @@ protected override void Dispose(bool disposing) base.Dispose(disposing); } } - - // Use this class as the fixture for AE tests to ensure only one platform-specific fixture - // is created for each test class - public class PlatformSpecificTestContext : IDisposable - { - private SQLSetupStrategy certStoreFixture = null; - private SQLSetupStrategy akvFixture = null; - public SQLSetupStrategy Fixture => certStoreFixture ?? akvFixture; - - public PlatformSpecificTestContext() - { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - certStoreFixture = new SQLSetupStrategyCertStoreProvider(); - } - else - { - akvFixture = new SQLSetupStrategyAzureKeyVault(); - } - } - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - protected virtual void Dispose(bool disposing) - { - - try - { - if (disposing) - { - akvFixture?.Dispose(); - } - } - finally - { - certStoreFixture?.Dispose(); - } - } - } } diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/TestTrustedMasterKeyPaths.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/TestTrustedMasterKeyPaths.cs index c88b2767ea..4012f00914 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/TestTrustedMasterKeyPaths.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/TestTrustedMasterKeyPaths.cs @@ -44,7 +44,6 @@ private void ValidateResultSet(SqlDataReader sqlDataReader) Assert.True(rowsFound == 1, "Incorrect number of rows returned in first execution."); } - [PlatformSpecific(TestPlatforms.Windows)] [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] [ClassData(typeof(AEConnectionStringProvider))] public void TestTrustedColumnEncryptionMasterKeyPathsWithNullDictionary(string connection) @@ -83,7 +82,6 @@ FROM [{tableName}] SqlConnection.ColumnEncryptionTrustedMasterKeyPaths.Clear(); } - [PlatformSpecific(TestPlatforms.Windows)] [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] [ClassData(typeof(AEConnectionStringProvider))] public void TestTrustedColumnEncryptionMasterKeyPathsWithOneServer(string connection) @@ -129,7 +127,6 @@ FROM [{tableName}] SqlConnection.ColumnEncryptionTrustedMasterKeyPaths.Clear(); } - [PlatformSpecific(TestPlatforms.Windows)] [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] [ClassData(typeof(AEConnectionStringProvider))] public void TestTrustedColumnEncryptionMasterKeyPathsWithMultipleServers(string connection) @@ -188,7 +185,6 @@ FROM [{tableName}] SqlConnection.ColumnEncryptionTrustedMasterKeyPaths.Clear(); } - [PlatformSpecific(TestPlatforms.Windows)] [ConditionalTheory(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringSetupForAE))] [ClassData(typeof(AEConnectionStringProvider))] public void TestTrustedColumnEncryptionMasterKeyPathsWithInvalidInputs(string connection)