Skip to content

Commit 32058ed

Browse files
committed
Test spec tests against GCP/Azure
1 parent cc836ea commit 32058ed

File tree

1 file changed

+131
-7
lines changed

1 file changed

+131
-7
lines changed

tests/SpecTests/ClientSideEncryptionSpecTest.php

Lines changed: 131 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,8 @@ public function testDataKeyAndDoubleEncryption(string $providerName, $masterKey)
178178
'keyVaultNamespace' => 'keyvault.datakeys',
179179
'kmsProviders' => [
180180
'aws' => Context::getAWSCredentials(),
181+
'azure' => Context::getAzureCredentials(),
182+
'gcp' => Context::getGCPCredentials(),
181183
'local' => ['key' => new Binary(base64_decode(self::LOCAL_MASTERKEY), 0)],
182184
],
183185
];
@@ -268,6 +270,22 @@ public static function dataKeyProvider()
268270
'key' => 'arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0',
269271
],
270272
],
273+
'azure' => [
274+
'providerName' => 'azure',
275+
'masterKey' => [
276+
'keyVaultEndpoint' => 'key-vault-csfle.vault.azure.net',
277+
'keyName' => 'key-name-csfle',
278+
],
279+
],
280+
'gcp' => [
281+
'providerName' => 'gcp',
282+
'masterKey' => [
283+
'projectId' => 'devprod-drivers',
284+
'location' => 'global',
285+
'keyRing' => 'key-ring-csfle',
286+
'keyName' => 'key-name-csfle',
287+
],
288+
],
271289
];
272290
}
273291

@@ -505,12 +523,16 @@ public function testCorpus($schemaMap = true)
505523
$client->selectCollection('keyvault', 'datakeys')->insertMany([
506524
$this->decodeJson(file_get_contents(__DIR__ . '/client-side-encryption/corpus/corpus-key-local.json')),
507525
$this->decodeJson(file_get_contents(__DIR__ . '/client-side-encryption/corpus/corpus-key-aws.json')),
526+
$this->decodeJson(file_get_contents(__DIR__ . '/client-side-encryption/corpus/corpus-key-azure.json')),
527+
$this->decodeJson(file_get_contents(__DIR__ . '/client-side-encryption/corpus/corpus-key-gcp.json')),
508528
]);
509529

510530
$encryptionOpts = [
511531
'keyVaultNamespace' => 'keyvault.datakeys',
512532
'kmsProviders' => [
513533
'aws' => Context::getAWSCredentials(),
534+
'azure' => Context::getAzureCredentials(),
535+
'gcp' => Context::getGCPCredentials(),
514536
'local' => ['key' => new Binary(base64_decode(self::LOCAL_MASTERKEY), 0)],
515537
],
516538
];
@@ -535,19 +557,55 @@ public function testCorpus($schemaMap = true)
535557
switch ($fieldName) {
536558
case '_id':
537559
case 'altname_aws':
560+
case 'altname_azure':
561+
case 'altname_gcp':
538562
case 'altname_local':
539563
$corpusCopied[$fieldName] = $data;
540564
break;
541565

542566
default:
543-
$corpusCopied[$fieldName] = $this->prepareCorpusData($data, $clientEncryption);
567+
$corpusCopied[$fieldName] = $this->prepareCorpusData($fieldName, $data, $clientEncryption);
544568
}
545569
}
546570

547571
$collection->insertOne($corpusCopied);
548572
$corpusDecrypted = $collection->findOne(['_id' => 'client_side_encryption_corpus']);
549573

