Changes according to PR comments
This commit is contained in:
parent
fb1a2ecb70
commit
364fef6908
|
@ -93,10 +93,10 @@ function getDSN($sqlsrvserver, $database, $keywords = '', $disableCE = false)
|
||||||
$dsn .= "ColumnEncryption=Enabled;";
|
$dsn .= "ColumnEncryption=Enabled;";
|
||||||
}
|
}
|
||||||
if ($keystore == "akv" && !$disableCE) {
|
if ($keystore == "akv" && !$disableCE) {
|
||||||
if ($keyStoreAuthentication == "KeyVaultPassword") {
|
if ($AKVKeyStoreAuthentication == "KeyVaultPassword") {
|
||||||
$dsn .= "KeyStoreAuthentication=$keyStoreAuthentication;KeyStorePrincipalId=$principalName;KeyStoreSecret=$AKVPassword;";
|
$dsn .= "KeyStoreAuthentication=$AKVKeyStoreAuthentication;KeyStorePrincipalId=$AKVPrincipalName;KeyStoreSecret=$AKVPassword;";
|
||||||
} else if ($keyStoreAuthentication == "KeyVaultClientSecret") {
|
} else if ($AKVKeyStoreAuthentication == "KeyVaultClientSecret") {
|
||||||
$dsn .= "KeyStoreAuthentication=$keyStoreAuthentication;KeyStorePrincipalId=$clientID;KeyStoreSecret=$AKVSecret;";
|
$dsn .= "KeyStoreAuthentication=$AKVKeyStoreAuthentication;KeyStorePrincipalId=$AKVClientID;KeyStoreSecret=$AKVSecret;";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($keystore == "ksp" && !$disableCE) {
|
if ($keystore == "ksp" && !$disableCE) {
|
||||||
|
|
|
@ -11,7 +11,7 @@ require_once('values.php');
|
||||||
// We will test the direct product (set of all possible combinations) of the following
|
// We will test the direct product (set of all possible combinations) of the following
|
||||||
$columnEncryption = ['enabled', 'disabled', 'notvalid', ''];
|
$columnEncryption = ['enabled', 'disabled', 'notvalid', ''];
|
||||||
$keyStoreAuthentication = ['KeyVaultPassword', 'KeyVaultClientSecret', 'KeyVaultNothing', ''];
|
$keyStoreAuthentication = ['KeyVaultPassword', 'KeyVaultClientSecret', 'KeyVaultNothing', ''];
|
||||||
$keyStorePrincipalId = [$principalName, $clientID, 'notaname', ''];
|
$keyStorePrincipalId = [$AKVPrincipalName, $AKVClientID, 'notaname', ''];
|
||||||
$keyStoreSecret = [$AKVPassword, $AKVSecret, 'notasecret', ''];
|
$keyStoreSecret = [$AKVPassword, $AKVSecret, 'notasecret', ''];
|
||||||
|
|
||||||
function checkErrors($errors, ...$codes)
|
function checkErrors($errors, ...$codes)
|
||||||
|
@ -79,6 +79,8 @@ $dataTypes = array ("char($strsize)", "varchar($strsize)", "nvarchar($strsize)",
|
||||||
"decimal", "float", "real", "bigint", "int", "bit"
|
"decimal", "float", "real", "bigint", "int", "bit"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$tableName = "akv_comparison_table";
|
||||||
|
|
||||||
// Test every combination of the keywords above
|
// Test every combination of the keywords above
|
||||||
// Leave good credentials to the end to avoid caching influencing the results.
|
// Leave good credentials to the end to avoid caching influencing the results.
|
||||||
// The cache timeout can only be changed with SQLSetConnectAttr, so we can't
|
// The cache timeout can only be changed with SQLSetConnectAttr, so we can't
|
||||||
|
@ -113,8 +115,6 @@ for ($i=0; $i < sizeof($columnEncryption); ++$i) {
|
||||||
$conn = new PDO($connectionOptions, $uid, $pwd);
|
$conn = new PDO($connectionOptions, $uid, $pwd);
|
||||||
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||||
|
|
||||||
$tableName = "type_conversion_table";
|
|
||||||
|
|
||||||
$columns = array();
|
$columns = array();
|
||||||
$insertQuery = "";
|
$insertQuery = "";
|
||||||
|
|
||||||
|
@ -175,163 +175,7 @@ for ($i=0; $i < sizeof($columnEncryption); ++$i) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now test the good credentials, where ($i, $j, $k, $m) == (0, 0, 0, 0)
|
echo "Done.\n";
|
||||||
// and ($i, $j, $k, $m) == (0, 1, 1, 1)
|
|
||||||
$connectionOptions = "sqlsrv:Server=$server;Database=$databaseName";
|
|
||||||
|
|
||||||
$connectionOptions .= ";ColumnEncryption=".$columnEncryption[0];
|
|
||||||
$connectionOptions .= ";KeyStoreAuthentication=".$keyStoreAuthentication[0];
|
|
||||||
$connectionOptions .= ";KeyStorePrincipalId=".$keyStorePrincipalId[0];
|
|
||||||
$connectionOptions .= ";KeyStoreSecret=".$keyStoreSecret[0];
|
|
||||||
|
|
||||||
$connectionOptions .= ";";
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Connect to the AE-enabled database
|
|
||||||
$conn = new PDO($connectionOptions, $uid, $pwd);
|
|
||||||
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
|
||||||
|
|
||||||
$tableName = "type_conversion_table";
|
|
||||||
|
|
||||||
$columns = array();
|
|
||||||
$insertQuery = "";
|
|
||||||
|
|
||||||
// Generate the INSERT query
|
|
||||||
FormulateSetupQuery($tableName, $dataTypes, $columns, $insertQuery);
|
|
||||||
|
|
||||||
createTable($conn, $tableName, $columns);
|
|
||||||
|
|
||||||
// Duplicate all values for insertion - one is encrypted, one is not
|
|
||||||
$testValues = array();
|
|
||||||
for ($n=0; $n<sizeof($small_values); ++$n) {
|
|
||||||
$testValues[] = $small_values[$n];
|
|
||||||
$testValues[] = $small_values[$n];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prepare the INSERT query
|
|
||||||
// This is never expected to fail
|
|
||||||
$stmt = $conn->prepare($insertQuery);
|
|
||||||
if ($stmt == false) {
|
|
||||||
print_r($conn->errorInfo());
|
|
||||||
fatalError("sqlsrv_prepare failed\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Execute the INSERT query
|
|
||||||
// This should not fail since our credentials are correct
|
|
||||||
if ($stmt->execute($testValues) == false) {
|
|
||||||
print_r($stmt->errorInfo());
|
|
||||||
fatalError("INSERT query execution failed with good credentials.\n");
|
|
||||||
} else {
|
|
||||||
echo "Successful insertion with username/password.\n";
|
|
||||||
|
|
||||||
$selectQuery = "SELECT * FROM $tableName";
|
|
||||||
|
|
||||||
$stmt1 = $conn->query($selectQuery);
|
|
||||||
|
|
||||||
$data = $stmt1->fetchAll(PDO::FETCH_NUM);
|
|
||||||
$data = $data[0];
|
|
||||||
|
|
||||||
if (sizeof($data) != 2*sizeof($dataTypes)) {
|
|
||||||
fatalError("Incorrect number of fields returned.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
for ($n=0; $n<sizeof($data); $n+=2) {
|
|
||||||
if ($data[$n] != $data[$n+1]) {
|
|
||||||
echo "Failed on field $n: ".$data[$n]." ".$data[$n+1]."\n";
|
|
||||||
fatalError("AE and non-AE values do not match.\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$stmt = null;
|
|
||||||
$stmt1 = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Free the statement and close the connection
|
|
||||||
$stmt = null;
|
|
||||||
$conn = null;
|
|
||||||
} catch(Exception $e) {
|
|
||||||
echo "Unexpected error.\n";
|
|
||||||
print_r($e->errorInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
$connectionOptions = "sqlsrv:Server=$server;Database=$databaseName";
|
|
||||||
|
|
||||||
$connectionOptions .= ";ColumnEncryption=".$columnEncryption[0];
|
|
||||||
$connectionOptions .= ";KeyStoreAuthentication=".$keyStoreAuthentication[1];
|
|
||||||
$connectionOptions .= ";KeyStorePrincipalId=".$keyStorePrincipalId[1];
|
|
||||||
$connectionOptions .= ";KeyStoreSecret=".$keyStoreSecret[1];
|
|
||||||
|
|
||||||
$connectionOptions .= ";";
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Connect to the AE-enabled database
|
|
||||||
$conn = new PDO($connectionOptions, $uid, $pwd);
|
|
||||||
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
|
||||||
|
|
||||||
$tableName = "type_conversion_table";
|
|
||||||
|
|
||||||
$columns = array();
|
|
||||||
$insertQuery = "";
|
|
||||||
|
|
||||||
// Generate the INSERT query
|
|
||||||
FormulateSetupQuery($tableName, $dataTypes, $columns, $insertQuery);
|
|
||||||
|
|
||||||
createTable($conn, $tableName, $columns);
|
|
||||||
|
|
||||||
// Duplicate all values for insertion - one is encrypted, one is not
|
|
||||||
$testValues = array();
|
|
||||||
for ($n=0; $n<sizeof($small_values); ++$n) {
|
|
||||||
$testValues[] = $small_values[$n];
|
|
||||||
$testValues[] = $small_values[$n];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prepare the INSERT query
|
|
||||||
// This is never expected to fail
|
|
||||||
$stmt = $conn->prepare($insertQuery);
|
|
||||||
if ($stmt == false) {
|
|
||||||
print_r($conn->errorInfo());
|
|
||||||
fatalError("sqlsrv_prepare failed\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Execute the INSERT query
|
|
||||||
// This should not fail since our credentials are correct
|
|
||||||
if ($stmt->execute($testValues) == false) {
|
|
||||||
print_r($stmt->errorInfo());
|
|
||||||
fatalError("INSERT query execution failed with good credentials.\n");
|
|
||||||
} else {
|
|
||||||
echo "Successful insertion with client ID/secret.\n";
|
|
||||||
|
|
||||||
$selectQuery = "SELECT * FROM $tableName";
|
|
||||||
|
|
||||||
$stmt1 = $conn->query($selectQuery);
|
|
||||||
|
|
||||||
$data = $stmt1->fetchAll(PDO::FETCH_NUM);
|
|
||||||
$data = $data[0];
|
|
||||||
|
|
||||||
if (sizeof($data) != 2*sizeof($dataTypes)) {
|
|
||||||
fatalError("Incorrect number of fields returned.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
for ($n=0; $n<sizeof($data); $n+=2) {
|
|
||||||
if ($data[$n] != $data[$n+1]) {
|
|
||||||
echo "Failed on field $n: ".$data[$n]." ".$data[$n+1]."\n";
|
|
||||||
fatalError("AE and non-AE values do not match.\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$stmt = null;
|
|
||||||
$stmt1 = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Free the statement and close the connection
|
|
||||||
$stmt = null;
|
|
||||||
$conn = null;
|
|
||||||
} catch(Exception $e) {
|
|
||||||
echo "Unexpected error2.\n";
|
|
||||||
print_r($e->errorInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
?>
|
||||||
--EXPECT--
|
--EXPECT--
|
||||||
Successful insertion with username/password.
|
Done.
|
||||||
Successful insertion with clinet ID/secret.
|
|
||||||
|
|
|
@ -0,0 +1,198 @@
|
||||||
|
--TEST--
|
||||||
|
Test connection keywords and credentials for Azure Key Vault for Always Encrypted.
|
||||||
|
--SKIPIF--
|
||||||
|
<?php require('skipif_mid-refactor.inc'); ?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
require_once("MsCommon_mid-refactor.inc");
|
||||||
|
require_once("MsSetup.inc");
|
||||||
|
require_once('values.php');
|
||||||
|
|
||||||
|
// Set up the columns and build the insert query. Each data type has an
|
||||||
|
// AE-encrypted and a non-encrypted column side by side in the table.
|
||||||
|
function FormulateSetupQuery($tableName, &$dataTypes, &$columns, &$insertQuery)
|
||||||
|
{
|
||||||
|
$columns = array();
|
||||||
|
$queryTypes = "(";
|
||||||
|
$queryTypesAE = "(";
|
||||||
|
$valuesString = "VALUES (";
|
||||||
|
$numTypes = sizeof($dataTypes);
|
||||||
|
|
||||||
|
for ($i = 0; $i < $numTypes; ++$i) {
|
||||||
|
// Replace parentheses for column names
|
||||||
|
$colname = str_replace(array("(", ",", ")"), array("_", "_", ""), $dataTypes[$i]);
|
||||||
|
$columns[] = new ColumnMeta($dataTypes[$i], "c_".$colname."_AE", null, "deterministic", false);
|
||||||
|
$columns[] = new ColumnMeta($dataTypes[$i], "c_".$colname, null, "none", false);
|
||||||
|
$queryTypes .= "c_"."$colname, ";
|
||||||
|
$queryTypes .= "c_"."$colname"."_AE, ";
|
||||||
|
$valuesString .= "?, ?, ";
|
||||||
|
}
|
||||||
|
|
||||||
|
$queryTypes = substr($queryTypes, 0, -2).")";
|
||||||
|
$valuesString = substr($valuesString, 0, -2).")";
|
||||||
|
|
||||||
|
$insertQuery = "INSERT INTO $tableName ".$queryTypes." ".$valuesString;
|
||||||
|
}
|
||||||
|
|
||||||
|
$strsize = 64;
|
||||||
|
|
||||||
|
$dataTypes = array ("char($strsize)", "varchar($strsize)", "nvarchar($strsize)",
|
||||||
|
"decimal", "float", "real", "bigint", "int", "bit"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Test data insertion and retrieval with username/password
|
||||||
|
// and client Id/client secret combinations.
|
||||||
|
$connectionOptions = "sqlsrv:Server=$server;Database=$databaseName";
|
||||||
|
|
||||||
|
$connectionOptions .= ";ColumnEncryption=enabled";
|
||||||
|
$connectionOptions .= ";KeyStoreAuthentication=KeyVaultPassword";
|
||||||
|
$connectionOptions .= ";KeyStorePrincipalId=".$AKVPrincipalName;
|
||||||
|
$connectionOptions .= ";KeyStoreSecret=".$AKVPassword;
|
||||||
|
$connectionOptions .= ";";
|
||||||
|
|
||||||
|
$tableName = "akv_comparison_table";
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Connect to the AE-enabled database
|
||||||
|
$conn = new PDO($connectionOptions, $uid, $pwd);
|
||||||
|
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||||
|
|
||||||
|
$columns = array();
|
||||||
|
$insertQuery = "";
|
||||||
|
|
||||||
|
// Generate the INSERT query
|
||||||
|
FormulateSetupQuery($tableName, $dataTypes, $columns, $insertQuery);
|
||||||
|
|
||||||
|
createTable($conn, $tableName, $columns);
|
||||||
|
|
||||||
|
// Duplicate all values for insertion - one is encrypted, one is not
|
||||||
|
$testValues = array();
|
||||||
|
for ($n=0; $n<sizeof($small_values); ++$n) {
|
||||||
|
$testValues[] = $small_values[$n];
|
||||||
|
$testValues[] = $small_values[$n];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare the INSERT query
|
||||||
|
// This is never expected to fail
|
||||||
|
$stmt = $conn->prepare($insertQuery);
|
||||||
|
if ($stmt == false) {
|
||||||
|
print_r($conn->errorInfo());
|
||||||
|
fatalError("sqlsrv_prepare failed\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute the INSERT query
|
||||||
|
// This should not fail since our credentials are correct
|
||||||
|
if ($stmt->execute($testValues) == false) {
|
||||||
|
print_r($stmt->errorInfo());
|
||||||
|
fatalError("INSERT query execution failed with good credentials.\n");
|
||||||
|
} else {
|
||||||
|
$selectQuery = "SELECT * FROM $tableName";
|
||||||
|
|
||||||
|
$stmt1 = $conn->query($selectQuery);
|
||||||
|
|
||||||
|
$data = $stmt1->fetchAll(PDO::FETCH_NUM);
|
||||||
|
$data = $data[0];
|
||||||
|
|
||||||
|
if (sizeof($data) != 2*sizeof($dataTypes)) {
|
||||||
|
fatalError("Incorrect number of fields returned.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
for ($n=0; $n<sizeof($data); $n+=2) {
|
||||||
|
if ($data[$n] != $data[$n+1]) {
|
||||||
|
echo "Failed on field $n: ".$data[$n]." ".$data[$n+1]."\n";
|
||||||
|
fatalError("AE and non-AE values do not match.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "Successful insertion and retrieval with username/password.\n";
|
||||||
|
|
||||||
|
$stmt = null;
|
||||||
|
$stmt1 = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Free the statement and close the connection
|
||||||
|
$stmt = null;
|
||||||
|
$conn = null;
|
||||||
|
} catch(Exception $e) {
|
||||||
|
echo "Unexpected error.\n";
|
||||||
|
print_r($e->errorInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
$connectionOptions = "sqlsrv:Server=$server;Database=$databaseName";
|
||||||
|
|
||||||
|
$connectionOptions .= ";ColumnEncryption=enabled";
|
||||||
|
$connectionOptions .= ";KeyStoreAuthentication=KeyVaultClientSecret";
|
||||||
|
$connectionOptions .= ";KeyStorePrincipalId=".$AKVClientID;
|
||||||
|
$connectionOptions .= ";KeyStoreSecret=".$AKVSecret;
|
||||||
|
$connectionOptions .= ";";
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Connect to the AE-enabled database
|
||||||
|
$conn = new PDO($connectionOptions, $uid, $pwd);
|
||||||
|
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||||
|
|
||||||
|
$columns = array();
|
||||||
|
$insertQuery = "";
|
||||||
|
|
||||||
|
// Generate the INSERT query
|
||||||
|
FormulateSetupQuery($tableName, $dataTypes, $columns, $insertQuery);
|
||||||
|
|
||||||
|
createTable($conn, $tableName, $columns);
|
||||||
|
|
||||||
|
// Duplicate all values for insertion - one is encrypted, one is not
|
||||||
|
$testValues = array();
|
||||||
|
for ($n=0; $n<sizeof($small_values); ++$n) {
|
||||||
|
$testValues[] = $small_values[$n];
|
||||||
|
$testValues[] = $small_values[$n];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare the INSERT query
|
||||||
|
// This is never expected to fail
|
||||||
|
$stmt = $conn->prepare($insertQuery);
|
||||||
|
if ($stmt == false) {
|
||||||
|
print_r($conn->errorInfo());
|
||||||
|
fatalError("sqlsrv_prepare failed\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute the INSERT query
|
||||||
|
// This should not fail since our credentials are correct
|
||||||
|
if ($stmt->execute($testValues) == false) {
|
||||||
|
print_r($stmt->errorInfo());
|
||||||
|
fatalError("INSERT query execution failed with good credentials.\n");
|
||||||
|
} else {
|
||||||
|
$selectQuery = "SELECT * FROM $tableName";
|
||||||
|
|
||||||
|
$stmt1 = $conn->query($selectQuery);
|
||||||
|
|
||||||
|
$data = $stmt1->fetchAll(PDO::FETCH_NUM);
|
||||||
|
$data = $data[0];
|
||||||
|
|
||||||
|
if (sizeof($data) != 2*sizeof($dataTypes)) {
|
||||||
|
fatalError("Incorrect number of fields returned.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
for ($n=0; $n<sizeof($data); $n+=2) {
|
||||||
|
if ($data[$n] != $data[$n+1]) {
|
||||||
|
echo "Failed on field $n: ".$data[$n]." ".$data[$n+1]."\n";
|
||||||
|
fatalError("AE and non-AE values do not match.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "Successful insertion and retrieval with client ID/secret.\n";
|
||||||
|
|
||||||
|
$stmt = null;
|
||||||
|
$stmt1 = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Free the statement and close the connection
|
||||||
|
$stmt = null;
|
||||||
|
$conn = null;
|
||||||
|
} catch(Exception $e) {
|
||||||
|
echo "Unexpected error.\n";
|
||||||
|
print_r($e->errorInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
||||||
|
Successful insertion and retrieval with username/password.
|
||||||
|
Successful insertion and retrieval with client ID/secret.
|
|
@ -360,12 +360,12 @@ function connect($options = array(), $disableCE = false)
|
||||||
$connectionOptions = array_merge($connectionOptions, array("ColumnEncryption" => "Enabled"));
|
$connectionOptions = array_merge($connectionOptions, array("ColumnEncryption" => "Enabled"));
|
||||||
}
|
}
|
||||||
if ($keystore == 'akv') {
|
if ($keystore == 'akv') {
|
||||||
$akv_options = array("KeyStoreAuthentication"=>$keyStoreAuthentication);
|
$akv_options = array("KeyStoreAuthentication"=>$AKVKeyStoreAuthentication);
|
||||||
if ($keyStoreAuthentication == 'KeyVaultPassword') {
|
if ($AKVKeyStoreAuthentication == "KeyVaultPassword") {
|
||||||
$akv_options["KeyStorePrincipalId"] = $principalName;
|
$akv_options["KeyStorePrincipalId"] = $AKVPrincipalName;
|
||||||
$akv_options["KeyStoreSecret"] = $AKVPassword;
|
$akv_options["KeyStoreSecret"] = $AKVPassword;
|
||||||
} else if ($keyStoreAuthentication == "KeyVaultClientSecret") {
|
} else if ($AKVKeyStoreAuthentication == "KeyVaultClientSecret") {
|
||||||
$akv_options["KeyStorePrincipalId"] = $clientID;
|
$akv_options["KeyStorePrincipalId"] = $AKVClientID;
|
||||||
$akv_options["KeyStoreSecret"] = $AKVSecret;
|
$akv_options["KeyStoreSecret"] = $AKVSecret;
|
||||||
}
|
}
|
||||||
$connectionOptions = array_merge($connectionOptions, $akv_options);
|
$connectionOptions = array_merge($connectionOptions, $akv_options);
|
||||||
|
|
|
@ -11,7 +11,7 @@ require_once('values.php');
|
||||||
// We will test the direct product (set of all possible combinations) of the following
|
// We will test the direct product (set of all possible combinations) of the following
|
||||||
$columnEncryption = ['enabled', 'disabled', 'notvalid', ''];
|
$columnEncryption = ['enabled', 'disabled', 'notvalid', ''];
|
||||||
$keyStoreAuthentication = ['KeyVaultPassword', 'KeyVaultClientSecret', 'KeyVaultNothing', ''];
|
$keyStoreAuthentication = ['KeyVaultPassword', 'KeyVaultClientSecret', 'KeyVaultNothing', ''];
|
||||||
$keyStorePrincipalId = [$principalName, $clientID, 'notaname', ''];
|
$keyStorePrincipalId = [$AKVPrincipalName, $AKVClientID, 'notaname', ''];
|
||||||
$keyStoreSecret = [$AKVPassword, $AKVSecret, 'notasecret', ''];
|
$keyStoreSecret = [$AKVPassword, $AKVSecret, 'notasecret', ''];
|
||||||
|
|
||||||
function checkErrors($errors, ...$codes)
|
function checkErrors($errors, ...$codes)
|
||||||
|
@ -49,7 +49,7 @@ function checkErrors($errors, ...$codes)
|
||||||
|
|
||||||
// Set up the columns and build the insert query. Each data type has an
|
// Set up the columns and build the insert query. Each data type has an
|
||||||
// AE-encrypted and a non-encrypted column side by side in the table.
|
// AE-encrypted and a non-encrypted column side by side in the table.
|
||||||
function FormulateSetupQuery($tableName, &$dataTypes, &$columns, &$insertQuery, $strsize)
|
function FormulateSetupQuery($tableName, &$dataTypes, &$columns, &$insertQuery)
|
||||||
{
|
{
|
||||||
$columns = array();
|
$columns = array();
|
||||||
$queryTypes = "(";
|
$queryTypes = "(";
|
||||||
|
@ -79,12 +79,15 @@ $dataTypes = array ("char($strsize)", "varchar($strsize)", "nvarchar($strsize)",
|
||||||
"decimal", "float", "real", "bigint", "int", "bit"
|
"decimal", "float", "real", "bigint", "int", "bit"
|
||||||
);
|
);
|
||||||
|
|
||||||
// Test every combination of the keywords above
|
$tableName = "akv_comparison_table";
|
||||||
// Leave good credentials to the end to avoid caching influencing the results.
|
|
||||||
// The cache timeout can only be changed with SQLSetConnectAttr, so we can't
|
// Test every combination of the keywords above.
|
||||||
// run a PHP test without caching, and if we started with good credentials
|
// Leave out good credentials to ensure that caching does not influence the
|
||||||
// then subsequent calls with bad credentials can work, which would muddle
|
// results. The cache timeout can only be changed with SQLSetConnectAttr, so
|
||||||
// the results of this test.
|
// 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.
|
||||||
for ($i=0; $i < sizeof($columnEncryption); ++$i) {
|
for ($i=0; $i < sizeof($columnEncryption); ++$i) {
|
||||||
for ($j=0; $j < sizeof($keyStoreAuthentication); ++$j) {
|
for ($j=0; $j < sizeof($keyStoreAuthentication); ++$j) {
|
||||||
for ($k=0; $k < sizeof($keyStorePrincipalId); ++$k) {
|
for ($k=0; $k < sizeof($keyStorePrincipalId); ++$k) {
|
||||||
|
@ -129,13 +132,11 @@ for ($i=0; $i < sizeof($columnEncryption); ++$i) {
|
||||||
else
|
else
|
||||||
fatalError("Connection failed, unexpected connection string.\n");
|
fatalError("Connection failed, unexpected connection string.\n");
|
||||||
} else {
|
} else {
|
||||||
$tableName = "type_conversion_table";
|
|
||||||
|
|
||||||
$columns = array();
|
$columns = array();
|
||||||
$insertQuery = "";
|
$insertQuery = "";
|
||||||
|
|
||||||
// Generate the INSERT query
|
// Generate the INSERT query
|
||||||
FormulateSetupQuery($tableName, $dataTypes, $columns, $insertQuery, $strsize);
|
FormulateSetupQuery($tableName, $dataTypes, $columns, $insertQuery);
|
||||||
|
|
||||||
$stmt = AE\createTable($conn, $tableName, $columns);
|
$stmt = AE\createTable($conn, $tableName, $columns);
|
||||||
if (!$stmt) {
|
if (!$stmt) {
|
||||||
|
@ -185,159 +186,7 @@ for ($i=0; $i < sizeof($columnEncryption); ++$i) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now test the good credentials, where ($i, $j, $k, $m) == (0, 0, 0, 0)
|
echo "Done.\n";
|
||||||
// and ($i, $j, $k, $m) == (0, 1, 1, 1)
|
|
||||||
$connectionOptions = array("CharacterSet"=>"UTF-8",
|
|
||||||
"database"=>$databaseName,
|
|
||||||
"uid"=>$uid,
|
|
||||||
"pwd"=>$pwd,
|
|
||||||
"ConnectionPooling"=>0);
|
|
||||||
|
|
||||||
$connectionOptions['ColumnEncryption'] = $columnEncryption[0];
|
|
||||||
$connectionOptions['KeyStoreAuthentication'] = $keyStoreAuthentication[0];
|
|
||||||
$connectionOptions['KeyStorePrincipalId'] = $keyStorePrincipalId[0];
|
|
||||||
$connectionOptions['KeyStoreSecret'] = $keyStoreSecret[0];
|
|
||||||
|
|
||||||
// Connect to the AE-enabled database
|
|
||||||
$conn = sqlsrv_connect($server, $connectionOptions);
|
|
||||||
if (!$conn) {
|
|
||||||
$errors = sqlsrv_errors();
|
|
||||||
fatalError("Connection failed while testing good credentials.\n");
|
|
||||||
} else {
|
|
||||||
$tableName = "type_conversion_table";
|
|
||||||
|
|
||||||
$columns = array();
|
|
||||||
$insertQuery = "";
|
|
||||||
|
|
||||||
// Generate the INSERT query
|
|
||||||
FormulateSetupQuery($tableName, $dataTypes, $columns, $insertQuery, $strsize);
|
|
||||||
|
|
||||||
$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();
|
|
||||||
for ($n=0; $n<sizeof($small_values); ++$n) {
|
|
||||||
$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 should not fail since our credentials are correct
|
|
||||||
if (sqlsrv_execute($stmt) == false) {
|
|
||||||
$errors = sqlsrv_errors();
|
|
||||||
fatalError("INSERT query failed with good credentials.\n");
|
|
||||||
} else {
|
|
||||||
echo "Successful insertion with username/password.\n";
|
|
||||||
|
|
||||||
// Now get the data back and display it
|
|
||||||
$selectQuery = "SELECT * FROM $tableName";
|
|
||||||
|
|
||||||
$stmt1 = sqlsrv_query($conn, $selectQuery);
|
|
||||||
$data = sqlsrv_fetch_array($stmt1, SQLSRV_FETCH_NUMERIC);
|
|
||||||
|
|
||||||
if (sizeof($data) != 2*sizeof($dataTypes)) {
|
|
||||||
fatalError("Incorrect number of fields returned.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
for ($n=0; $n<sizeof($data); $n+=2) {
|
|
||||||
if ($data[$n] != $data[$n+1]) {
|
|
||||||
echo "Failed on field $n: ".$data[$n]." ".$data[$n+1]."\n";
|
|
||||||
fatalError("AE and non-AE values do not match.\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sqlsrv_free_stmt($stmt);
|
|
||||||
sqlsrv_free_stmt($stmt1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Free the statement and close the connection
|
|
||||||
sqlsrv_close($conn);
|
|
||||||
}
|
|
||||||
|
|
||||||
$connectionOptions['ColumnEncryption'] = $columnEncryption[0];
|
|
||||||
$connectionOptions['KeyStoreAuthentication'] = $keyStoreAuthentication[1];
|
|
||||||
$connectionOptions['KeyStorePrincipalId'] = $keyStorePrincipalId[1];
|
|
||||||
$connectionOptions['KeyStoreSecret'] = $keyStoreSecret[1];
|
|
||||||
|
|
||||||
// Connect to the AE-enabled database
|
|
||||||
$conn = sqlsrv_connect($server, $connectionOptions);
|
|
||||||
if (!$conn) {
|
|
||||||
$errors = sqlsrv_errors();
|
|
||||||
fatalError("Connection failed while testing good credentials.\n");
|
|
||||||
} else {
|
|
||||||
$tableName = "type_conversion_table";
|
|
||||||
|
|
||||||
$columns = array();
|
|
||||||
$insertQuery = "";
|
|
||||||
|
|
||||||
// Generate the INSERT query
|
|
||||||
FormulateSetupQuery($tableName, $dataTypes, $columns, $insertQuery, $strsize);
|
|
||||||
|
|
||||||
$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();
|
|
||||||
for ($n=0; $n<sizeof($small_values); ++$n) {
|
|
||||||
$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 should not fail since our credentials are correct
|
|
||||||
if (sqlsrv_execute($stmt) == false) {
|
|
||||||
$errors = sqlsrv_errors();
|
|
||||||
fatalError("INSERT query execution failed with good credentials.\n");
|
|
||||||
} else {
|
|
||||||
echo "Successful insertion with client ID/secret.\n";
|
|
||||||
|
|
||||||
// Now get the data back and display it
|
|
||||||
$selectQuery = "SELECT * FROM $tableName";
|
|
||||||
|
|
||||||
$stmt1 = sqlsrv_query($conn, $selectQuery);
|
|
||||||
$data = sqlsrv_fetch_array($stmt1, SQLSRV_FETCH_NUMERIC);
|
|
||||||
|
|
||||||
if (sizeof($data) != 2*sizeof($dataTypes)) {
|
|
||||||
fatalError("Incorrect number of fields returned.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
for ($n=0; $n<sizeof($data); $n+=2) {
|
|
||||||
if ($data[$n] != $data[$n+1]) {
|
|
||||||
echo "Failed on field $n: ".$data[$n]." ".$data[$n+1]."\n";
|
|
||||||
fatalError("AE and non-AE values do not match.\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sqlsrv_free_stmt($stmt);
|
|
||||||
sqlsrv_free_stmt($stmt1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Free the statement and close the connection
|
|
||||||
sqlsrv_close($conn);
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
?>
|
||||||
--EXPECT--
|
--EXPECT--
|
||||||
Successful insertion with username/password.
|
Done.
|
||||||
Successful insertion with clinet ID/secret.
|
|
||||||
|
|
|
@ -0,0 +1,196 @@
|
||||||
|
--TEST--
|
||||||
|
Test connection keywords nad credentials for Azure Key Vault for Always Encrypted.
|
||||||
|
--SKIPIF--
|
||||||
|
<?php require('skipif.inc'); ?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
require_once('MsCommon.inc');
|
||||||
|
require_once('tools.inc');
|
||||||
|
require_once('values.php');
|
||||||
|
|
||||||
|
// Set up the columns and build the insert query. Each data type has an
|
||||||
|
// AE-encrypted and a non-encrypted column side by side in the table.
|
||||||
|
function FormulateSetupQuery($tableName, &$dataTypes, &$columns, &$insertQuery)
|
||||||
|
{
|
||||||
|
$columns = array();
|
||||||
|
$queryTypes = "(";
|
||||||
|
$queryTypesAE = "(";
|
||||||
|
$valuesString = "VALUES (";
|
||||||
|
$numTypes = sizeof($dataTypes);
|
||||||
|
|
||||||
|
for ($i = 0; $i < $numTypes; ++$i) {
|
||||||
|
// Replace parentheses for column names
|
||||||
|
$colname = str_replace(array("(", ",", ")"), array("_", "_", ""), $dataTypes[$i]);
|
||||||
|
$columns[] = new AE\ColumnMeta($dataTypes[$i], "c_".$colname."_AE");
|
||||||
|
$columns[] = new AE\ColumnMeta($dataTypes[$i], "c_".$colname, null, true, true);
|
||||||
|
$queryTypes .= "c_"."$colname, ";
|
||||||
|
$queryTypes .= "c_"."$colname"."_AE, ";
|
||||||
|
$valuesString .= "?, ?, ";
|
||||||
|
}
|
||||||
|
|
||||||
|
$queryTypes = substr($queryTypes, 0, -2).")";
|
||||||
|
$valuesString = substr($valuesString, 0, -2).")";
|
||||||
|
|
||||||
|
$insertQuery = "INSERT INTO $tableName ".$queryTypes." ".$valuesString;
|
||||||
|
}
|
||||||
|
|
||||||
|
$strsize = 64;
|
||||||
|
|
||||||
|
$dataTypes = array ("char($strsize)", "varchar($strsize)", "nvarchar($strsize)",
|
||||||
|
"decimal", "float", "real", "bigint", "int", "bit"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Test data insertion and retrieval with username/password
|
||||||
|
// and client Id/client secret combinations.
|
||||||
|
$connectionOptions = array("CharacterSet"=>"UTF-8",
|
||||||
|
"database"=>$databaseName,
|
||||||
|
"uid"=>$uid,
|
||||||
|
"pwd"=>$pwd,
|
||||||
|
"ConnectionPooling"=>0);
|
||||||
|
|
||||||
|
$connectionOptions['ColumnEncryption'] = "enabled";
|
||||||
|
$connectionOptions['KeyStoreAuthentication'] = "KeyVaultPassword";
|
||||||
|
$connectionOptions['KeyStorePrincipalId'] = $AKVPrincipalName;
|
||||||
|
$connectionOptions['KeyStoreSecret'] = $AKVPassword;
|
||||||
|
|
||||||
|
$tableName = "akv_comparison_table";
|
||||||
|
|
||||||
|
// Connect to the AE-enabled database
|
||||||
|
$conn = sqlsrv_connect($server, $connectionOptions);
|
||||||
|
if (!$conn) {
|
||||||
|
$errors = sqlsrv_errors();
|
||||||
|
fatalError("Connection failed while testing good credentials.\n");
|
||||||
|
} else {
|
||||||
|
$columns = array();
|
||||||
|
$insertQuery = "";
|
||||||
|
|
||||||
|
// Generate the INSERT query
|
||||||
|
FormulateSetupQuery($tableName, $dataTypes, $columns, $insertQuery);
|
||||||
|
|
||||||
|
$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();
|
||||||
|
for ($n=0; $n<sizeof($small_values); ++$n) {
|
||||||
|
$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 should not fail since our credentials are correct
|
||||||
|
if (sqlsrv_execute($stmt) == false) {
|
||||||
|
$errors = sqlsrv_errors();
|
||||||
|
fatalError("INSERT query failed with good credentials.\n");
|
||||||
|
} else {
|
||||||
|
// Get the data back and compare the encrypted and non-encrypted versions
|
||||||
|
$selectQuery = "SELECT * FROM $tableName";
|
||||||
|
|
||||||
|
$stmt1 = sqlsrv_query($conn, $selectQuery);
|
||||||
|
$data = sqlsrv_fetch_array($stmt1, SQLSRV_FETCH_NUMERIC);
|
||||||
|
|
||||||
|
if (sizeof($data) != 2*sizeof($dataTypes)) {
|
||||||
|
fatalError("Incorrect number of fields returned.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
for ($n=0; $n<sizeof($data); $n+=2) {
|
||||||
|
if ($data[$n] != $data[$n+1]) {
|
||||||
|
echo "Failed on field $n: ".$data[$n]." ".$data[$n+1]."\n";
|
||||||
|
fatalError("AE and non-AE values do not match.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "Successful insertion and retrieval with username/password.\n";
|
||||||
|
|
||||||
|
sqlsrv_free_stmt($stmt);
|
||||||
|
sqlsrv_free_stmt($stmt1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Free the statement and close the connection
|
||||||
|
sqlsrv_close($conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
$connectionOptions['ColumnEncryption'] = "enabled";
|
||||||
|
$connectionOptions['KeyStoreAuthentication'] = "KeyVaultClientSecret";
|
||||||
|
$connectionOptions['KeyStorePrincipalId'] = $AKVClientID;
|
||||||
|
$connectionOptions['KeyStoreSecret'] = $AKVSecret;
|
||||||
|
|
||||||
|
// Connect to the AE-enabled database
|
||||||
|
$conn = sqlsrv_connect($server, $connectionOptions);
|
||||||
|
if (!$conn) {
|
||||||
|
$errors = sqlsrv_errors();
|
||||||
|
fatalError("Connection failed while testing good credentials.\n");
|
||||||
|
} else {
|
||||||
|
$columns = array();
|
||||||
|
$insertQuery = "";
|
||||||
|
|
||||||
|
// Generate the INSERT query
|
||||||
|
FormulateSetupQuery($tableName, $dataTypes, $columns, $insertQuery);
|
||||||
|
|
||||||
|
$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();
|
||||||
|
for ($n=0; $n<sizeof($small_values); ++$n) {
|
||||||
|
$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 should not fail since our credentials are correct
|
||||||
|
if (sqlsrv_execute($stmt) == false) {
|
||||||
|
$errors = sqlsrv_errors();
|
||||||
|
fatalError("INSERT query execution failed with good credentials.\n");
|
||||||
|
} else {
|
||||||
|
// Get the data back and compare the encrypted and non-encrypted versions
|
||||||
|
$selectQuery = "SELECT * FROM $tableName";
|
||||||
|
|
||||||
|
$stmt1 = sqlsrv_query($conn, $selectQuery);
|
||||||
|
$data = sqlsrv_fetch_array($stmt1, SQLSRV_FETCH_NUMERIC);
|
||||||
|
|
||||||
|
if (sizeof($data) != 2*sizeof($dataTypes)) {
|
||||||
|
fatalError("Incorrect number of fields returned.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
for ($n=0; $n<sizeof($data); $n+=2) {
|
||||||
|
if ($data[$n] != $data[$n+1]) {
|
||||||
|
echo "Failed on field $n: ".$data[$n]." ".$data[$n+1]."\n";
|
||||||
|
fatalError("AE and non-AE values do not match.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "Successful insertion and retrieval with client ID/secret.\n";
|
||||||
|
|
||||||
|
sqlsrv_free_stmt($stmt);
|
||||||
|
sqlsrv_free_stmt($stmt1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Free the statement and close the connection
|
||||||
|
sqlsrv_close($conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
||||||
|
Successful insertion and retrieval with username/password.
|
||||||
|
Successful insertion and retrieval with client ID/secret.
|
Loading…
Reference in a new issue