@@ -14,108 +14,111 @@ namespace Microsoft.Data.SqlClient.ManualTesting.Tests.AlwaysEncrypted
14
14
{
15
15
public class AKVTest : IClassFixture < SQLSetupStrategyAzureKeyVault >
16
16
{
17
- private SQLSetupStrategyAzureKeyVault fixture ;
18
- private readonly string akvTableName ;
17
+ private readonly SQLSetupStrategyAzureKeyVault _fixture ;
18
+ private readonly string _akvTableName ;
19
19
20
20
public AKVTest ( SQLSetupStrategyAzureKeyVault fixture )
21
21
{
22
- this . fixture = fixture ;
23
- akvTableName = fixture . AKVTestTable . Name ;
22
+ _fixture = fixture ;
23
+ _akvTableName = fixture . AKVTestTable . Name ;
24
24
25
25
// Disable the cache to avoid false failures.
26
26
SqlConnection . ColumnEncryptionQueryMetadataCacheEnabled = false ;
27
27
}
28
28
29
- [ ConditionalFact ( typeof ( DataTestUtility ) , nameof ( DataTestUtility . AreConnStringsSetup ) , nameof ( DataTestUtility . IsAKVSetupAvailable ) ) ]
29
+ [ ConditionalFact ( typeof ( DataTestUtility ) , nameof ( DataTestUtility . AreConnStringSetupForAE ) , nameof ( DataTestUtility . IsAKVSetupAvailable ) ) ]
30
30
public void TestEncryptDecryptWithAKV ( )
31
31
{
32
- using ( SqlConnection sqlConnection = new SqlConnection ( string . Concat ( DataTestUtility . TCPConnectionString , @";Column Encryption Setting = Enabled;" ) ) )
32
+ SqlConnectionStringBuilder builder = new ( DataTestUtility . TCPConnectionStringHGSVBS )
33
33
{
34
- sqlConnection . Open ( ) ;
35
-
36
- Customer customer = new Customer ( 45 , "Microsoft" , "Corporation" ) ;
37
-
38
- // Start a transaction and either commit or rollback based on the test variation.
39
- using ( SqlTransaction sqlTransaction = sqlConnection . BeginTransaction ( ) )
40
- {
41
- DatabaseHelper . InsertCustomerData ( sqlConnection , sqlTransaction , akvTableName , customer ) ;
42
- sqlTransaction . Commit ( ) ;
43
- }
44
-
45
- // Test INPUT parameter on an encrypted parameter
46
- using SqlCommand sqlCommand = new SqlCommand ( $ "SELECT CustomerId, FirstName, LastName FROM [{ akvTableName } ] WHERE FirstName = @firstName",
47
- sqlConnection ) ;
48
- SqlParameter customerFirstParam = sqlCommand . Parameters . AddWithValue ( @"firstName" , @"Microsoft" ) ;
49
- customerFirstParam . Direction = System . Data . ParameterDirection . Input ;
50
- customerFirstParam . ForceColumnEncryption = true ;
51
-
52
- using SqlDataReader sqlDataReader = sqlCommand . ExecuteReader ( ) ;
53
- DatabaseHelper . ValidateResultSet ( sqlDataReader ) ;
34
+ ColumnEncryptionSetting = SqlConnectionColumnEncryptionSetting . Enabled ,
35
+ AttestationProtocol = SqlConnectionAttestationProtocol . NotSpecified ,
36
+ EnclaveAttestationUrl = ""
37
+ } ;
38
+ using SqlConnection sqlConnection = new ( builder . ConnectionString ) ;
39
+
40
+ sqlConnection . Open ( ) ;
41
+ Customer customer = new ( 45 , "Microsoft" , "Corporation" ) ;
42
+
43
+ // Start a transaction and either commit or rollback based on the test variation.
44
+ using ( SqlTransaction sqlTransaction = sqlConnection . BeginTransaction ( ) )
45
+ {
46
+ DatabaseHelper . InsertCustomerData ( sqlConnection , sqlTransaction , _akvTableName , customer ) ;
47
+ sqlTransaction . Commit ( ) ;
54
48
}
49
+
50
+ // Test INPUT parameter on an encrypted parameter
51
+ using SqlCommand sqlCommand = new ( $ "SELECT CustomerId, FirstName, LastName FROM [{ _akvTableName } ] WHERE FirstName = @firstName",
52
+ sqlConnection ) ;
53
+ SqlParameter customerFirstParam = sqlCommand . Parameters . AddWithValue ( @"firstName" , @"Microsoft" ) ;
54
+ customerFirstParam . Direction = System . Data . ParameterDirection . Input ;
55
+ customerFirstParam . ForceColumnEncryption = true ;
56
+
57
+ using SqlDataReader sqlDataReader = sqlCommand . ExecuteReader ( ) ;
58
+ DatabaseHelper . ValidateResultSet ( sqlDataReader ) ;
55
59
}
56
60
57
- [ ConditionalFact ( typeof ( DataTestUtility ) , nameof ( DataTestUtility . AreConnStringsSetup ) , nameof ( DataTestUtility . IsAKVSetupAvailable ) ) ]
61
+ [ ConditionalFact ( typeof ( DataTestUtility ) , nameof ( DataTestUtility . IsAKVSetupAvailable ) ) ]
58
62
[ PlatformSpecific ( TestPlatforms . Windows ) ]
59
63
public void TestRoundTripWithAKVAndCertStoreProvider ( )
60
64
{
61
- using ( SQLSetupStrategyCertStoreProvider certStoreFixture = new SQLSetupStrategyCertStoreProvider ( ) )
62
- {
63
- byte [ ] plainTextColumnEncryptionKey = ColumnEncryptionKey . GenerateRandomBytes ( ColumnEncryptionKey . KeySizeInBytes ) ;
64
- byte [ ] encryptedColumnEncryptionKeyUsingAKV = fixture . AkvStoreProvider . EncryptColumnEncryptionKey ( DataTestUtility . AKVUrl , @"RSA_OAEP" , plainTextColumnEncryptionKey ) ;
65
- byte [ ] columnEncryptionKeyReturnedAKV2Cert = certStoreFixture . CertStoreProvider . DecryptColumnEncryptionKey ( certStoreFixture . CspColumnMasterKey . KeyPath , @"RSA_OAEP" , encryptedColumnEncryptionKeyUsingAKV ) ;
66
- Assert . True ( plainTextColumnEncryptionKey . SequenceEqual ( columnEncryptionKeyReturnedAKV2Cert ) , @"Roundtrip failed" ) ;
67
-
68
- // Try the opposite.
69
- byte [ ] encryptedColumnEncryptionKeyUsingCert = certStoreFixture . CertStoreProvider . EncryptColumnEncryptionKey ( certStoreFixture . CspColumnMasterKey . KeyPath , @"RSA_OAEP" , plainTextColumnEncryptionKey ) ;
70
- byte [ ] columnEncryptionKeyReturnedCert2AKV = fixture . AkvStoreProvider . DecryptColumnEncryptionKey ( DataTestUtility . AKVUrl , @"RSA_OAEP" , encryptedColumnEncryptionKeyUsingCert ) ;
71
- Assert . True ( plainTextColumnEncryptionKey . SequenceEqual ( columnEncryptionKeyReturnedCert2AKV ) , @"Roundtrip failed" ) ;
72
- }
65
+ using SQLSetupStrategyCertStoreProvider certStoreFixture = new ( ) ;
66
+ byte [ ] plainTextColumnEncryptionKey = ColumnEncryptionKey . GenerateRandomBytes ( ColumnEncryptionKey . KeySizeInBytes ) ;
67
+ byte [ ] encryptedColumnEncryptionKeyUsingAKV = _fixture . AkvStoreProvider . EncryptColumnEncryptionKey ( DataTestUtility . AKVUrl , @"RSA_OAEP" , plainTextColumnEncryptionKey ) ;
68
+ byte [ ] columnEncryptionKeyReturnedAKV2Cert = certStoreFixture . CertStoreProvider . DecryptColumnEncryptionKey ( certStoreFixture . CspColumnMasterKey . KeyPath , @"RSA_OAEP" , encryptedColumnEncryptionKeyUsingAKV ) ;
69
+ Assert . True ( plainTextColumnEncryptionKey . SequenceEqual ( columnEncryptionKeyReturnedAKV2Cert ) , @"Roundtrip failed" ) ;
70
+
71
+ // Try the opposite.
72
+ byte [ ] encryptedColumnEncryptionKeyUsingCert = certStoreFixture . CertStoreProvider . EncryptColumnEncryptionKey ( certStoreFixture . CspColumnMasterKey . KeyPath , @"RSA_OAEP" , plainTextColumnEncryptionKey ) ;
73
+ byte [ ] columnEncryptionKeyReturnedCert2AKV = _fixture . AkvStoreProvider . DecryptColumnEncryptionKey ( DataTestUtility . AKVUrl , @"RSA_OAEP" , encryptedColumnEncryptionKeyUsingCert ) ;
74
+ Assert . True ( plainTextColumnEncryptionKey . SequenceEqual ( columnEncryptionKeyReturnedCert2AKV ) , @"Roundtrip failed" ) ;
73
75
}
74
76
75
- [ ConditionalFact ( typeof ( DataTestUtility ) , nameof ( DataTestUtility . AreConnStringsSetup ) , nameof ( DataTestUtility . IsAKVSetupAvailable ) ) ]
77
+ [ ConditionalFact ( typeof ( DataTestUtility ) , nameof ( DataTestUtility . AreConnStringSetupForAE ) , nameof ( DataTestUtility . IsAKVSetupAvailable ) ) ]
76
78
public void TestLocalCekCacheIsScopedToProvider ( )
77
79
{
78
- using ( SqlConnection sqlConnection = new ( string . Concat ( DataTestUtility . TCPConnectionString , @";Column Encryption Setting = Enabled;" ) ) )
80
+ SqlConnectionStringBuilder builder = new ( DataTestUtility . TCPConnectionStringHGSVBS )
79
81
{
80
- sqlConnection . Open ( ) ;
82
+ ColumnEncryptionSetting = SqlConnectionColumnEncryptionSetting . Enabled ,
83
+ AttestationProtocol = SqlConnectionAttestationProtocol . NotSpecified ,
84
+ EnclaveAttestationUrl = ""
85
+ } ;
86
+
87
+ using SqlConnection sqlConnection = new ( builder . ConnectionString ) ;
81
88
82
- Customer customer = new ( 45 , "Microsoft" , "Corporation" ) ;
89
+ sqlConnection . Open ( ) ;
83
90
84
- // Test INPUT parameter on an encrypted parameter
85
- using ( SqlCommand sqlCommand = new ( $ "SELECT CustomerId, FirstName, LastName FROM [{ akvTableName } ] WHERE FirstName = @firstName",
86
- sqlConnection ) )
87
- {
88
- SqlParameter customerFirstParam = sqlCommand . Parameters . AddWithValue ( @"firstName" , @"Microsoft" ) ;
89
- customerFirstParam . Direction = System . Data . ParameterDirection . Input ;
90
- customerFirstParam . ForceColumnEncryption = true ;
91
+ // Test INPUT parameter on an encrypted parameter
92
+ using SqlCommand sqlCommand = new ( $ "SELECT CustomerId, FirstName, LastName FROM [{ _akvTableName } ] WHERE FirstName = @firstName",
93
+ sqlConnection ) ;
94
+ SqlParameter customerFirstParam = sqlCommand . Parameters . AddWithValue ( @"firstName" , @"Microsoft" ) ;
95
+ customerFirstParam . Direction = System . Data . ParameterDirection . Input ;
96
+ customerFirstParam . ForceColumnEncryption = true ;
91
97
92
- SqlDataReader sqlDataReader = sqlCommand . ExecuteReader ( ) ;
93
- sqlDataReader . Close ( ) ;
98
+ SqlDataReader sqlDataReader = sqlCommand . ExecuteReader ( ) ;
99
+ sqlDataReader . Close ( ) ;
94
100
95
- SqlColumnEncryptionAzureKeyVaultProvider sqlColumnEncryptionAzureKeyVaultProvider =
96
- new ( new SqlClientCustomTokenCredential ( ) ) ;
101
+ SqlColumnEncryptionAzureKeyVaultProvider sqlColumnEncryptionAzureKeyVaultProvider =
102
+ new ( new SqlClientCustomTokenCredential ( ) ) ;
97
103
98
- Dictionary < string , SqlColumnEncryptionKeyStoreProvider > customProvider = new ( )
104
+ Dictionary < string , SqlColumnEncryptionKeyStoreProvider > customProvider = new ( )
99
105
{
100
106
{ SqlColumnEncryptionAzureKeyVaultProvider . ProviderName , sqlColumnEncryptionAzureKeyVaultProvider }
101
107
} ;
102
108
103
- // execute a query using provider from command-level cache. this will cache the cek in the local cek cache
104
- sqlCommand . RegisterColumnEncryptionKeyStoreProvidersOnCommand ( customProvider ) ;
105
- SqlDataReader sqlDataReader2 = sqlCommand . ExecuteReader ( ) ;
106
- sqlDataReader2 . Close ( ) ;
107
-
108
- // global cek cache and local cek cache are populated above
109
- // when using a new per-command provider, it will only use its local cek cache
110
- // the following query should fail due to an empty cek cache and invalid credentials
111
- customProvider [ SqlColumnEncryptionAzureKeyVaultProvider . ProviderName ] =
112
- new SqlColumnEncryptionAzureKeyVaultProvider ( new ClientSecretCredential ( "tenant" , "client" , "secret" ) ) ;
113
- sqlCommand . RegisterColumnEncryptionKeyStoreProvidersOnCommand ( customProvider ) ;
114
- Exception ex = Assert . Throws < SqlException > ( ( ) => sqlCommand . ExecuteReader ( ) ) ;
115
- Assert . Contains ( "ClientSecretCredential authentication failed" , ex . Message ) ;
116
- }
117
- }
109
+ // execute a query using provider from command-level cache. this will cache the cek in the local cek cache
110
+ sqlCommand . RegisterColumnEncryptionKeyStoreProvidersOnCommand ( customProvider ) ;
111
+ SqlDataReader sqlDataReader2 = sqlCommand . ExecuteReader ( ) ;
112
+ sqlDataReader2 . Close ( ) ;
113
+
114
+ // global cek cache and local cek cache are populated above
115
+ // when using a new per-command provider, it will only use its local cek cache
116
+ // the following query should fail due to an empty cek cache and invalid credentials
117
+ customProvider [ SqlColumnEncryptionAzureKeyVaultProvider . ProviderName ] =
118
+ new SqlColumnEncryptionAzureKeyVaultProvider ( new ClientSecretCredential ( "tenant" , "client" , "secret" ) ) ;
119
+ sqlCommand . RegisterColumnEncryptionKeyStoreProvidersOnCommand ( customProvider ) ;
120
+ Exception ex = Assert . Throws < SqlException > ( ( ) => sqlCommand . ExecuteReader ( ) ) ;
121
+ Assert . StartsWith ( "The current credential is not configured to acquire tokens for tenant" , ex . InnerException . Message ) ;
118
122
}
119
-
120
123
}
121
124
}
0 commit comments