550574
$this->assertDocumentsMatch($corpus, $corpusDecrypted);
575+
576+
$corpusEncryptedExpected = (array) $this->decodeJson(file_get_contents(__DIR__ . '/client-side-encryption/corpus/corpus-encrypted.json'));
577+
$corpusEncryptedActual = $client->selectCollection('db', 'coll')->findOne(['_id' => 'client_side_encryption_corpus'], ['typeMap' => ['root' => 'array', 'document' => stdClass::class, 'array' => 'array']]);
578+
579+
foreach ($corpusEncryptedExpected as $fieldName => $expectedData) {
580+
switch ($fieldName) {
581+
case '_id':
582+
case 'altname_aws':
583+
case 'altname_azure':
584+
case 'altname_gcp':
585+
case 'altname_local':
586+
continue 2;
587+
}
588+
589+
$actualData = $corpusEncryptedActual[$fieldName];
590+
591+
if ($expectedData->algo === 'det') {
592+
$this->assertEquals($expectedData->value, $actualData->value, 'Value for field ' . $fieldName . ' does not match expected value.');
593+
}
594+
595+
if ($expectedData->allowed) {
596+
if ($expectedData->algo === 'rand') {
597+
$this->assertNotEquals($expectedData->value, $actualData->value, 'Value for field ' . $fieldName . ' does not differ from expected value.');
598+
}
599+
600+
$this->assertEquals(
601+
$clientEncryption->decrypt($expectedData->value),
602+
$clientEncryption->decrypt($actualData->value),
603+
'Decrypted value for field ' . $fieldName . ' does not match.'
604+
);
605+
} else {
606+
$this->assertEquals($corpus[$fieldName]->value, $actualData->value, 'Value for field ' . $fieldName . ' does not match original value.');
607+
}
608+
}
551609
}
552610

