From a892c4141501a95add2be95b95d52259e185b276 Mon Sep 17 00:00:00 2001 From: Wraith2 Date: Fri, 27 Sep 2019 15:49:39 +0100 Subject: [PATCH] make test only run for csp providers discovered ensure that cleanup of certificates happens if one is created add single test run command to buildguide --- BUILDGUIDE.md | 12 +- .../AlwaysEncrypted/CspProviderExt.cs | 116 ++++++++++-------- .../Setup/CertificateUtilityWin.cs | 10 +- 3 files changed, 82 insertions(+), 56 deletions(-) diff --git a/BUILDGUIDE.md b/BUILDGUIDE.md index eb2c83d0f5..18473f2b3f 100644 --- a/BUILDGUIDE.md +++ b/BUILDGUIDE.md @@ -38,7 +38,7 @@ Once the environment is setup properly, execute the desired set of commands belo ```bash > msbuild /t:restore # Restores Nuget Packages. - ``` +``` ```bash > msbuild /t:BuildAllConfigurations @@ -79,11 +79,11 @@ Windows (`netcoreapp2.1`): ```bash > dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Platform="AnyCPU" /p:Configuration="Release" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonwindowstests" ``` - + Windows (`net46 x86`): ```bash > dotnet test "src\Microsoft.Data.SqlClient\tests\FunctionalTests\Microsoft.Data.SqlClient.Tests.csproj" /p:Platform="Win32" /p:Configuration="Release" /p:TestTargetOS="Windowsnetfx" --no-build -v n --filter "category!=nonnetfxtests&category!=failing&category!=nonwindowstests" - ``` +``` Windows (`net46 x64`): ```bash @@ -134,3 +134,9 @@ Unix (`netcoreapp2.1`): ```bash > dotnet test "src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Platform="AnyCPU" /p:Configuration="Release" /p:TestTargetOS="Unixnetcoreapp" --no-build -v n --filter "category!=nonnetcoreapptests&category!=failing&category!=nonlinuxtests&category!=nonuaptests" ``` + +## Run A Single Test +```bash +> dotnet test "src\Microsoft.Data.SqlClient\tests\ManualTests\Microsoft.Data.SqlClient.ManualTesting.Tests.csproj" /p:Platform="AnyCPU" /p:Configuration="Debug" /p:TestTargetOS="Windowsnetcoreapp" --no-build -v n --filter "FullyQualifiedName=Microsoft.Data.SqlClient.ManualTesting.Tests.AlwaysEncrypted.CspProviderExt.TestKeysFromCertificatesCreatedWithMultipleCryptoProviders" +``` + diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/CspProviderExt.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/CspProviderExt.cs index a2c27d41b7..c755666616 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/CspProviderExt.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/CspProviderExt.cs @@ -24,7 +24,7 @@ public void TestKeysFromCertificatesCreatedWithMultipleCryptoProviders() { const string providersRegistryKeyPath = @"SOFTWARE\Microsoft\Cryptography\Defaults\Provider"; Microsoft.Win32.RegistryKey defaultCryptoProvidersRegistryKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(providersRegistryKeyPath); - + foreach (string subKeyName in defaultCryptoProvidersRegistryKey.GetSubKeyNames()) { // NOTE: RSACryptoServiceProvider.SignData() fails for other providers when testing locally @@ -33,69 +33,78 @@ public void TestKeysFromCertificatesCreatedWithMultipleCryptoProviders() Console.WriteLine(@"INFO: Skipping Certificate creation for {0}.", subKeyName); continue; } - + string providerName; + string providerType; + string certificateName; using (Microsoft.Win32.RegistryKey providerKey = defaultCryptoProvidersRegistryKey.OpenSubKey(subKeyName)) { // Get Provider Name and its type - string providerName = providerKey.Name.Substring(providerKey.Name.LastIndexOf(@"\") + 1); - string providerType = providerKey.GetValue(@"Type").ToString(); + providerName = providerKey.Name.Substring(providerKey.Name.LastIndexOf(@"\") + 1); + providerType = providerKey.GetValue(@"Type").ToString(); // Create a certificate from that provider - string certificateName = string.Format(@"AETest - {0}", providerName); - - CertificateUtilityWin.CreateCertificate(certificateName, StoreLocation.CurrentUser.ToString(), providerName, providerType); + certificateName = string.Format(@"AETest - {0}", providerName); + } + CertificateUtilityWin.CreateCertificate(certificateName, StoreLocation.CurrentUser.ToString(), providerName, providerType); + SQLSetupStrategyCspExt sqlSetupStrategyCsp = null; + try + { if (false == CertificateUtilityWin.CertificateExists(certificateName, StoreLocation.CurrentUser)) { Console.WriteLine(@"INFO: Certificate creation for provider {0} failed so skipping it.", providerName); continue; } - // Get CSP Path X509Certificate2 cert = CertificateUtilityWin.GetCertificate(certificateName, StoreLocation.CurrentUser); string cspPath = CertificateUtilityWin.GetCspPathFromCertificate(cert); + + if (string.IsNullOrEmpty(cspPath)) + { + Console.WriteLine(@"INFO: Certificate provider {0} is not a csp provider so skipping it.", providerName); + continue; + } + Console.WriteLine("CSP path is {0}", cspPath); - SQLSetupStrategyCspExt sqlSetupStrategyCsp = new SQLSetupStrategyCspExt(cspPath); + sqlSetupStrategyCsp = new SQLSetupStrategyCspExt(cspPath); string tableName = sqlSetupStrategyCsp.CspProviderTable.Name; - try + using (SqlConnection sqlConn = new SqlConnection(DataTestUtility.TcpConnStr)) { - using (SqlConnection sqlConn = new SqlConnection(DataTestUtility.TcpConnStr)) - { - sqlConn.Open(); + sqlConn.Open(); - // insert 1 row data - Customer customer = new Customer(45, "Microsoft", "Corporation"); + // insert 1 row data + Customer customer = new Customer(45, "Microsoft", "Corporation"); - DatabaseHelper.InsertCustomerData(sqlConn, tableName, customer); + DatabaseHelper.InsertCustomerData(sqlConn, tableName, customer); - // Test INPUT parameter on an encrypted parameter - using (SqlCommand sqlCommand = new SqlCommand(string.Format(@"SELECT CustomerId, FirstName, LastName FROM [{0}] WHERE FirstName = @firstName", tableName), - sqlConn, null, SqlCommandColumnEncryptionSetting.Enabled)) + // Test INPUT parameter on an encrypted parameter + using (SqlCommand sqlCommand = new SqlCommand(string.Format(@"SELECT CustomerId, FirstName, LastName FROM [{0}] WHERE FirstName = @firstName", tableName), + sqlConn, null, SqlCommandColumnEncryptionSetting.Enabled)) + { + SqlParameter customerFirstParam = sqlCommand.Parameters.AddWithValue(@"firstName", @"Microsoft"); + customerFirstParam.Direction = System.Data.ParameterDirection.Input; + + using (SqlDataReader sqlDataReader = sqlCommand.ExecuteReader()) { - SqlParameter customerFirstParam = sqlCommand.Parameters.AddWithValue(@"firstName", @"Microsoft"); - customerFirstParam.Direction = System.Data.ParameterDirection.Input; - - using (SqlDataReader sqlDataReader = sqlCommand.ExecuteReader()) - { - ValidateResultSet(sqlDataReader); - Console.WriteLine(@"INFO: Successfully validated using a certificate using provider:{0}", providerName); - } + ValidateResultSet(sqlDataReader); + Console.WriteLine(@"INFO: Successfully validated using a certificate using provider:{0}", providerName); } } } - catch (Exception e) - { - Console.WriteLine(@"INFO: Failed to validate using a certificate using provider:{0}", providerName); - Console.WriteLine(@"Exception: {0}", e.Message); - } - finally - { - CertificateUtilityWin.RemoveCertificate(certificateName, StoreLocation.CurrentUser); - sqlSetupStrategyCsp.DropTable(); - } } + catch (Exception e) + { + Console.WriteLine(@"INFO: Failed to validate using a certificate using provider:{0}", providerName); + Console.WriteLine(@"Exception: {0}", e.Message); + } + finally + { + CertificateUtilityWin.RemoveCertificate(certificateName, StoreLocation.CurrentUser); + sqlSetupStrategyCsp?.DropTable(); + } + } } @@ -108,24 +117,29 @@ public void TestRoundTripWithCSPAndCertStoreProvider() string certificateName = string.Format(@"AETest - {0}", providerName); CertificateUtilityWin.CreateCertificate(certificateName, StoreLocation.CurrentUser.ToString(), providerName, providerType); + try + { + X509Certificate2 cert = CertificateUtilityWin.GetCertificate(certificateName, StoreLocation.CurrentUser); + string cspPath = CertificateUtilityWin.GetCspPathFromCertificate(cert); + string certificatePath = String.Concat(@"CurrentUser/my/", cert.Thumbprint); - X509Certificate2 cert = CertificateUtilityWin.GetCertificate(certificateName, StoreLocation.CurrentUser); - string cspPath = CertificateUtilityWin.GetCspPathFromCertificate(cert); - string certificatePath = String.Concat(@"CurrentUser/my/", cert.Thumbprint); - - SqlColumnEncryptionCertificateStoreProvider certProvider = new SqlColumnEncryptionCertificateStoreProvider(); - SqlColumnEncryptionCspProvider cspProvider = new SqlColumnEncryptionCspProvider(); - byte[] columnEncryptionKey = DatabaseHelper.GenerateRandomBytes(32); + SqlColumnEncryptionCertificateStoreProvider certProvider = new SqlColumnEncryptionCertificateStoreProvider(); + SqlColumnEncryptionCspProvider cspProvider = new SqlColumnEncryptionCspProvider(); + byte[] columnEncryptionKey = DatabaseHelper.GenerateRandomBytes(32); - byte[] encryptedColumnEncryptionKeyUsingCert = certProvider.EncryptColumnEncryptionKey(certificatePath, @"RSA_OAEP", columnEncryptionKey); - byte[] columnEncryptionKeyReturnedCert2CSP = cspProvider.DecryptColumnEncryptionKey(cspPath, @"RSA_OAEP", encryptedColumnEncryptionKeyUsingCert); - Assert.True(columnEncryptionKey.SequenceEqual(columnEncryptionKeyReturnedCert2CSP)); + byte[] encryptedColumnEncryptionKeyUsingCert = certProvider.EncryptColumnEncryptionKey(certificatePath, @"RSA_OAEP", columnEncryptionKey); + byte[] columnEncryptionKeyReturnedCert2CSP = cspProvider.DecryptColumnEncryptionKey(cspPath, @"RSA_OAEP", encryptedColumnEncryptionKeyUsingCert); + Assert.True(columnEncryptionKey.SequenceEqual(columnEncryptionKeyReturnedCert2CSP)); - byte[] encryptedColumnEncryptionKeyUsingCSP = cspProvider.EncryptColumnEncryptionKey(cspPath, @"RSA_OAEP", columnEncryptionKey); - byte[] columnEncryptionKeyReturnedCSP2Cert = certProvider.DecryptColumnEncryptionKey(certificatePath, @"RSA_OAEP", encryptedColumnEncryptionKeyUsingCSP); - Assert.True(columnEncryptionKey.SequenceEqual(columnEncryptionKeyReturnedCSP2Cert)); + byte[] encryptedColumnEncryptionKeyUsingCSP = cspProvider.EncryptColumnEncryptionKey(cspPath, @"RSA_OAEP", columnEncryptionKey); + byte[] columnEncryptionKeyReturnedCSP2Cert = certProvider.DecryptColumnEncryptionKey(certificatePath, @"RSA_OAEP", encryptedColumnEncryptionKeyUsingCSP); + Assert.True(columnEncryptionKey.SequenceEqual(columnEncryptionKeyReturnedCSP2Cert)); - CertificateUtilityWin.RemoveCertificate(certificateName, StoreLocation.CurrentUser); + } + finally + { + CertificateUtilityWin.RemoveCertificate(certificateName, StoreLocation.CurrentUser); + } } [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/TestFixtures/Setup/CertificateUtilityWin.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/TestFixtures/Setup/CertificateUtilityWin.cs index 1212fcf5c4..c7eb42071d 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/TestFixtures/Setup/CertificateUtilityWin.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/AlwaysEncrypted/TestFixtures/Setup/CertificateUtilityWin.cs @@ -182,8 +182,14 @@ internal static X509Certificate2 GetCertificate(string certificateName, StoreLoc /// internal static string GetCspPathFromCertificate(X509Certificate2 certificate) { - RSACryptoServiceProvider rsaProvider = (RSACryptoServiceProvider)certificate.PrivateKey; - return string.Concat(rsaProvider.CspKeyContainerInfo.ProviderName, @"/", rsaProvider.CspKeyContainerInfo.KeyContainerName); + if (certificate.PrivateKey is RSACryptoServiceProvider csp) + { + return string.Concat(csp.CspKeyContainerInfo.ProviderName, @"/", csp.CspKeyContainerInfo.KeyContainerName); + } + else + { + return null; + } } ///