Skip to content

Commit dc33a61

Browse files
committed
PYTHON-1941 Implement prose test for data key and double encryption
1 parent 0a1d777 commit dc33a61

File tree

1 file changed

+100
-0
lines changed

1 file changed

+100
-0
lines changed

test/test_encryption.py

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,106 @@ def create_key_vault(vault, *data_keys):
446446
return vault
447447

448448

449+
class TestDataKeyDoubleEncryption(EncryptionIntegrationTest):
450+
451+
@classmethod
452+
@unittest.skipUnless(all(AWS_CREDS.values()),
453+
'AWS environment credentials are not set')
454+
def setUpClass(cls):
455+
super(TestDataKeyDoubleEncryption, cls).setUpClass()
456+
457+
@staticmethod
458+
def kms_providers():
459+
return {'aws': AWS_CREDS, 'local': {'key': LOCAL_MASTER_KEY}}
460+
461+
def test_data_key(self):
462+
self.client.db.coll.drop()
463+
vault = create_key_vault(self.client.admin.datakeys)
464+
self.addCleanup(vault.drop)
465+
466+
# Configure the encrypted field via the local schema_map option.
467+
schemas = {
468+
"db.coll": {
469+
"bsonType": "object",
470+
"properties": {
471+
"encrypted_placeholder": {
472+
"encrypt": {
473+
"keyId": "/placeholder",
474+
"bsonType": "string",
475+
"algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random"
476+
}
477+
}
478+
}
479+
}
480+
}
481+
opts = AutoEncryptionOpts(
482+
self.kms_providers(), 'admin.datakeys', schema_map=schemas)
483+
client_encrypted = rs_or_single_client(
484+
auto_encryption_opts=opts, uuidRepresentation='standard')
485+
self.addCleanup(client_encrypted.close)
486+
487+
client_encryption = ClientEncryption(
488+
self.kms_providers(), 'admin.datakeys', client_context.client)
489+
self.addCleanup(client_encryption.close)
490+
491+
# Local create data key.
492+
local_datakey_id = client_encryption.create_data_key(
493+
'local', key_alt_names=['local_altname'])
494+
self.assertIsInstance(local_datakey_id, uuid.UUID)
495+
docs = list(vault.find({'_id': local_datakey_id}))
496+
self.assertEqual(len(docs), 1)
497+
self.assertEqual(docs[0]['masterKey']['provider'], 'local')
498+
499+
# Local encrypt by key_id.
500+
local_encrypted = client_encryption.encrypt(
501+
'hello local', Algorithm.Deterministic, key_id=local_datakey_id)
502+
self.assertEncrypted(local_encrypted)
503+
client_encrypted.db.coll.insert_one(
504+
{'_id': 'local', 'value': local_encrypted})
505+
doc_decrypted = client_encrypted.db.coll.find_one({'_id': 'local'})
506+
self.assertEqual(doc_decrypted['value'], 'hello local')
507+
508+
# Local encrypt by key_alt_name.
509+
local_encrypted_altname = client_encryption.encrypt(
510+
'hello local', Algorithm.Deterministic,
511+
key_alt_name='local_altname')
512+
self.assertEqual(local_encrypted_altname, local_encrypted)
513+
514+
# AWS create data key.
515+
master_key = {
516+
'region': 'us-east-1',
517+
'key': 'arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-'
518+
'9f25-e30687b580d0'
519+
}
520+
aws_datakey_id = client_encryption.create_data_key(
521+
'aws', master_key=master_key, key_alt_names=['aws_altname'])
522+
self.assertIsInstance(aws_datakey_id, uuid.UUID)
523+
docs = list(vault.find({'_id': aws_datakey_id}))
524+
self.assertEqual(len(docs), 1)
525+
self.assertEqual(docs[0]['masterKey']['provider'], 'aws')
526+
527+
# AWS encrypt by key_id.
528+
aws_encrypted = client_encryption.encrypt(
529+
'hello aws', Algorithm.Deterministic, key_id=aws_datakey_id)
530+
self.assertEncrypted(aws_encrypted)
531+
client_encrypted.db.coll.insert_one(
532+
{'_id': 'aws', 'value': aws_encrypted})
533+
doc_decrypted = client_encrypted.db.coll.find_one({'_id': 'aws'})
534+
self.assertEqual(doc_decrypted['value'], 'hello aws')
535+
536+
# AWS encrypt by key_alt_name.
537+
aws_encrypted_altname = client_encryption.encrypt(
538+
'hello aws', Algorithm.Deterministic, key_alt_name='aws_altname')
539+
self.assertEqual(aws_encrypted_altname, aws_encrypted)
540+
541+
# Explicitly encrypting an auto encrypted field.
542+
msg = ('Cannot encrypt element of type binData because schema '
543+
'requires that type is one of: \[ string \]')
544+
with self.assertRaisesRegex(EncryptionError, msg):
545+
client_encrypted.db.coll.insert_one(
546+
{'encrypted_placeholder': local_encrypted})
547+
548+
449549
class TestExternalKeyVault(EncryptionIntegrationTest):
450550

451551
@staticmethod

0 commit comments

Comments
 (0)