5
5
using System ;
6
6
using System . Linq ;
7
7
using System . Security . Cryptography . X509Certificates ;
8
- using Microsoft . Data . SqlClient . ManualTesting . Tests . AlwaysEncrypted . Setup ;
9
8
using Xunit ;
10
- using System . Collections . Generic ;
11
- using static Microsoft . Data . SqlClient . ManualTesting . Tests . AlwaysEncrypted . CertificateUtilityWin ;
9
+ using System . Security . Cryptography ;
10
+ using Microsoft . Data . SqlClient . TestUtilities . Fixtures ;
12
11
#if ! NETFRAMEWORK
13
12
using System . Runtime . Versioning ;
14
13
#endif
@@ -25,184 +24,48 @@ namespace Microsoft.Data.SqlClient.ManualTesting.Tests.AlwaysEncrypted
25
24
[ PlatformSpecific ( TestPlatforms . Windows ) ]
26
25
public class CspProviderExt
27
26
{
28
- [ ConditionalTheory ( typeof ( DataTestUtility ) , nameof ( DataTestUtility . AreConnStringSetupForAE ) ) ]
29
- [ ClassData ( typeof ( AEConnectionStringProvider ) ) ]
30
- public void TestKeysFromCertificatesCreatedWithMultipleCryptoProviders ( string connectionString )
31
- {
32
- const string providersRegistryKeyPath = @"SOFTWARE\Microsoft\Cryptography\Defaults\Provider" ;
33
- Microsoft . Win32 . RegistryKey defaultCryptoProvidersRegistryKey = Microsoft . Win32 . Registry . LocalMachine . OpenSubKey ( providersRegistryKeyPath ) ;
34
-
35
- foreach ( string subKeyName in defaultCryptoProvidersRegistryKey . GetSubKeyNames ( ) )
36
- {
37
- // NOTE: RSACryptoServiceProvider.SignData() fails for other providers when testing locally
38
- if ( ! subKeyName . Contains ( @"RSA and AES" ) )
39
- {
40
- Console . WriteLine ( @"INFO: Skipping Certificate creation for {0}." , subKeyName ) ;
41
- continue ;
42
- }
43
- string providerName ;
44
- string providerType ;
45
- string certificateName ;
46
- using ( Microsoft . Win32 . RegistryKey providerKey = defaultCryptoProvidersRegistryKey . OpenSubKey ( subKeyName ) )
47
- {
48
- // Get Provider Name and its type
49
- providerName = providerKey . Name . Substring ( providerKey . Name . LastIndexOf ( @"\" , StringComparison . Ordinal ) + 1 ) ;
50
- providerType = providerKey . GetValue ( @"Type" ) . ToString ( ) ;
51
-
52
- // Create a certificate from that provider
53
- certificateName = string . Format ( @"AETest - {0}" , providerName ) ;
54
- }
55
-
56
- var extensions = new List < Tuple < string , string , string > > ( ) ;
57
- CertificateOption certOption = new ( )
58
- {
59
- Subject = certificateName ,
60
- KeyExportPolicy = "Exportable" ,
61
- CertificateStoreLocation = $ "{ StoreLocation . CurrentUser } \\ My",
62
- Provider = providerName ,
63
- Type = providerType ,
64
- } ;
65
- CreateCertificate ( certOption ) ;
66
- SQLSetupStrategyCspExt sqlSetupStrategyCsp = null ;
67
- try
68
- {
69
- if ( false == CertificateUtilityWin . CertificateExists ( certificateName , StoreLocation . CurrentUser ) )
70
- {
71
- Console . WriteLine ( @"INFO: Certificate creation for provider {0} failed so skipping it." , providerName ) ;
72
- continue ;
73
- }
74
-
75
- X509Certificate2 cert = CertificateUtilityWin . GetCertificate ( certificateName , StoreLocation . CurrentUser ) ;
76
- string cspPath = CertificateUtilityWin . GetCspPathFromCertificate ( cert ) ;
77
-
78
- if ( string . IsNullOrEmpty ( cspPath ) )
79
- {
80
- Console . WriteLine ( @"INFO: Certificate provider {0} is not a csp provider so skipping it." , providerName ) ;
81
- continue ;
82
- }
83
-
84
- Console . WriteLine ( "CSP path is {0}" , cspPath ) ;
85
-
86
- sqlSetupStrategyCsp = new SQLSetupStrategyCspExt ( cspPath ) ;
87
- string tableName = sqlSetupStrategyCsp . CspProviderTable . Name ;
88
-
89
- using SqlConnection sqlConn = new ( connectionString ) ;
90
- sqlConn . Open ( ) ;
91
-
92
- Table . DeleteData ( tableName , sqlConn ) ;
93
-
94
- // insert 1 row data
95
- Customer customer = new Customer ( 45 , "Microsoft" , "Corporation" ) ;
96
-
97
- DatabaseHelper . InsertCustomerData ( sqlConn , null , tableName , customer ) ;
98
-
99
- // Test INPUT parameter on an encrypted parameter
100
- using SqlCommand sqlCommand = new ( @$ "SELECT CustomerId, FirstName, LastName FROM [{ tableName } ] WHERE FirstName = @firstName",
101
- sqlConn , null , SqlCommandColumnEncryptionSetting . Enabled ) ;
102
- SqlParameter customerFirstParam = sqlCommand . Parameters . AddWithValue ( @"firstName" , @"Microsoft" ) ;
103
- customerFirstParam . Direction = System . Data . ParameterDirection . Input ;
104
-
105
- using SqlDataReader sqlDataReader = sqlCommand . ExecuteReader ( ) ;
106
- ValidateResultSet ( sqlDataReader ) ;
107
- Console . WriteLine ( @"INFO: Successfully validated using a certificate using provider:{0}" , providerName ) ;
108
- }
109
- finally
110
- {
111
- CertificateUtilityWin . RemoveCertificate ( certificateName , StoreLocation . CurrentUser ) ;
112
- // clean up database resources
113
- sqlSetupStrategyCsp ? . Dispose ( ) ;
114
- }
115
-
116
- }
117
- }
118
-
119
27
// [Fact(Skip="Run this in non-parallel mode")] or [ConditionalFact()]
120
28
[ Fact ( Skip = "Failing in TCE" ) ]
121
29
public void TestRoundTripWithCSPAndCertStoreProvider ( )
122
30
{
123
- const string providerName = "Microsoft Enhanced RSA and AES Cryptographic Provider" ;
124
- string providerType = "24" ;
125
-
126
- string certificateName = string . Format ( @"AETest - {0}" , providerName ) ;
127
- CertificateOption options = new ( )
128
- {
129
- Subject = certificateName ,
130
- CertificateStoreLocation = StoreLocation . CurrentUser . ToString ( ) ,
131
- Provider = providerName ,
132
- Type = providerType
133
- } ;
134
- CertificateUtilityWin . CreateCertificate ( options ) ;
135
- try
136
- {
137
- X509Certificate2 cert = CertificateUtilityWin . GetCertificate ( certificateName , StoreLocation . CurrentUser ) ;
138
- string cspPath = CertificateUtilityWin . GetCspPathFromCertificate ( cert ) ;
139
- string certificatePath = String . Concat ( @"CurrentUser/my/" , cert . Thumbprint ) ;
31
+ using CspCertificateFixture cspCertificateFixture = new CspCertificateFixture ( ) ;
140
32
141
- SqlColumnEncryptionCertificateStoreProvider certProvider = new SqlColumnEncryptionCertificateStoreProvider ( ) ;
142
- SqlColumnEncryptionCspProvider cspProvider = new SqlColumnEncryptionCspProvider ( ) ;
143
- byte [ ] columnEncryptionKey = DatabaseHelper . GenerateRandomBytes ( 32 ) ;
33
+ X509Certificate2 cert = cspCertificateFixture . CspCertificate ;
34
+ string cspPath = cspCertificateFixture . CspKeyPath ;
35
+ string certificatePath = cspCertificateFixture . CspCertificatePath ;
144
36
145
- byte [ ] encryptedColumnEncryptionKeyUsingCert = certProvider . EncryptColumnEncryptionKey ( certificatePath , @"RSA_OAEP" , columnEncryptionKey ) ;
146
- byte [ ] columnEncryptionKeyReturnedCert2CSP = cspProvider . DecryptColumnEncryptionKey ( cspPath , @"RSA_OAEP" , encryptedColumnEncryptionKeyUsingCert ) ;
147
- Assert . True ( columnEncryptionKey . SequenceEqual ( columnEncryptionKeyReturnedCert2CSP ) ) ;
37
+ SqlColumnEncryptionCertificateStoreProvider certProvider = new SqlColumnEncryptionCertificateStoreProvider ( ) ;
38
+ SqlColumnEncryptionCspProvider cspProvider = new SqlColumnEncryptionCspProvider ( ) ;
39
+ byte [ ] columnEncryptionKey = DatabaseHelper . GenerateRandomBytes ( 32 ) ;
148
40
149
- byte [ ] encryptedColumnEncryptionKeyUsingCSP = cspProvider . EncryptColumnEncryptionKey ( cspPath , @"RSA_OAEP" , columnEncryptionKey ) ;
150
- byte [ ] columnEncryptionKeyReturnedCSP2Cert = certProvider . DecryptColumnEncryptionKey ( certificatePath , @"RSA_OAEP" , encryptedColumnEncryptionKeyUsingCSP ) ;
151
- Assert . True ( columnEncryptionKey . SequenceEqual ( columnEncryptionKeyReturnedCSP2Cert ) ) ;
41
+ byte [ ] encryptedColumnEncryptionKeyUsingCert = certProvider . EncryptColumnEncryptionKey ( certificatePath , @"RSA_OAEP" , columnEncryptionKey ) ;
42
+ byte [ ] columnEncryptionKeyReturnedCert2CSP = cspProvider . DecryptColumnEncryptionKey ( cspPath , @"RSA_OAEP" , encryptedColumnEncryptionKeyUsingCert ) ;
43
+ Assert . True ( columnEncryptionKey . SequenceEqual ( columnEncryptionKeyReturnedCert2CSP ) ) ;
152
44
153
- }
154
- finally
155
- {
156
- CertificateUtilityWin . RemoveCertificate ( certificateName , StoreLocation . CurrentUser ) ;
157
- }
45
+ byte [ ] encryptedColumnEncryptionKeyUsingCSP = cspProvider . EncryptColumnEncryptionKey ( cspPath , @"RSA_OAEP" , columnEncryptionKey ) ;
46
+ byte [ ] columnEncryptionKeyReturnedCSP2Cert = certProvider . DecryptColumnEncryptionKey ( certificatePath , @"RSA_OAEP" , encryptedColumnEncryptionKeyUsingCSP ) ;
47
+ Assert . True ( columnEncryptionKey . SequenceEqual ( columnEncryptionKeyReturnedCSP2Cert ) ) ;
158
48
}
159
49
160
50
[ ConditionalTheory ( typeof ( DataTestUtility ) , nameof ( DataTestUtility . AreConnStringSetupForAE ) ) ]
161
- [ ClassData ( typeof ( AEConnectionStringProvider ) ) ]
162
- public void TestEncryptDecryptWithCSP ( string connectionString )
51
+ [ ClassData ( typeof ( AEConnectionStringProviderWithCspParameters ) ) ]
52
+ public void TestEncryptDecryptWithCSP ( string connectionString , CspParameters cspParameters )
163
53
{
164
- string providerName = @"Microsoft Enhanced RSA and AES Cryptographic Provider" ;
165
54
string keyIdentifier = DataTestUtility . GetUniqueNameForSqlServer ( "CSP" ) ;
55
+ CspParameters namedCspParameters = new CspParameters ( cspParameters . ProviderType , cspParameters . ProviderName , keyIdentifier ) ;
56
+ using SQLSetupStrategyCspProvider sqlSetupStrategyCsp = new SQLSetupStrategyCspProvider ( namedCspParameters ) ;
166
57
167
- try
168
- {
169
- CertificateUtilityWin . RSAPersistKeyInCsp ( providerName , keyIdentifier ) ;
170
- string cspPath = String . Concat ( providerName , @"/" , keyIdentifier ) ;
171
-
172
- SQLSetupStrategyCspExt sqlSetupStrategyCsp = new SQLSetupStrategyCspExt ( cspPath ) ;
173
- string tableName = sqlSetupStrategyCsp . CspProviderTable . Name ;
174
-
175
- try
176
- {
177
- using SqlConnection sqlConn = new ( connectionString ) ;
178
- sqlConn . Open ( ) ;
179
-
180
- Table . DeleteData ( tableName , sqlConn ) ;
181
-
182
- // insert 1 row data
183
- Customer customer = new Customer ( 45 , "Microsoft" , "Corporation" ) ;
184
-
185
- DatabaseHelper . InsertCustomerData ( sqlConn , null , tableName , customer ) ;
58
+ using SqlConnection sqlConn = new ( connectionString ) ;
59
+ sqlConn . Open ( ) ;
186
60
187
- // Test INPUT parameter on an encrypted parameter
188
- using SqlCommand sqlCommand = new ( @$ "SELECT CustomerId, FirstName, LastName FROM [{ tableName } ] WHERE FirstName = @firstName",
189
- sqlConn , null , SqlCommandColumnEncryptionSetting . Enabled ) ;
190
- SqlParameter customerFirstParam = sqlCommand . Parameters . AddWithValue ( @"firstName" , @"Microsoft" ) ;
191
- customerFirstParam . Direction = System . Data . ParameterDirection . Input ;
61
+ // Test INPUT parameter on an encrypted parameter
62
+ using SqlCommand sqlCommand = new ( @$ "SELECT CustomerId, FirstName, LastName FROM [{ sqlSetupStrategyCsp . ApiTestTable . Name } ] WHERE FirstName = @firstName",
63
+ sqlConn , null , SqlCommandColumnEncryptionSetting . Enabled ) ;
64
+ SqlParameter customerFirstParam = sqlCommand . Parameters . AddWithValue ( @"firstName" , @"Microsoft" ) ;
65
+ customerFirstParam . Direction = System . Data . ParameterDirection . Input ;
192
66
193
- using SqlDataReader sqlDataReader = sqlCommand . ExecuteReader ( ) ;
194
- ValidateResultSet ( sqlDataReader ) ;
195
- }
196
- finally
197
- {
198
- // clean up database resources
199
- sqlSetupStrategyCsp . Dispose ( ) ;
200
- }
201
- }
202
- finally
203
- {
204
- CertificateUtilityWin . RSADeleteKeyInCsp ( providerName , keyIdentifier ) ;
205
- }
67
+ using SqlDataReader sqlDataReader = sqlCommand . ExecuteReader ( ) ;
68
+ ValidateResultSet ( sqlDataReader ) ;
206
69
}
207
70
208
71
/// <summary>
0 commit comments