553611
/**
@@ -582,6 +640,14 @@ public function testCustomEndpoint(Closure $test)
582640
public static function customEndpointProvider()
583641
{
584642
$awsMasterKey = ['region' => 'us-east-1', 'key' => 'arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0'];
643+
$azureMasterKey = ['keyVaultEndpoint' => 'key-vault-csfle.vault.azure.net', 'keyName' => 'key-name-csfle'];
644+
$gcpMasterKey = [
645+
'projectId' => 'devprod-drivers',
646+
'location' => 'global',
647+
'keyRing' => 'key-ring-csfle',
648+
'keyName' => 'key-name-csfle',
649+
'endpoint' => 'cloudkms.googleapis.com:443',
650+
];
585651

586652
return [
587653
'Test 1' => [
@@ -625,6 +691,38 @@ static function (self $test, ClientEncryption $clientEncryption, ClientEncryptio
625691
$clientEncryption->createDataKey('aws', ['masterKey' => $awsMasterKey + ['endpoint' => 'example.com']]);
626692
},
627693
],
694+
'Test 7' => [
695+
static function (self $test, ClientEncryption $clientEncryption, ClientEncryption $clientEncryptionInvalid) use ($azureMasterKey) {
696+
$keyId = $clientEncryption->createDataKey('azure', ['masterKey' => $azureMasterKey]);
697+
$encrypted = $clientEncryption->encrypt('test', ['algorithm' => ClientEncryption::AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC, 'keyId' => $keyId]);
698+
$test->assertSame('test', $clientEncryption->decrypt($encrypted));
699+
700+
$test->expectException(RuntimeException::class);
701+
$test->expectExceptionMessageMatches('#parse error#');
702+
$clientEncryptionInvalid->createDataKey('azure', ['masterKey' => $azureMasterKey]);
703+
},
704+
],
705+
'Test 8' => [
706+
static function (self $test, ClientEncryption $clientEncryption, ClientEncryption $clientEncryptionInvalid) use ($gcpMasterKey) {
707+
$keyId = $clientEncryption->createDataKey('gcp', ['masterKey' => $gcpMasterKey]);
708+
$encrypted = $clientEncryption->encrypt('test', ['algorithm' => ClientEncryption::AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC, 'keyId' => $keyId]);
709+
$test->assertSame('test', $clientEncryption->decrypt($encrypted));
710+
711+
$test->expectException(RuntimeException::class);
712+
$test->expectExceptionMessageMatches('#parse error#');
713+
$clientEncryptionInvalid->createDataKey('gcp', ['masterKey' => $gcpMasterKey]);
714+
},
715+
],
716+
'Test 9' => [
717+
static function (self $test, ClientEncryption $clientEncryption, ClientEncryption $clientEncryptionInvalid) use ($gcpMasterKey) {
718+
$masterKey = $gcpMasterKey;
719+
$masterKey['endpoint'] = 'example.com:443';
720+
721+
$test->expectException(RuntimeException::class);
722+
$test->expectExceptionMessageMatches('#Invalid KMS response#');
723+
$clientEncryption->createDataKey('gcp', ['masterKey' => $masterKey]);
724+
},
725+
],
628726
];
629727
}
630728

@@ -719,28 +817,54 @@ private function createTestCollection($jsonSchema)
719817
$operation->execute($this->getPrimaryServer());
720818
}
721819

722-
private function encryptCorpusValue(stdClass $data, ClientEncryption $clientEncryption)
820+
private function encryptCorpusValue(string $fieldName, stdClass $data, ClientEncryption $clientEncryption)
723821
{
724822
$encryptionOptions = [
725823
'algorithm' => $data->algo === 'rand' ? ClientEncryption::AEAD_AES_256_CBC_HMAC_SHA_512_RANDOM : ClientEncryption::AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC,
726824
];
727825

826+
switch ($data->kms) {
827+
case 'local':
828+
$keyId = 'LOCALAAAAAAAAAAAAAAAAA==';
829+
$keyAltName = 'local';
830+
break;
831+
case 'aws':
832+
$keyId = 'AWSAAAAAAAAAAAAAAAAAAA==';
833+
$keyAltName = 'aws';
834+
break;
835+
case 'azure':
836+
$keyId = 'AZUREAAAAAAAAAAAAAAAAA==';
837+
$keyAltName = 'azure';
838+
break;
839+
case 'gcp':
840+
$keyId = 'GCPAAAAAAAAAAAAAAAAAAA==';
841+
$keyAltName = 'gcp';
842+
break;
843+
844+
default:
845+
throw new UnexpectedValueException('Unexpected KMS "%s"', $data->kms);
846+
}
847+
728848
switch ($data->identifier) {
729849
case 'id':
730-
$keyId = $data->kms === 'local' ? 'LOCALAAAAAAAAAAAAAAAAA==' : 'AWSAAAAAAAAAAAAAAAAAAA==';
731850
$encryptionOptions['keyId'] = new Binary(base64_decode($keyId), 4);
732851
break;
733852

734853
case 'altname':
735-
$encryptionOptions['keyAltName'] = $data->kms === 'local' ? 'local' : 'aws';
854+
$encryptionOptions['keyAltName'] = $keyAltName;
736855
break;
737856

738857
default:
739858
throw new UnexpectedValueException('Unexpected value "%s" for identifier', $data->identifier);
740859
}
741860

742861
if ($data->allowed) {
743-
$encrypted = $clientEncryption->encrypt($this->craftInt64($data), $encryptionOptions);
862+
try {
863+
$encrypted = $clientEncryption->encrypt($this->craftInt64($data), $encryptionOptions);
864+
} catch (EncryptionException $e) {
865+
$this->fail('Could not encrypt value for field ' . $fieldName . ': ' . $e->getMessage());
866+
}
867+
744868
$this->assertEquals($data->value, $clientEncryption->decrypt($encrypted));
745869

746870
return $encrypted;
@@ -769,7 +893,7 @@ private function insertKeyVaultData(array $keyVaultData = null)
769893
return;
770894
}
771895

772-
private function prepareCorpusData(stdClass $data, ClientEncryption $clientEncryption)
896+
private function prepareCorpusData(string $fieldName, stdClass $data, ClientEncryption $clientEncryption)
773897
{
774898
if ($data->method === 'auto') {
775899
$data->value = $this->craftInt64($data);
@@ -778,7 +902,7 @@ private function prepareCorpusData(stdClass $data, ClientEncryption $clientEncry
778902
}
779903

780904
$returnData = clone $data;
781-
$returnData->value = $this->encryptCorpusValue($data, $clientEncryption);
905+
$returnData->value = $this->encryptCorpusValue($fieldName, $data, $clientEncryption);
782906

783907
return $data->allowed ? $returnData : $data;
784908
}

0 commit comments

Comments
 (0)