php-sqlsrv/test/functional/sqlsrv/sqlsrv_ae_azure_key_vault_keywords.phpt

198 lines
7.7 KiB
Plaintext
Raw Normal View History

2018-05-06 02:08:01 +02:00
--TEST--
2018-05-18 21:24:37 +02:00
Test connection keywords for Azure Key Vault for Always Encrypted.
2018-05-06 02:08:01 +02:00
--SKIPIF--
<?php require('skipif_azure.inc');
require('skipif_versions_old.inc'); ?>
2018-05-06 02:08:01 +02:00
--FILE--
<?php
require_once('sqlsrv_ae_azure_key_vault_common.php');
2018-05-06 02:08:01 +02:00
// This test only applies to Azure Key Vault, or to no encryption at all
if ($keystore != 'none' and $keystore != 'akv') {
echo "Done.\n";
exit();
}
2018-05-06 02:08:01 +02:00
// We will test the direct product (set of all possible combinations) of the following
$columnEncryption = ['enabled', 'disabled', 'notvalid', ''];
$keyStoreAuthentication = ['KeyVaultPassword', 'KeyVaultClientSecret', 'KeyVaultNothing', ''];
2018-05-09 01:16:27 +02:00
$keyStorePrincipalId = [$AKVPrincipalName, $AKVClientID, 'notaname', ''];
2018-05-06 02:08:01 +02:00
$keyStoreSecret = [$AKVPassword, $AKVSecret, 'notasecret', ''];
function checkErrors($errors, ...$codes)
2018-05-18 21:24:37 +02:00
{
$codeFound = false;
2018-05-18 23:05:18 +02:00
2018-05-18 21:24:37 +02:00
foreach ($codes as $code) {
if ($code[0]==$errors[0][0] and $code[1]==$errors[0][1]) {
$codeFound = true;
2018-05-18 21:24:37 +02:00
}
}
2018-05-18 23:05:18 +02:00
2018-05-18 21:24:37 +02:00
if ($codeFound == false) {
echo "Error: ";
print_r($errors);
echo "\nExpected: ";
print_r($codes);
echo "\n";
fatalError("Error code not found.\n");
2018-05-06 02:08:01 +02:00
}
}
2018-05-25 23:42:32 +02:00
// The array of data types corresponding to $small_values in values.php.
// SHORT_STRSIZE is defined in values.php as well.
$dataTypes = array("char(".SHORT_STRSIZE.")", "varchar(".SHORT_STRSIZE.")", "nvarchar(".SHORT_STRSIZE.")",
2018-05-06 02:08:01 +02:00
"decimal", "float", "real", "bigint", "int", "bit"
);
2018-05-09 01:16:27 +02:00
$tableName = "akv_comparison_table";
// First determine if the server is AE v2 enabled
$isEnclaveEnabled = false;
$connectionOptions = array("CharacterSet"=>"UTF-8",
"database"=>$databaseName,
"uid"=>$uid,
"pwd"=>$pwd,
"ConnectionPooling"=>0);
$conn = sqlsrv_connect($server, $connectionOptions);
if (!$conn) {
fatalError("Initial connection failed\n");
} else {
$query = "SELECT [name], [value], [value_in_use] FROM sys.configurations WHERE [name] = 'column encryption enclave type';";
$stmt = sqlsrv_query($conn, $query);
$info = sqlsrv_fetch_array($stmt);
if (!empty($info) and $info['value'] == 1 and $info['value_in_use'] == 1) {
$isEnclaveEnabled = true;
}
sqlsrv_query($conn, "DBCC FREEPROCCACHE");
}
unset($conn);
2018-05-09 01:16:27 +02:00
// Test every combination of the keywords above.
2018-05-18 21:24:37 +02:00
// Leave out good credentials to ensure that caching does not influence the
2018-05-09 01:16:27 +02:00
// results. The cache timeout can only be changed with SQLSetConnectAttr, so
// we can't run a PHP test without caching, and if we started with good
// credentials then subsequent calls with bad credentials can work, which
// would muddle the results of this test. Good credentials are tested in a
// separate test.
2018-05-18 23:05:18 +02:00
for ($i = 0; $i < sizeof($columnEncryption); ++$i) {
for ($j = 0; $j < sizeof($keyStoreAuthentication); ++$j) {
for ($k = 0; $k < sizeof($keyStorePrincipalId); ++$k) {
for ($m = 0; $m < sizeof($keyStoreSecret); ++$m) {
2018-05-18 21:24:37 +02:00
$connectionOptions = array("CharacterSet"=>"UTF-8",
"database"=>$databaseName,
"uid"=>$uid,
2018-05-06 02:08:01 +02:00
"pwd"=>$pwd,
"ConnectionPooling"=>0);
2018-05-18 23:05:18 +02:00
2018-05-18 21:24:37 +02:00
if (!empty($columnEncryption[$i])) {
2018-05-06 02:08:01 +02:00
$connectionOptions['ColumnEncryption'] = $columnEncryption[$i];
2018-05-18 21:24:37 +02:00
}
if (!empty($keyStoreAuthentication[$j])) {
2018-05-06 02:08:01 +02:00
$connectionOptions['KeyStoreAuthentication'] = $keyStoreAuthentication[$j];
2018-05-18 21:24:37 +02:00
}
if (!empty($keyStorePrincipalId[$k])) {
$connectionOptions['KeyStorePrincipalId'] = $keyStorePrincipalId[$k];
}
if (!empty($keyStoreSecret[$m])) {
2018-05-06 02:08:01 +02:00
$connectionOptions['KeyStoreSecret'] = $keyStoreSecret[$m];
2018-05-18 21:24:37 +02:00
}
2018-05-06 02:08:01 +02:00
// Valid credentials getting skipped
2018-05-18 23:05:18 +02:00
if (($i == 0 and $j == 0 and $k == 0 and $m == 0) or
($i == 0 and $j == 1 and $k == 1 and $m == 1)) {
2018-05-06 02:08:01 +02:00
continue;
}
// Connect to the AE-enabled database
// Failure is expected when the keyword combination is wrong
$conn = sqlsrv_connect($server, $connectionOptions);
2018-05-18 21:24:37 +02:00
if (!$conn) {
2018-05-06 02:08:01 +02:00
$errors = sqlsrv_errors();
2018-05-18 23:05:18 +02:00
2018-05-18 21:24:37 +02:00
checkErrors(
$errors,
array('08001','0'),
array('08001','-1'), // SSL error on some Linuxes
2018-05-18 21:24:37 +02:00
array('IMSSP','-110'),
array('IMSSP','-111'),
array('IMSSP','-112'),
array('IMSSP','-113'),
array('CE400','0')
2018-05-18 21:24:37 +02:00
);
} else {
2018-05-06 02:08:01 +02:00
$columns = array();
$insertQuery = "";
// Generate the INSERT query
2018-05-18 23:05:18 +02:00
formulateSetupQuery($tableName, $dataTypes, $columns, $insertQuery);
2018-05-06 02:08:01 +02:00
$stmt = AE\createTable($conn, $tableName, $columns);
if (!$stmt) {
fatalError("Failed to create table $tableName.\n");
}
// Duplicate all values for insertion - one is encrypted, one is not
$testValues = array();
2018-05-18 23:05:18 +02:00
for ($n = 0; $n < sizeof($small_values); ++$n) {
2018-05-06 02:08:01 +02:00
$testValues[] = $small_values[$n];
$testValues[] = $small_values[$n];
}
// Prepare the INSERT query
// This is never expected to fail
$stmt = sqlsrv_prepare($conn, $insertQuery, $testValues);
if ($stmt == false) {
print_r(sqlsrv_errors());
fatalError("sqlsrv_prepare failed.\n");
}
// Execute the INSERT query
// This is where we expect failure if the credentials are incorrect
if (sqlsrv_execute($stmt) == false) {
$errors = sqlsrv_errors();
2018-05-18 23:05:18 +02:00
2018-05-30 01:22:26 +02:00
if (!AE\isDataEncrypted()) {
2018-05-18 21:24:37 +02:00
checkErrors(
$errors,
array('CE258', '0'),
array('CE275', '0')
);
} else {
checkErrors(
$errors,
array('CE258', '0'),
array('CE275', '0'),
array('22018', '206')
);
}
2018-05-18 23:05:18 +02:00
2018-05-06 02:08:01 +02:00
sqlsrv_free_stmt($stmt);
2018-05-18 21:24:37 +02:00
} else {
2018-05-10 00:21:40 +02:00
// The INSERT query succeeded with bad credentials, which
// should only happen when 1. encryption is not enabled or
// 2. when ColumnEncryption is set to something other than
// enabled or disabled (i.e. $i == 2), and the server is
// not enclave-enabled
if (!(!AE\isDataEncrypted() or ($i == 2 and !$isEnclaveEnabled))) {
2018-05-18 21:24:37 +02:00
fatalError("Successful insertion with bad credentials\n");
}
2018-05-06 02:08:01 +02:00
}
2018-05-18 23:05:18 +02:00
2018-05-26 00:19:20 +02:00
// Drop the table and close the connection
dropTable($conn, $tableName);
2018-05-06 02:08:01 +02:00
sqlsrv_close($conn);
}
}
}
}
}
2018-05-09 01:16:27 +02:00
echo "Done.\n";
2018-05-06 02:08:01 +02:00
?>
--EXPECT--
2018-05-09 01:16:27 +02:00
Done.