From eff4d6e4416c44e3ebd7587b1f1b1856cab574eb Mon Sep 17 00:00:00 2001 From: Abraham Egnor Date: Wed, 26 Oct 2022 12:08:31 -0400 Subject: [PATCH 01/10] pull in tests, move testdata --- src/test/csfle.rs | 2 +- .../json/client-side-encryption/README.rst | 2381 +++++++++++++++++ .../legacy/aggregate.json | 390 +++ .../legacy/aggregate.yml | 120 + .../legacy/awsTemporary.json | 225 ++ .../legacy/awsTemporary.yml | 57 + .../legacy/azureKMS.json | 224 ++ .../legacy/azureKMS.yml | 46 + .../legacy/badQueries.json | 1446 ++++++++++ .../legacy/badQueries.yml | 536 ++++ .../legacy/badSchema.json | 254 ++ .../legacy/badSchema.yml | 73 + .../client-side-encryption/legacy/basic.json | 350 +++ .../client-side-encryption/legacy/basic.yml | 102 + .../client-side-encryption/legacy/bulk.json | 333 +++ .../client-side-encryption/legacy/bulk.yml | 78 + .../legacy/bypassAutoEncryption.json | 402 +++ .../legacy/bypassAutoEncryption.yml | 100 + .../legacy/bypassedCommand.json | 106 + .../legacy/bypassedCommand.yml | 42 + .../client-side-encryption/legacy/count.json | 229 ++ .../client-side-encryption/legacy/count.yml | 54 + .../legacy/countDocuments.json | 241 ++ .../legacy/countDocuments.yml | 52 + .../legacy/create-and-createIndexes.json | 115 + .../legacy/create-and-createIndexes.yml | 58 + .../client-side-encryption/legacy/delete.json | 340 +++ .../client-side-encryption/legacy/delete.yml | 91 + .../legacy/distinct.json | 276 ++ .../legacy/distinct.yml | 66 + .../legacy/explain.json | 239 ++ .../client-side-encryption/legacy/explain.yml | 57 + .../client-side-encryption/legacy/find.json | 408 +++ .../client-side-encryption/legacy/find.yml | 105 + .../legacy/findOneAndDelete.json | 221 ++ .../legacy/findOneAndDelete.yml | 50 + .../legacy/findOneAndReplace.json | 227 ++ .../legacy/findOneAndReplace.yml | 50 + .../legacy/findOneAndUpdate.json | 231 ++ .../legacy/findOneAndUpdate.yml | 50 + .../legacy/fle2-BypassQueryAnalysis.json | 290 ++ .../legacy/fle2-BypassQueryAnalysis.yml | 101 + .../legacy/fle2-Compact.json | 233 ++ .../legacy/fle2-Compact.yml | 80 + .../legacy/fle2-CreateCollection.json | 2240 ++++++++++++++++ .../legacy/fle2-CreateCollection.yml | 1263 +++++++++ .../legacy/fle2-DecryptExistingData.json | 149 ++ .../legacy/fle2-DecryptExistingData.yml | 64 + .../legacy/fle2-Delete.json | 306 +++ .../legacy/fle2-Delete.yml | 107 + ...EncryptedFields-vs-EncryptedFieldsMap.json | 218 ++ ...-EncryptedFields-vs-EncryptedFieldsMap.yml | 80 + .../fle2-EncryptedFields-vs-jsonSchema.json | 305 +++ .../fle2-EncryptedFields-vs-jsonSchema.yml | 90 + .../fle2-EncryptedFieldsMap-defaults.json | 106 + .../fle2-EncryptedFieldsMap-defaults.yml | 57 + .../legacy/fle2-FindOneAndUpdate.json | 603 +++++ .../legacy/fle2-FindOneAndUpdate.yml | 213 ++ .../legacy/fle2-InsertFind-Indexed.json | 301 +++ .../legacy/fle2-InsertFind-Indexed.yml | 86 + .../legacy/fle2-InsertFind-Unindexed.json | 251 ++ .../legacy/fle2-InsertFind-Unindexed.yml | 87 + .../legacy/fle2-MissingKey.json | 119 + .../legacy/fle2-MissingKey.yml | 41 + .../legacy/fle2-NoEncryption.json | 87 + .../legacy/fle2-NoEncryption.yml | 42 + .../legacy/fle2-Update.json | 611 +++++ .../legacy/fle2-Update.yml | 221 ++ ...e2-validatorAndPartialFieldExpression.json | 521 ++++ ...le2-validatorAndPartialFieldExpression.yml | 168 ++ .../client-side-encryption/legacy/gcpKMS.json | 226 ++ .../client-side-encryption/legacy/gcpKMS.yml | 46 + .../legacy/getMore.json | 263 ++ .../client-side-encryption/legacy/getMore.yml | 61 + .../client-side-encryption/legacy/insert.json | 344 +++ .../client-side-encryption/legacy/insert.yml | 88 + .../legacy/keyAltName.json | 228 ++ .../legacy/keyAltName.yml | 64 + .../legacy/kmipKMS.json | 223 ++ .../client-side-encryption/legacy/kmipKMS.yml | 46 + .../legacy/localKMS.json | 191 ++ .../legacy/localKMS.yml | 47 + .../legacy/localSchema.json | 258 ++ .../legacy/localSchema.yml | 65 + .../legacy/malformedCiphertext.json | 321 +++ .../legacy/malformedCiphertext.yml | 69 + .../legacy/maxWireVersion.json | 74 + .../legacy/maxWireVersion.yml | 22 + .../legacy/missingKey.json | 179 ++ .../legacy/missingKey.yml | 42 + .../legacy/noSchema.json | 67 + .../legacy/noSchema.yml | 37 + .../legacy/replaceOne.json | 239 ++ .../legacy/replaceOne.yml | 54 + .../legacy/timeoutMS.json | 200 ++ .../legacy/timeoutMS.yml | 65 + .../client-side-encryption/legacy/types.json | 1646 ++++++++++++ .../client-side-encryption/legacy/types.yml | 501 ++++ .../legacy/unsupportedCommand.json | 152 ++ .../legacy/unsupportedCommand.yml | 25 + .../legacy/updateMany.json | 307 +++ .../legacy/updateMany.yml | 70 + .../legacy/updateOne.json | 465 ++++ .../legacy/updateOne.yml | 160 ++ .../validatorAndPartialFieldExpression.json | 642 +++++ .../validatorAndPartialFieldExpression.yml | 166 ++ .../testdata/encryptedFields.json | 33 - .../testdata/key1-document.json | 30 - .../unified/addKeyAltName.json | 609 +++++ .../unified/addKeyAltName.yml | 194 ++ .../createDataKey-kms_providers-invalid.json | 119 + .../createDataKey-kms_providers-invalid.yml | 67 + .../unified/createDataKey.json | 711 +++++ .../unified/createDataKey.yml | 309 +++ .../unified/deleteKey.json | 557 ++++ .../unified/deleteKey.yml | 159 ++ .../unified/getKey.json | 319 +++ .../client-side-encryption/unified/getKey.yml | 105 + .../unified/getKeyByAltName.json | 289 ++ .../unified/getKeyByAltName.yml | 104 + .../unified/getKeys.json | 260 ++ .../unified/getKeys.yml | 122 + .../unified/removeKeyAltName.json | 672 +++++ .../unified/removeKeyAltName.yml | 157 ++ .../rewrapManyDataKey-decrypt_failure.json | 162 ++ .../rewrapManyDataKey-decrypt_failure.yml | 69 + .../rewrapManyDataKey-encrypt_failure.json | 250 ++ .../rewrapManyDataKey-encrypt_failure.yml | 122 + .../unified/rewrapManyDataKey.json | 1475 ++++++++++ .../unified/rewrapManyDataKey.yml | 432 +++ .../corpus/corpus-encrypted.json | 0 .../corpus/corpus-key-aws.json | 0 .../corpus/corpus-key-azure.json | 0 .../corpus/corpus-key-gcp.json | 0 .../corpus/corpus-key-kmip.json | 0 .../corpus/corpus-key-local.json | 0 .../corpus/corpus-schema.json | 0 .../corpus/corpus.json | 0 .../client-side-encryption}/external-key.json | 0 .../external-schema.json | 0 .../client-side-encryption}/limits-doc.json | 0 .../client-side-encryption}/limits-key.json | 0 .../limits-schema.json | 0 143 files changed, 34382 insertions(+), 64 deletions(-) create mode 100644 src/test/spec/json/client-side-encryption/README.rst create mode 100644 src/test/spec/json/client-side-encryption/legacy/aggregate.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/aggregate.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/awsTemporary.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/awsTemporary.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/azureKMS.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/azureKMS.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/badQueries.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/badQueries.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/badSchema.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/badSchema.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/basic.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/basic.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/bulk.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/bulk.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/bypassAutoEncryption.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/bypassAutoEncryption.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/bypassedCommand.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/bypassedCommand.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/count.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/count.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/countDocuments.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/countDocuments.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/create-and-createIndexes.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/create-and-createIndexes.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/delete.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/delete.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/distinct.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/distinct.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/explain.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/explain.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/find.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/find.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/findOneAndDelete.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/findOneAndDelete.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/findOneAndReplace.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/findOneAndReplace.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/findOneAndUpdate.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/findOneAndUpdate.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/fle2-BypassQueryAnalysis.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/fle2-BypassQueryAnalysis.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/fle2-Compact.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/fle2-Compact.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/fle2-CreateCollection.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/fle2-CreateCollection.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/fle2-DecryptExistingData.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/fle2-DecryptExistingData.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/fle2-Delete.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/fle2-Delete.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/fle2-EncryptedFields-vs-EncryptedFieldsMap.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/fle2-EncryptedFields-vs-EncryptedFieldsMap.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/fle2-EncryptedFields-vs-jsonSchema.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/fle2-EncryptedFields-vs-jsonSchema.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/fle2-EncryptedFieldsMap-defaults.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/fle2-EncryptedFieldsMap-defaults.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/fle2-FindOneAndUpdate.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/fle2-FindOneAndUpdate.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/fle2-InsertFind-Indexed.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/fle2-InsertFind-Indexed.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/fle2-InsertFind-Unindexed.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/fle2-InsertFind-Unindexed.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/fle2-MissingKey.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/fle2-MissingKey.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/fle2-NoEncryption.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/fle2-NoEncryption.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/fle2-Update.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/fle2-Update.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/fle2-validatorAndPartialFieldExpression.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/fle2-validatorAndPartialFieldExpression.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/gcpKMS.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/gcpKMS.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/getMore.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/getMore.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/insert.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/insert.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/keyAltName.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/keyAltName.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/kmipKMS.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/kmipKMS.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/localKMS.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/localKMS.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/localSchema.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/localSchema.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/malformedCiphertext.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/malformedCiphertext.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/maxWireVersion.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/maxWireVersion.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/missingKey.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/missingKey.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/noSchema.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/noSchema.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/replaceOne.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/replaceOne.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/timeoutMS.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/timeoutMS.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/types.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/types.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/unsupportedCommand.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/unsupportedCommand.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/updateMany.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/updateMany.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/updateOne.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/updateOne.yml create mode 100644 src/test/spec/json/client-side-encryption/legacy/validatorAndPartialFieldExpression.json create mode 100644 src/test/spec/json/client-side-encryption/legacy/validatorAndPartialFieldExpression.yml delete mode 100644 src/test/spec/json/client-side-encryption/testdata/encryptedFields.json delete mode 100644 src/test/spec/json/client-side-encryption/testdata/key1-document.json create mode 100644 src/test/spec/json/client-side-encryption/unified/addKeyAltName.json create mode 100644 src/test/spec/json/client-side-encryption/unified/addKeyAltName.yml create mode 100644 src/test/spec/json/client-side-encryption/unified/createDataKey-kms_providers-invalid.json create mode 100644 src/test/spec/json/client-side-encryption/unified/createDataKey-kms_providers-invalid.yml create mode 100644 src/test/spec/json/client-side-encryption/unified/createDataKey.json create mode 100644 src/test/spec/json/client-side-encryption/unified/createDataKey.yml create mode 100644 src/test/spec/json/client-side-encryption/unified/deleteKey.json create mode 100644 src/test/spec/json/client-side-encryption/unified/deleteKey.yml create mode 100644 src/test/spec/json/client-side-encryption/unified/getKey.json create mode 100644 src/test/spec/json/client-side-encryption/unified/getKey.yml create mode 100644 src/test/spec/json/client-side-encryption/unified/getKeyByAltName.json create mode 100644 src/test/spec/json/client-side-encryption/unified/getKeyByAltName.yml create mode 100644 src/test/spec/json/client-side-encryption/unified/getKeys.json create mode 100644 src/test/spec/json/client-side-encryption/unified/getKeys.yml create mode 100644 src/test/spec/json/client-side-encryption/unified/removeKeyAltName.json create mode 100644 src/test/spec/json/client-side-encryption/unified/removeKeyAltName.yml create mode 100644 src/test/spec/json/client-side-encryption/unified/rewrapManyDataKey-decrypt_failure.json create mode 100644 src/test/spec/json/client-side-encryption/unified/rewrapManyDataKey-decrypt_failure.yml create mode 100644 src/test/spec/json/client-side-encryption/unified/rewrapManyDataKey-encrypt_failure.json create mode 100644 src/test/spec/json/client-side-encryption/unified/rewrapManyDataKey-encrypt_failure.yml create mode 100644 src/test/spec/json/client-side-encryption/unified/rewrapManyDataKey.json create mode 100644 src/test/spec/json/client-side-encryption/unified/rewrapManyDataKey.yml rename src/test/spec/json/{client-side-encryption/testdata => testdata/client-side-encryption}/corpus/corpus-encrypted.json (100%) rename src/test/spec/json/{client-side-encryption/testdata => testdata/client-side-encryption}/corpus/corpus-key-aws.json (100%) rename src/test/spec/json/{client-side-encryption/testdata => testdata/client-side-encryption}/corpus/corpus-key-azure.json (100%) rename src/test/spec/json/{client-side-encryption/testdata => testdata/client-side-encryption}/corpus/corpus-key-gcp.json (100%) rename src/test/spec/json/{client-side-encryption/testdata => testdata/client-side-encryption}/corpus/corpus-key-kmip.json (100%) rename src/test/spec/json/{client-side-encryption/testdata => testdata/client-side-encryption}/corpus/corpus-key-local.json (100%) rename src/test/spec/json/{client-side-encryption/testdata => testdata/client-side-encryption}/corpus/corpus-schema.json (100%) rename src/test/spec/json/{client-side-encryption/testdata => testdata/client-side-encryption}/corpus/corpus.json (100%) rename src/test/spec/json/{client-side-encryption/testdata => testdata/client-side-encryption}/external-key.json (100%) rename src/test/spec/json/{client-side-encryption/testdata => testdata/client-side-encryption}/external-schema.json (100%) rename src/test/spec/json/{client-side-encryption/testdata => testdata/client-side-encryption}/limits-doc.json (100%) rename src/test/spec/json/{client-side-encryption/testdata => testdata/client-side-encryption}/limits-key.json (100%) rename src/test/spec/json/{client-side-encryption/testdata => testdata/client-side-encryption}/limits-schema.json (100%) diff --git a/src/test/csfle.rs b/src/test/csfle.rs index 620b55735..939e101e3 100644 --- a/src/test/csfle.rs +++ b/src/test/csfle.rs @@ -496,7 +496,7 @@ async fn external_key_vault() -> Result<()> { fn load_testdata_raw(name: &str) -> Result { let path: PathBuf = [ env!("CARGO_MANIFEST_DIR"), - "src/test/spec/json/client-side-encryption/testdata", + "src/test/spec/json/testdata/client-side-encryption", name, ] .iter() diff --git a/src/test/spec/json/client-side-encryption/README.rst b/src/test/spec/json/client-side-encryption/README.rst new file mode 100644 index 000000000..5457de981 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/README.rst @@ -0,0 +1,2381 @@ +============================ +Client Side Encryption Tests +============================ + +.. contents:: + +---- + +Introduction +============ + +This document describes the format of the driver spec tests included in the +JSON and YAML files included in the ``legacy`` sub-directory. Tests in the +``unified`` directory are written using the `Unified Test Format +<../../unified-test-format/unified-test-format.rst>`_. + +The ``timeoutMS.yml``/``timeoutMS.json`` files in this directory contain tests +for the ``timeoutMS`` option and its application to the client-side encryption +feature. Drivers MUST only run these tests after implementing the +`Client Side Operations Timeout +<../client-side-operations-timeout/client-side-operations-timeout.rst>`__ +specification. + +Additional prose tests, that are not represented in the spec tests, are described +and MUST be implemented by all drivers. + +Spec Test Format +================ + +The spec tests format is an extension of `transactions spec tests `_ with some additions: + +- A ``json_schema`` to set on the collection used for operations. + +- An ``encrypted_fields`` to set on the collection used for operations. + +- A ``key_vault_data`` of data that should be inserted in the key vault collection before each test. + +- Introduction ``autoEncryptOpts`` to `clientOptions` + +- Addition of `$db` to command in `command_started_event` + +- Addition of `$$type` to command_started_event and outcome. + +The semantics of `$$type` is that any actual value matching one of the types indicated by either a BSON type string +or an array of BSON type strings is considered a match. + +For example, the following matches a command_started_event for an insert of a document where `random` must be of type ``binData``:: + + - command_started_event: + command: + insert: *collection_name + documents: + - { random: { $$type: "binData" } } + ordered: true + command_name: insert + +The following matches a command_started_event for an insert of a document where ``random`` must be of type +``binData`` or ``string``:: + + - command_started_event: + command: + insert: *collection_name + documents: + - { random: { $$type: ["binData", "string"] } } + ordered: true + command_name: insert + +The values of `$$type` correspond to `these documented string representations of BSON types `_. + + +Each YAML file has the following keys: + +.. |txn| replace:: Unchanged from Transactions spec tests. + +- ``runOn`` |txn| + +- ``database_name`` |txn| + +- ``collection_name`` |txn| + +- ``data`` |txn| + +- ``json_schema`` A JSON Schema that should be set on the collection (using ``createCollection``) before each test run. + +- ``encrypted_fields`` An encryptedFields option that should be set on the collection (using ``createCollection``) before each test run. + +- ``key_vault_data`` The data that should exist in the key vault collection under test before each test run. + +- ``tests``: An array of tests that are to be run independently of each other. + Each test will have some or all of the following fields: + + - ``description``: |txn| + + - ``skipReason``: |txn| + + - ``useMultipleMongoses``: |txn| + + - ``failPoint``: |txn| + + - ``clientOptions``: Optional, parameters to pass to MongoClient(). + + - ``autoEncryptOpts``: Optional + + - ``kmsProviders`` A dictionary of KMS providers to set on the key vault ("aws" or "local") + + - ``aws`` The AWS KMS provider. An empty object. Drivers MUST fill in AWS credentials (`accessKeyId`, `secretAccessKey`) from the environment. + + - ``azure`` The Azure KMS provider credentials. An empty object. Drivers MUST fill in Azure credentials (`tenantId`, `clientId`, and `clientSecret`) from the environment. + + - ``gcp`` The GCP KMS provider credentials. An empty object. Drivers MUST fill in GCP credentials (`email`, `privateKey`) from the environment. + + - ``local`` The local KMS provider. + + - ``key`` A 96 byte local key. + + - ``kmip`` The KMIP KMS provider credentials. An empty object. Drivers MUST fill in KMIP credentials (`endpoint`, and TLS options). + + - ``schemaMap``: Optional, a map from namespaces to local JSON schemas. + + - ``keyVaultNamespace``: Optional, a namespace to the key vault collection. Defaults to "keyvault.datakeys". + + - ``bypassAutoEncryption``: Optional, a boolean to indicate whether or not auto encryption should be bypassed. Defaults to ``false``. + + - ``encryptedFieldsMap`` An optional document. The document maps collection namespace to ``EncryptedFields`` documents. + + - ``operations``: Array of documents, each describing an operation to be + executed. Each document has the following fields: + + - ``name``: |txn| + + - ``object``: |txn|. Defaults to "collection" if omitted. + + - ``collectionOptions``: |txn| + + - ``command_name``: |txn| + + - ``arguments``: |txn| + + - ``result``: Same as the Transactions spec test format with one addition: if the operation is expected to return + an error, the ``result`` document may contain an ``isTimeoutError`` boolean field. If ``true``, the test runner + MUST assert that the error represents a timeout due to the use of the ``timeoutMS`` option. If ``false``, the + test runner MUST assert that the error does not represent a timeout. + + - ``expectations``: |txn| + + - ``outcome``: |txn| + + + +Use as integration tests +======================== + +Do the following before running spec tests: + +- If available for the platform under test, obtain a crypt_shared_ binary and place it + in a location accessible to the tests. Refer to: `Using crypt_shared`_ +- Start the mongocryptd process. +- Start a mongod process with **server version 4.1.9 or later**. +- Place credentials to an AWS IAM user (access key ID + secret access key) somewhere in the environment outside of tracked code. (If testing on evergreen, project variables are a good place). +- Start a KMIP test server on port 5698 by running `drivers-evergreen-tools/.evergreen/csfle/kms_kmip_server.py `_. + +.. _crypt_shared: ../client-side-encryption.rst#crypt_shared + +Load each YAML (or JSON) file using a Canonical Extended JSON parser. + +Then for each element in ``tests``: + +#. If the ``skipReason`` field is present, skip this test completely. +#. If the ``key_vault_data`` field is present: + + #. Drop the ``keyvault.datakeys`` collection using writeConcern "majority". + #. Insert the data specified into the ``keyvault.datakeys`` with write concern "majority". + +#. Create a MongoClient. + +#. Create a collection object from the MongoClient, using the ``database_name`` + and ``collection_name`` fields from the YAML file. Drop the collection + with writeConcern "majority". If a ``json_schema`` is defined in the test, + use the ``createCollection`` command to explicitly create the collection: + + .. code:: typescript + + {"create": , "validator": {"$jsonSchema": }} + + If ``encrypted_fields`` is defined in the test, the required collections and index described in `Create and Drop Collection Helpers `_ must be created: + + - Use the ``dropCollection`` helper with ``encrypted_fields`` as an option and writeConcern "majority". + - Use the ``createCollection`` helper with ``encrypted_fields`` as an option. + +#. If the YAML file contains a ``data`` array, insert the documents in ``data`` + into the test collection, using writeConcern "majority". + +#. Create a **new** MongoClient using ``clientOptions``. + + #. If ``autoEncryptOpts`` includes ``aws``, ``awsTemporary``, ``awsTemporaryNoSessionToken``, + ``azure``, ``gcp``, and/or ``kmip`` as a KMS provider, pass in credentials from the environment. + + - ``awsTemporary``, and ``awsTemporaryNoSessionToken`` require temporary + AWS credentials. These can be retrieved using the csfle `set-temp-creds.sh + `_ + script. + + - ``aws``, ``awsTemporary``, and ``awsTemporaryNoSessionToken`` are + mutually exclusive. + + ``aws`` should be substituted with: + + .. code:: javascript + + "aws": { + "accessKeyId": , + "secretAccessKey": + } + + ``awsTemporary`` should be substituted with: + + .. code:: javascript + + "aws": { + "accessKeyId": , + "secretAccessKey": + "sessionToken": + } + + ``awsTemporaryNoSessionToken`` should be substituted with: + + .. code:: javascript + + "aws": { + "accessKeyId": , + "secretAccessKey": + } + + ``gcp`` should be substituted with: + + .. code:: javascript + + "gcp": { + "email": , + "privateKey": , + } + + ``azure`` should be substituted with: + + .. code:: javascript + + "azure": { + "tenantId": , + "clientId": , + "clientSecret": , + } + + ``local`` should be substituted with: + + .. code:: javascript + + "local": { "key": } + + ``kmip`` should be substituted with: + + .. code:: javascript + + "kmip": { "endpoint": "localhost:5698" } + + Configure KMIP TLS connections to use the following options: + + - ``tlsCAFile`` (or equivalent) set to `drivers-evergreen-tools/.evergreen/x509gen/ca.pem `_. This MAY be configured system-wide. + - ``tlsCertificateKeyFile`` (or equivalent) set to `drivers-evergreen-tools/.evergreen/x509gen/client.pem `_. + + The method of passing TLS options for KMIP TLS connections is driver dependent. + + #. If ``autoEncryptOpts`` does not include ``keyVaultNamespace``, default it + to ``keyvault.datakeys``. + +#. For each element in ``operations``: + + - Enter a "try" block or your programming language's closest equivalent. + - Create a Database object from the MongoClient, using the ``database_name`` + field at the top level of the test file. + - Create a Collection object from the Database, using the + ``collection_name`` field at the top level of the test file. + If ``collectionOptions`` is present create the Collection object with the + provided options. Otherwise create the object with the default options. + - Execute the named method on the provided ``object``, passing the + arguments listed. + - If the driver throws an exception / returns an error while executing this + series of operations, store the error message and server error code. + - If the result document has an "errorContains" field, verify that the + method threw an exception or returned an error, and that the value of the + "errorContains" field matches the error string. "errorContains" is a + substring (case-insensitive) of the actual error message. + + If the result document has an "errorCodeName" field, verify that the + method threw a command failed exception or returned an error, and that + the value of the "errorCodeName" field matches the "codeName" in the + server error response. + + If the result document has an "errorLabelsContain" field, verify that the + method threw an exception or returned an error. Verify that all of the + error labels in "errorLabelsContain" are present in the error or exception + using the ``hasErrorLabel`` method. + + If the result document has an "errorLabelsOmit" field, verify that the + method threw an exception or returned an error. Verify that none of the + error labels in "errorLabelsOmit" are present in the error or exception + using the ``hasErrorLabel`` method. + - If the operation returns a raw command response, eg from ``runCommand``, + then compare only the fields present in the expected result document. + Otherwise, compare the method's return value to ``result`` using the same + logic as the CRUD Spec Tests runner. + +#. If the test includes a list of command-started events in ``expectations``, + compare them to the actual command-started events using the + same logic as the Command Monitoring Spec Tests runner. + +#. For each element in ``outcome``: + + - If ``name`` is "collection", create a new MongoClient *without encryption* + and verify that the test collection contains exactly the documents in the + ``data`` array. Ensure this find reads the latest data by using + **primary read preference** with **local read concern** even when the + MongoClient is configured with another read preference or read concern. + +The spec test MUST be run with *and* without auth. + + +Using ``crypt_shared`` +====================== + +On platforms where crypt_shared_ is available, drivers should prefer to test +with the ``crypt_shared`` library instead of spawning mongocryptd. + +crypt_shared_ is released alongside the server. +crypt_shared_ is only available in versions 6.0 and above. +Drivers SHOULD prefer testing a version of crypt_shared_ that matches the server version being tested. +Driver tests on server versions less than 6.0 SHOULD use mongocryptd. + +Drivers MUST continue to run all tests with mongocryptd on at least one +platform for all tested server versions. + +Note that some tests assert on mongocryptd-related behaviors (e.g. the +``mongocryptdBypassSpawn`` test). + +Drivers under test should load the crypt_shared_ library using either the +``cryptSharedLibPath`` public API option (as part of the AutoEncryption +``extraOptions``), or by setting a special search path instead. + +Some tests will require *not* using crypt_shared_. For such tests, one should +ensure that ``crypt_shared`` will not be loaded. Refer to the +client-side-encryption documentation for information on "disabling" +``crypt_shared`` and setting library search paths. + +.. note:: + + The crypt_shared_ dynamic library can be obtained using the mongodl_ Python + script from drivers-evergreen-tools_: + + .. code-block:: shell + + $ python3 mongodl.py --component=crypt_shared --version= --out=./crypt_shared/ + + Other versions of ``crypt_shared`` are also available. Please use the + ``--list`` option to see versions. + +.. _mongodl: https://github.com/mongodb-labs/drivers-evergreen-tools/blob/master/.evergreen/mongodl.py +.. _drivers-evergreen-tools: https://github.com/mongodb-labs/drivers-evergreen-tools/ + + + +Prose Tests +=========== + +Tests for the ClientEncryption type are not included as part of the YAML tests. + +In the prose tests LOCAL_MASTERKEY refers to the following base64: + +.. code:: javascript + + Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk + +Perform all applicable operations on key vault collections (e.g. inserting an example data key, or running a find command) with readConcern/writeConcern "majority". + +1. Custom Key Material Test +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +#. Create a ``MongoClient`` object (referred to as ``client``). + +#. Using ``client``, drop the collection ``keyvault.datakeys``. + +#. Create a ``ClientEncryption`` object (referred to as ``client_encryption``) with ``client`` set as the ``keyVaultClient``. + +#. Using ``client_encryption``, create a data key with a ``local`` KMS provider and the following custom key material (given as base64): + +.. code:: javascript + + xPTAjBRG5JiPm+d3fj6XLi2q5DMXUS/f1f+SMAlhhwkhDRL0kr8r9GDLIGTAGlvC+HVjSIgdL+RKwZCvpXSyxTICWSXTUYsWYPyu3IoHbuBZdmw2faM3WhcRIgbMReU5 + +#. Find the resulting key document in ``keyvault.datakeys``, save a copy of the key document, then remove the key document from the collection. + +#. Replace the ``_id`` field in the copied key document with a UUID with base64 value ``AAAAAAAAAAAAAAAAAAAAAA==`` (16 bytes all equal to ``0x00``) and insert the modified key document into ``keyvault.datakeys`` with majority write concern. + +#. Using ``client_encryption``, encrypt the string ``"test"`` with the modified data key using the ``AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic`` algorithm and assert the resulting value is equal to the following (given as base64): + +.. code:: javascript + + AQAAAAAAAAAAAAAAAAAAAAACz0ZOLuuhEYi807ZXTdhbqhLaS2/t9wLifJnnNYwiw79d75QYIZ6M/aYC1h9nCzCjZ7pGUpAuNnkUhnIXM3PjrA== + +2. Data Key and Double Encryption +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +First, perform the setup. + +#. Create a MongoClient without encryption enabled (referred to as ``client``). Enable command monitoring to listen for command_started events. + +#. Using ``client``, drop the collections ``keyvault.datakeys`` and ``db.coll``. + +#. Create the following: + + - A MongoClient configured with auto encryption (referred to as ``client_encrypted``) + - A ``ClientEncryption`` object (referred to as ``client_encryption``) + + Configure both objects with the following KMS providers: + + .. code:: javascript + + { + "aws": { + "accessKeyId": , + "secretAccessKey": + }, + "azure": { + "tenantId": , + "clientId": , + "clientSecret": , + }, + "gcp": { + "email": , + "privateKey": , + } + "local": { "key": }, + "kmip": { "endpoint": "localhost:5698" } + } + + Configure KMIP TLS connections to use the following options: + + - ``tlsCAFile`` (or equivalent) set to `drivers-evergreen-tools/.evergreen/x509gen/ca.pem `_. This MAY be configured system-wide. + - ``tlsCertificateKeyFile`` (or equivalent) set to `drivers-evergreen-tools/.evergreen/x509gen/client.pem `_. + + The method of passing TLS options for KMIP TLS connections is driver dependent. + + Configure both objects with ``keyVaultNamespace`` set to ``keyvault.datakeys``. + + Configure the ``MongoClient`` with the following ``schema_map``: + + .. code:: javascript + + { + "db.coll": { + "bsonType": "object", + "properties": { + "encrypted_placeholder": { + "encrypt": { + "keyId": "/placeholder", + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + } + } + } + } + + Configure ``client_encryption`` with the ``keyVaultClient`` of the previously created ``client``. + +For each KMS provider (``aws``, ``azure``, ``gcp``, ``local``, and ``kmip``), referred to as ``provider_name``, run the following test. + +#. Call ``client_encryption.createDataKey()``. + + - Set keyAltNames to ``["_altname"]``. + - Set the masterKey document based on ``provider_name``. + + For "aws": + + .. code:: javascript + + { + region: "us-east-1", + key: "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0" + } + + For "azure": + + .. code:: javascript + + { + "keyVaultEndpoint": "key-vault-csfle.vault.azure.net", + "keyName": "key-name-csfle" + } + + For "gcp": + + .. code:: javascript + + { + "projectId": "devprod-drivers", + "location": "global", + "keyRing": "key-ring-csfle", + "keyName": "key-name-csfle" + } + + For "kmip": + + .. code:: javascript + + {} + + For "local", do not set a masterKey document. + - Expect a BSON binary with subtype 4 to be returned, referred to as ``datakey_id``. + - Use ``client`` to run a ``find`` on ``keyvault.datakeys`` by querying with the ``_id`` set to the ``datakey_id``. + - Expect that exactly one document is returned with the "masterKey.provider" equal to ``provider_name``. + - Check that ``client`` captured a command_started event for the ``insert`` command containing a majority writeConcern. + +#. Call ``client_encryption.encrypt()`` with the value "hello ", the algorithm ``AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic``, and the ``key_id`` of ``datakey_id``. + + - Expect the return value to be a BSON binary subtype 6, referred to as ``encrypted``. + - Use ``client_encrypted`` to insert ``{ _id: "", "value": }`` into ``db.coll``. + - Use ``client_encrypted`` to run a find querying with ``_id`` of "" and expect ``value`` to be "hello ". + +#. Call ``client_encryption.encrypt()`` with the value "hello ", the algorithm ``AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic``, and the ``key_alt_name`` of ``_altname``. + + - Expect the return value to be a BSON binary subtype 6. Expect the value to exactly match the value of ``encrypted``. + +#. Test explicit encrypting an auto encrypted field. + + - Use ``client_encrypted`` to attempt to insert ``{ "encrypted_placeholder": }`` + - Expect an exception to be thrown, since this is an attempt to auto encrypt an already encrypted value. + + + +3. External Key Vault Test +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Run the following tests twice, parameterized by a boolean ``withExternalKeyVault``. + +#. Create a MongoClient without encryption enabled (referred to as ``client``). + +#. Using ``client``, drop the collections ``keyvault.datakeys`` and ``db.coll``. + Insert the document `external/external-key.json <../external/external-key.json>`_ into ``keyvault.datakeys``. + +#. Create the following: + + - A MongoClient configured with auto encryption (referred to as ``client_encrypted``) + - A ``ClientEncryption`` object (referred to as ``client_encryption``) + + Configure both objects with the ``local`` KMS providers as follows: + + .. code:: javascript + + { "local": { "key": } } + + Configure both objects with ``keyVaultNamespace`` set to ``keyvault.datakeys``. + + Configure ``client_encrypted`` to use the schema `external/external-schema.json <../external/external-schema.json>`_ for ``db.coll`` by setting a schema map like: ``{ "db.coll": }`` + + If ``withExternalKeyVault == true``, configure both objects with an external key vault client. The external client MUST connect to the same + MongoDB cluster that is being tested against, except it MUST use the username ``fake-user`` and password ``fake-pwd``. + +#. Use ``client_encrypted`` to insert the document ``{"encrypted": "test"}`` into ``db.coll``. + If ``withExternalKeyVault == true``, expect an authentication exception to be thrown. Otherwise, expect the insert to succeed. + +#. Use ``client_encryption`` to explicitly encrypt the string ``"test"`` with key ID ``LOCALAAAAAAAAAAAAAAAAA==`` and deterministic algorithm. + If ``withExternalKeyVault == true``, expect an authentication exception to be thrown. Otherwise, expect the insert to succeed. + + +4. BSON Size Limits and Batch Splitting +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +First, perform the setup. + +#. Create a MongoClient without encryption enabled (referred to as ``client``). + +#. Using ``client``, drop and create the collection ``db.coll`` configured with the included JSON schema `limits/limits-schema.json <../limits/limits-schema.json>`_. + +#. Using ``client``, drop the collection ``keyvault.datakeys``. Insert the document `limits/limits-key.json <../limits/limits-key.json>`_ + +#. Create a MongoClient configured with auto encryption (referred to as ``client_encrypted``) + + Configure with the ``local`` KMS provider as follows: + + .. code:: javascript + + { "local": { "key": } } + + Configure with the ``keyVaultNamespace`` set to ``keyvault.datakeys``. + +Using ``client_encrypted`` perform the following operations: + +#. Insert ``{ "_id": "over_2mib_under_16mib", "unencrypted": }``. + + Expect this to succeed since this is still under the ``maxBsonObjectSize`` limit. + +#. Insert the document `limits/limits-doc.json <../limits/limits-doc.json>`_ concatenated with ``{ "_id": "encryption_exceeds_2mib", "unencrypted": < the string "a" repeated (2097152 - 2000) times > }`` + Note: limits-doc.json is a 1005 byte BSON document that encrypts to a ~10,000 byte document. + + Expect this to succeed since after encryption this still is below the normal maximum BSON document size. + Note, before auto encryption this document is under the 2 MiB limit. After encryption it exceeds the 2 MiB limit, but does NOT exceed the 16 MiB limit. + +#. Bulk insert the following: + + - ``{ "_id": "over_2mib_1", "unencrypted": }`` + + - ``{ "_id": "over_2mib_2", "unencrypted": }`` + + Expect the bulk write to succeed and split after first doc (i.e. two inserts occur). This may be verified using `command monitoring `_. + +#. Bulk insert the following: + + - The document `limits/limits-doc.json <../limits/limits-doc.json>`_ concatenated with ``{ "_id": "encryption_exceeds_2mib_1", "unencrypted": < the string "a" repeated (2097152 - 2000) times > }`` + + - The document `limits/limits-doc.json <../limits/limits-doc.json>`_ concatenated with ``{ "_id": "encryption_exceeds_2mib_2", "unencrypted": < the string "a" repeated (2097152 - 2000) times > }`` + + Expect the bulk write to succeed and split after first doc (i.e. two inserts occur). This may be verified using `command monitoring `_. + +#. Insert ``{ "_id": "under_16mib", "unencrypted": ``. + + Expect this to succeed since this is still (just) under the ``maxBsonObjectSize`` limit. + +#. Insert the document `limits/limits-doc.json <../limits/limits-doc.json>`_ concatenated with ``{ "_id": "encryption_exceeds_16mib", "unencrypted": < the string "a" repeated (16777216 - 2000) times > }`` + + Expect this to fail since encryption results in a document exceeding the ``maxBsonObjectSize`` limit. + +Optionally, if it is possible to mock the maxWriteBatchSize (i.e. the maximum number of documents in a batch) test that setting maxWriteBatchSize=1 and inserting the two documents ``{ "_id": "a" }, { "_id": "b" }`` with ``client_encrypted`` splits the operation into two inserts. + + +5. Views Are Prohibited +~~~~~~~~~~~~~~~~~~~~~~~ + +#. Create a MongoClient without encryption enabled (referred to as ``client``). + +#. Using ``client``, drop and create a view named ``db.view`` with an empty pipeline. E.g. using the command ``{ "create": "view", "viewOn": "coll" }``. + +#. Create a MongoClient configured with auto encryption (referred to as ``client_encrypted``) + + Configure with the ``local`` KMS provider as follows: + + .. code:: javascript + + { "local": { "key": } } + + Configure with the ``keyVaultNamespace`` set to ``keyvault.datakeys``. + +#. Using ``client_encrypted``, attempt to insert a document into ``db.view``. Expect an exception to be thrown containing the message: "cannot auto encrypt a view". + + +6. Corpus Test +~~~~~~~~~~~~~~ + +The corpus test exhaustively enumerates all ways to encrypt all BSON value types. Note, the test data includes BSON binary subtype 4 (or standard UUID), which MUST be decoded and encoded as subtype 4. Run the test as follows. + +1. Create a MongoClient without encryption enabled (referred to as ``client``). + +2. Using ``client``, drop and create the collection ``db.coll`` configured with the included JSON schema `corpus/corpus-schema.json <../corpus/corpus-schema.json>`_. + +3. Using ``client``, drop the collection ``keyvault.datakeys``. Insert the documents `corpus/corpus-key-local.json <../corpus/corpus-key-local.json>`_, `corpus/corpus-key-aws.json <../corpus/corpus-key-aws.json>`_, `corpus/corpus-key-azure.json <../corpus/corpus-key-azure.json>`_, `corpus/corpus-key-gcp.json <../corpus/corpus-key-gcp.json>`_, and `corpus/corpus-key-kmip.json <../corpus/corpus-key-kmip.json>`_. + +4. Create the following: + + - A MongoClient configured with auto encryption (referred to as ``client_encrypted``) + - A ``ClientEncryption`` object (referred to as ``client_encryption``) + + Configure both objects with ``aws``, ``azure``, ``gcp``, ``local``, and ``kmip`` KMS providers as follows: + + .. code:: javascript + + { + "aws": { }, + "azure": { }, + "gcp": { }, + "local": { "key": }, + "kmip": { "endpoint": "localhost:5698" } } + } + + Configure KMIP TLS connections to use the following options: + + - ``tlsCAFile`` (or equivalent) set to `drivers-evergreen-tools/.evergreen/x509gen/ca.pem `_. This MAY be configured system-wide. + - ``tlsCertificateKeyFile`` (or equivalent) set to `drivers-evergreen-tools/.evergreen/x509gen/client.pem `_. + + The method of passing TLS options for KMIP TLS connections is driver dependent. + + Where LOCAL_MASTERKEY is the following base64: + + .. code:: javascript + + Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk + + Configure both objects with ``keyVaultNamespace`` set to ``keyvault.datakeys``. + +5. Load `corpus/corpus.json <../corpus/corpus.json>`_ to a variable named ``corpus``. The corpus contains subdocuments with the following fields: + + - ``kms`` is ``aws``, ``azure``, ``gcp``, ``local``, or ``kmip`` + - ``type`` is a BSON type string `names coming from here `_) + - ``algo`` is either ``rand`` or ``det`` for random or deterministic encryption + - ``method`` is either ``auto``, for automatic encryption or ``explicit`` for explicit encryption + - ``identifier`` is either ``id`` or ``altname`` for the key identifier + - ``allowed`` is a boolean indicating whether the encryption for the given parameters is permitted. + - ``value`` is the value to be tested. + + Create a new BSON document, named ``corpus_copied``. + Iterate over each field of ``corpus``. + + - If the field name is ``_id``, ``altname_aws``, ``altname_local``, ``altname_azure``, ``altname_gcp``, or ``altname_kmip`` copy the field to ``corpus_copied``. + - If ``method`` is ``auto``, copy the field to ``corpus_copied``. + - If ``method`` is ``explicit``, use ``client_encryption`` to explicitly encrypt the value. + + - Encrypt with the algorithm described by ``algo``. + - If ``identifier`` is ``id`` + + - If ``kms`` is ``local`` set the key_id to the UUID with base64 value ``LOCALAAAAAAAAAAAAAAAAA==``. + - If ``kms`` is ``aws`` set the key_id to the UUID with base64 value ``AWSAAAAAAAAAAAAAAAAAAA==``. + - If ``kms`` is ``azure`` set the key_id to the UUID with base64 value ``AZUREAAAAAAAAAAAAAAAAA==``. + - If ``kms`` is ``gcp`` set the key_id to the UUID with base64 value ``GCPAAAAAAAAAAAAAAAAAAA==``. + - If ``kms`` is ``kmip`` set the key_id to the UUID with base64 value ``KMIPAAAAAAAAAAAAAAAAAA==``. + + - If ``identifier`` is ``altname`` + + - If ``kms`` is ``local`` set the key_alt_name to "local". + - If ``kms`` is ``aws`` set the key_alt_name to "aws". + - If ``kms`` is ``azure`` set the key_alt_name to "azure". + - If ``kms`` is ``gcp`` set the key_alt_name to "gcp". + - If ``kms`` is ``kmip`` set the key_alt_name to "kmip". + + If ``allowed`` is true, copy the field and encrypted value to ``corpus_copied``. + If ``allowed`` is false. verify that an exception is thrown. Copy the unencrypted value to to ``corpus_copied``. + + +6. Using ``client_encrypted``, insert ``corpus_copied`` into ``db.coll``. + +7. Using ``client_encrypted``, find the inserted document from ``db.coll`` to a variable named ``corpus_decrypted``. Since it should have been automatically decrypted, assert the document exactly matches ``corpus``. + +8. Load `corpus/corpus_encrypted.json <../corpus/corpus-encrypted.json>`_ to a variable named ``corpus_encrypted_expected``. + Using ``client`` find the inserted document from ``db.coll`` to a variable named ``corpus_encrypted_actual``. + + Iterate over each field of ``corpus_encrypted_expected`` and check the following: + + - If the ``algo`` is ``det``, that the value equals the value of the corresponding field in ``corpus_encrypted_actual``. + - If the ``algo`` is ``rand`` and ``allowed`` is true, that the value does not equal the value of the corresponding field in ``corpus_encrypted_actual``. + - If ``allowed`` is true, decrypt the value with ``client_encryption``. Decrypt the value of the corresponding field of ``corpus_encrypted`` and validate that they are both equal. + - If ``allowed`` is false, validate the value exactly equals the value of the corresponding field of ``corpus`` (neither was encrypted). + +9. Repeat steps 1-8 with a local JSON schema. I.e. amend step 4 to configure the schema on ``client_encrypted`` with the ``schema_map`` option. + +7. Custom Endpoint Test +~~~~~~~~~~~~~~~~~~~~~~~ + +Setup +````` + +For each test cases, start by creating two ``ClientEncryption`` objects. Recreate the ``ClientEncryption`` objects for each test case. + +Create a ``ClientEncryption`` object (referred to as ``client_encryption``) + +Configure with ``keyVaultNamespace`` set to ``keyvault.datakeys``, and a default MongoClient as the ``keyVaultClient``. + +Configure with KMS providers as follows: + +.. code:: javascript + + { + "aws": { + "accessKeyId": , + "secretAccessKey": + }, + "azure": { + "tenantId": , + "clientId": , + "clientSecret": , + "identityPlatformEndpoint": "login.microsoftonline.com:443" + }, + "gcp": { + "email": , + "privateKey": , + "endpoint": "oauth2.googleapis.com:443" + }, + "kmip" { + "endpoint": "localhost:5698" + } + } + +Create a ``ClientEncryption`` object (referred to as ``client_encryption_invalid``) + +Configure with ``keyVaultNamespace`` set to ``keyvault.datakeys``, and a default MongoClient as the ``keyVaultClient``. + +Configure with KMS providers as follows: + +.. code:: javascript + + { + "azure": { + "tenantId": , + "clientId": , + "clientSecret": , + "identityPlatformEndpoint": "doesnotexist.invalid:443" + }, + "gcp": { + "email": , + "privateKey": , + "endpoint": "doesnotexist.invalid:443" + }, + "kmip": { + "endpoint": "doesnotexist.local:5698" + } + } + +Configure KMIP TLS connections to use the following options: + +- ``tlsCAFile`` (or equivalent) set to `drivers-evergreen-tools/.evergreen/x509gen/ca.pem `_. This MAY be configured system-wide. +- ``tlsCertificateKeyFile`` (or equivalent) set to `drivers-evergreen-tools/.evergreen/x509gen/client.pem `_. + +The method of passing TLS options for KMIP TLS connections is driver dependent. + +Test cases +`````````` + +1. Call `client_encryption.createDataKey()` with "aws" as the provider and the following masterKey: + + .. code:: javascript + + { + region: "us-east-1", + key: "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0" + } + + Expect this to succeed. Use the returned UUID of the key to explicitly encrypt and decrypt the string "test" to validate it works. + +2. Call `client_encryption.createDataKey()` with "aws" as the provider and the following masterKey: + + .. code:: javascript + + { + region: "us-east-1", + key: "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + endpoint: "kms.us-east-1.amazonaws.com" + } + + Expect this to succeed. Use the returned UUID of the key to explicitly encrypt and decrypt the string "test" to validate it works. + +3. Call `client_encryption.createDataKey()` with "aws" as the provider and the following masterKey: + + .. code:: javascript + + { + region: "us-east-1", + key: "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + endpoint: "kms.us-east-1.amazonaws.com:443" + } + + Expect this to succeed. Use the returned UUID of the key to explicitly encrypt and decrypt the string "test" to validate it works. + +4. Call `client_encryption.createDataKey()` with "aws" as the provider and the following masterKey: + + .. code:: javascript + + { + region: "us-east-1", + key: "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + endpoint: "kms.us-east-1.amazonaws.com:12345" + } + + Expect this to fail with a socket connection error. + +5. Call `client_encryption.createDataKey()` with "aws" as the provider and the following masterKey: + + .. code:: javascript + + { + region: "us-east-1", + key: "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + endpoint: "kms.us-east-2.amazonaws.com" + } + + Expect this to fail with an exception. + +6. Call `client_encryption.createDataKey()` with "aws" as the provider and the following masterKey: + + .. code:: javascript + + { + region: "us-east-1", + key: "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + endpoint: "doesnotexist.invalid" + } + + Expect this to fail with a network exception indicating failure to resolve "doesnotexist.invalid". + +7. Call `client_encryption.createDataKey()` with "azure" as the provider and the following masterKey: + + .. code:: javascript + + { + "keyVaultEndpoint": "key-vault-csfle.vault.azure.net", + "keyName": "key-name-csfle" + } + + Expect this to succeed. Use the returned UUID of the key to explicitly encrypt and decrypt the string "test" to validate it works. + + Call ``client_encryption_invalid.createDataKey()`` with the same masterKey. Expect this to fail with a network exception indicating failure to resolve "doesnotexist.invalid". + +8. Call `client_encryption.createDataKey()` with "gcp" as the provider and the following masterKey: + + .. code:: javascript + + { + "projectId": "devprod-drivers", + "location": "global", + "keyRing": "key-ring-csfle", + "keyName": "key-name-csfle", + "endpoint": "cloudkms.googleapis.com:443" + } + + Expect this to succeed. Use the returned UUID of the key to explicitly encrypt and decrypt the string "test" to validate it works. + + Call ``client_encryption_invalid.createDataKey()`` with the same masterKey. Expect this to fail with a network exception indicating failure to resolve "doesnotexist.invalid". + +9. Call `client_encryption.createDataKey()` with "gcp" as the provider and the following masterKey: + + .. code:: javascript + + { + "projectId": "devprod-drivers", + "location": "global", + "keyRing": "key-ring-csfle", + "keyName": "key-name-csfle", + "endpoint": "doesnotexist.invalid:443" + } + + Expect this to fail with an exception with a message containing the string: "Invalid KMS response". + +10. Call `client_encryption.createDataKey()` with "kmip" as the provider and the following masterKey: + + .. code:: javascript + + { + "keyId": "1" + } + + Expect this to succeed. Use the returned UUID of the key to explicitly encrypt and decrypt the string "test" to validate it works. + + Call ``client_encryption_invalid.createDataKey()`` with the same masterKey. Expect this to fail with a network exception indicating failure to resolve "doesnotexist.local". + +11. Call ``client_encryption.createDataKey()`` with "kmip" as the provider and the following masterKey: + + .. code:: javascript + + { + "keyId": "1", + "endpoint": "localhost:5698" + } + + Expect this to succeed. Use the returned UUID of the key to explicitly encrypt and decrypt the string "test" to validate it works. + +12. Call ``client_encryption.createDataKey()`` with "kmip" as the provider and the following masterKey: + + .. code:: javascript + + { + "keyId": "1", + "endpoint": "doesnotexist.local:5698" + } + + Expect this to fail with a network exception indicating failure to resolve "doesnotexist.local". + +8. Bypass Spawning mongocryptd +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. note:: + + IMPORTANT: If crypt_shared_ is visible to the operating system's library + search mechanism, the expected server error generated by these + ``mongocryptdBypassSpawn`` tests will not appear because libmongocrypt will + load the ``crypt_shared`` library instead of consulting mongocryptd. For + these tests, it is required that libmongocrypt *not* load ``crypt_shared``. + Refer to the client-side-encryption document for more information on + "disabling" ``crypt_shared``. + + +Via mongocryptdBypassSpawn +`````````````````````````` + +The following tests that setting ``mongocryptdBypassSpawn=true`` really does bypass spawning mongocryptd. + +#. Create a MongoClient configured with auto encryption (referred to as ``client_encrypted``) + + Configure the required options. Use the ``local`` KMS provider as follows: + + .. code:: javascript + + { "local": { "key": } } + + Configure with the ``keyVaultNamespace`` set to ``keyvault.datakeys``. + + Configure ``client_encrypted`` to use the schema `external/external-schema.json <../external/external-schema.json>`_ for ``db.coll`` by setting a schema map like: ``{ "db.coll": }`` + + Configure the following ``extraOptions``: + + .. code:: javascript + + { + "mongocryptdBypassSpawn": true + "mongocryptdURI": "mongodb://localhost:27021/db?serverSelectionTimeoutMS=1000", + "mongocryptdSpawnArgs": [ "--pidfilepath=bypass-spawning-mongocryptd.pid", "--port=27021"] + } + + Drivers MAY pass a different port if they expect their testing infrastructure to be using port 27021. Pass a port that should be free. + +#. Use ``client_encrypted`` to insert the document ``{"encrypted": "test"}`` into ``db.coll``. Expect a server selection error propagated from the internal MongoClient failing to connect to mongocryptd on port 27021. + +Via bypassAutoEncryption +```````````````````````` + +The following tests that setting ``bypassAutoEncryption=true`` really does bypass spawning mongocryptd. + +#. Create a MongoClient configured with auto encryption (referred to as ``client_encrypted``) + + Configure the required options. Use the ``local`` KMS provider as follows: + + .. code:: javascript + + { "local": { "key": } } + + Configure with the ``keyVaultNamespace`` set to ``keyvault.datakeys``. + + Configure with ``bypassAutoEncryption=true``. + + Configure the following ``extraOptions``: + + .. code:: javascript + + { + "mongocryptdSpawnArgs": [ "--pidfilepath=bypass-spawning-mongocryptd.pid", "--port=27021"] + } + + Drivers MAY pass a different value to ``--port`` if they expect their testing infrastructure to be using port 27021. Pass a port that should be free. + +#. Use ``client_encrypted`` to insert the document ``{"unencrypted": "test"}`` into ``db.coll``. Expect this to succeed. + +#. Validate that mongocryptd was not spawned. Create a MongoClient to localhost:27021 (or whatever was passed via ``--port``) with serverSelectionTimeoutMS=1000. Run a handshake command and ensure it fails with a server selection timeout. + +Via bypassQueryAnalysis +``````````````````````` + +Repeat the steps from the "Via bypassAutoEncryption" test, replacing "bypassAutoEncryption=true" with "bypassQueryAnalysis=true". + +9. Deadlock Tests +~~~~~~~~~~~~~~~~~ + +.. _Connection Monitoring and Pooling: /source/connection-monitoring-and-pooling/connection-monitoring-and-pooling.rst + +The following tests only apply to drivers that have implemented a connection pool (see the `Connection Monitoring and Pooling`_ specification). + +There are multiple parameterized test cases. Before each test case, perform the setup. + +Setup +````` + +Create a ``MongoClient`` for setup operations named ``client_test``. + +Create a ``MongoClient`` for key vault operations with ``maxPoolSize=1`` named ``client_keyvault``. Capture command started events. + +Using ``client_test``, drop the collections ``keyvault.datakeys`` and ``db.coll``. + +Insert the document `external/external-key.json <../external/external-key.json>`_ into ``keyvault.datakeys`` with majority write concern. + +Create a collection ``db.coll`` configured with a JSON schema `external/external-schema.json <../external/external-schema.json>`_ as the validator, like so: + +.. code:: typescript + + {"create": "coll", "validator": {"$jsonSchema": }} + +Create a ``ClientEncryption`` object, named ``client_encryption`` configured with: +- ``keyVaultClient``=``client_test`` +- ``keyVaultNamespace``="keyvault.datakeys" +- ``kmsProviders``=``{ "local": { "key": } }`` + +Use ``client_encryption`` to encrypt the value "string0" with ``algorithm``="AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" and ``keyAltName``="local". Store the result in a variable named ``ciphertext``. + +Proceed to run the test case. + +Each test case configures a ``MongoClient`` with automatic encryption (named ``client_encrypted``). + +Each test must assert the number of unique ``MongoClient``s created. This can be accomplished by capturing ``TopologyOpeningEvent``, or by checking command started events for a client identifier (not possible in all drivers). + +Running a test case +``````````````````` +- Create a ``MongoClient`` named ``client_encrypted`` configured as follows: + - Set ``AutoEncryptionOpts``: + - ``keyVaultNamespace="keyvault.datakeys"`` + - ``kmsProviders``=``{ "local": { "key": } }`` + - Append ``TestCase.AutoEncryptionOpts`` (defined below) + - Capture command started events. + - Set ``maxPoolSize=TestCase.MaxPoolSize`` +- If the testcase sets ``AutoEncryptionOpts.bypassAutoEncryption=true``: + - Use ``client_test`` to insert ``{ "_id": 0, "encrypted": }`` into ``db.coll``. +- Otherwise: + - Use ``client_encrypted`` to insert ``{ "_id": 0, "encrypted": "string0" }``. +- Use ``client_encrypted`` to run a ``findOne`` operation on ``db.coll``, with the filter ``{ "_id": 0 }``. +- Expect the result to be ``{ "_id": 0, "encrypted": "string0" }``. +- Check captured events against ``TestCase.Expectations``. +- Check the number of unique ``MongoClient``s created is equal to ``TestCase.ExpectedNumberOfClients``. + +Case 1 +`````` +- MaxPoolSize: 1 +- AutoEncryptionOpts: + - bypassAutoEncryption=false + - keyVaultClient=unset +- Expectations: + - Expect ``client_encrypted`` to have captured four ``CommandStartedEvent``: + - a listCollections to "db". + - a find on "keyvault". + - an insert on "db". + - a find on "db" +- ExpectedNumberOfClients: 2 + +Case 2 +`````` +- MaxPoolSize: 1 +- AutoEncryptionOpts: + - bypassAutoEncryption=false + - keyVaultClient=client_keyvault +- Expectations: + - Expect ``client_encrypted`` to have captured three ``CommandStartedEvent``: + - a listCollections to "db". + - an insert on "db". + - a find on "db" + - Expect ``client_keyvault`` to have captured one ``CommandStartedEvent``: + - a find on "keyvault". +- ExpectedNumberOfClients: 2 + +Case 3 +`````` +- MaxPoolSize: 1 +- AutoEncryptionOpts: + - bypassAutoEncryption=true + - keyVaultClient=unset +- Expectations: + - Expect ``client_encrypted`` to have captured three ``CommandStartedEvent``: + - a find on "db" + - a find on "keyvault". +- ExpectedNumberOfClients: 2 + +Case 4 +`````` +- MaxPoolSize: 1 +- AutoEncryptionOpts: + - bypassAutoEncryption=true + - keyVaultClient=client_keyvault +- Expectations: + - Expect ``client_encrypted`` to have captured two ``CommandStartedEvent``: + - a find on "db" + - Expect ``client_keyvault`` to have captured one ``CommandStartedEvent``: + - a find on "keyvault". +- ExpectedNumberOfClients: 1 + +Case 5 +`````` +Drivers that do not support an unlimited maximum pool size MUST skip this test. + +- MaxPoolSize: 0 +- AutoEncryptionOpts: + - bypassAutoEncryption=false + - keyVaultClient=unset +- Expectations: + - Expect ``client_encrypted`` to have captured five ``CommandStartedEvent``: + - a listCollections to "db". + - a listCollections to "keyvault". + - a find on "keyvault". + - an insert on "db". + - a find on "db" +- ExpectedNumberOfClients: 1 + +Case 6 +`````` +Drivers that do not support an unlimited maximum pool size MUST skip this test. + +- MaxPoolSize: 0 +- AutoEncryptionOpts: + - bypassAutoEncryption=false + - keyVaultClient=client_keyvault +- Expectations: + - Expect ``client_encrypted`` to have captured three ``CommandStartedEvent``: + - a listCollections to "db". + - an insert on "db". + - a find on "db" + - Expect ``client_keyvault`` to have captured one ``CommandStartedEvent``: + - a find on "keyvault". +- ExpectedNumberOfClients: 1 + +Case 7 +`````` +Drivers that do not support an unlimited maximum pool size MUST skip this test. + +- MaxPoolSize: 0 +- AutoEncryptionOpts: + - bypassAutoEncryption=true + - keyVaultClient=unset +- Expectations: + - Expect ``client_encrypted`` to have captured three ``CommandStartedEvent``: + - a find on "db" + - a find on "keyvault". +- ExpectedNumberOfClients: 1 + +Case 8 +`````` +Drivers that do not support an unlimited maximum pool size MUST skip this test. + +- MaxPoolSize: 0 +- AutoEncryptionOpts: + - bypassAutoEncryption=true + - keyVaultClient=client_keyvault +- Expectations: + - Expect ``client_encrypted`` to have captured two ``CommandStartedEvent``: + - a find on "db" + - Expect ``client_keyvault`` to have captured one ``CommandStartedEvent``: + - a find on "keyvault". +- ExpectedNumberOfClients: 1 + +10. KMS TLS Tests +~~~~~~~~~~~~~~~~~ + +.. _ca.pem: https://github.com/mongodb-labs/drivers-evergreen-tools/blob/master/.evergreen/x509gen/ca.pem +.. _expired.pem: https://github.com/mongodb-labs/drivers-evergreen-tools/blob/master/.evergreen/x509gen/expired.pem +.. _wrong-host.pem: https://github.com/mongodb-labs/drivers-evergreen-tools/blob/master/.evergreen/x509gen/wrong-host.pem +.. _server.pem: https://github.com/mongodb-labs/drivers-evergreen-tools/blob/master/.evergreen/x509gen/server.pem +.. _client.pem: https://github.com/mongodb-labs/drivers-evergreen-tools/blob/master/.evergreen/x509gen/client.pem + +The following tests that connections to KMS servers with TLS verify peer certificates. + +The two tests below make use of mock KMS servers which can be run on Evergreen using `the mock KMS server script `_. +Drivers can set up their local Python enviroment for the mock KMS server by running `the virtualenv activation script `_. + +To start two mock KMS servers, one on port 9000 with `ca.pem`_ as a CA file and `expired.pem`_ as a cert file, and one on port 9001 with `ca.pem`_ as a CA file and `wrong-host.pem`_ as a cert file, +run the following commands from the ``.evergreen/csfle`` directory: + +.. code:: + + . ./activate_venv.sh + python -u kms_http_server.py --ca_file ../x509gen/ca.pem --cert_file ../x509gen/expired.pem --port 9000 & + python -u kms_http_server.py --ca_file ../x509gen/ca.pem --cert_file ../x509gen/wrong-host.pem --port 9001 & + +Setup +````` + +For both tests, do the following: + +#. Start a ``mongod`` process with **server version 4.1.9 or later**. + +#. Create a ``MongoClient`` for key vault operations. + +#. Create a ``ClientEncryption`` object (referred to as ``client_encryption``) with ``keyVaultNamespace`` set to ``keyvault.datakeys``. + +Invalid KMS Certificate +``````````````````````` + +#. Start a mock KMS server on port 9000 with `ca.pem`_ as a CA file and `expired.pem`_ as a cert file. + +#. Call ``client_encryption.createDataKey()`` with "aws" as the provider and the following masterKey: + + .. code:: javascript + + { + "region": "us-east-1", + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "endpoint": "127.0.0.1:9000", + } + + Expect this to fail with an exception with a message referencing an expired certificate. This message will be language dependent. + In Python, this message is "certificate verify failed: certificate has expired". In Go, this message is + "certificate has expired or is not yet valid". If the language of implementation has a single, generic error message for + all certificate validation errors, drivers may inspect other fields of the error to verify its meaning. + +Invalid Hostname in KMS Certificate +``````````````````````````````````` + +#. Start a mock KMS server on port 9001 with `ca.pem`_ as a CA file and `wrong-host.pem`_ as a cert file. + +#. Call ``client_encryption.createDataKey()`` with "aws" as the provider and the following masterKey: + + .. code:: javascript + + { + "region": "us-east-1", + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "endpoint": "127.0.0.1:9001", + } + + Expect this to fail with an exception with a message referencing an incorrect or unexpected host. This message will be language dependent. + In Python, this message is "certificate verify failed: IP address mismatch, certificate is not valid for '127.0.0.1'". In Go, this message + is "cannot validate certificate for 127.0.0.1 because it doesn't contain any IP SANs". If the language of implementation has a single, generic + error message for all certificate validation errors, drivers may inspect other fields of the error to verify its meaning. + +11. KMS TLS Options Tests +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Setup +````` + +Start a ``mongod`` process with **server version 4.1.9 or later**. + +Four mock KMS server processes must be running: + +1. The mock `KMS HTTP server `_. + + Run on port 9000 with `ca.pem`_ as a CA file and `expired.pem`_ as a cert file. + + Example: + + .. code:: + + python -u kms_http_server.py --ca_file ../x509gen/ca.pem --cert_file ../x509gen/expired.pem --port 9000 + +2. The mock `KMS HTTP server `_. + + Run on port 9001 with `ca.pem`_ as a CA file and `wrong-host.pem`_ as a cert file. + + Example: + + .. code:: + + python -u kms_http_server.py --ca_file ../x509gen/ca.pem --cert_file ../x509gen/wrong-host.pem --port 9001 + +3. The mock `KMS HTTP server `_. + + Run on port 9002 with `ca.pem`_ as a CA file and `server.pem`_ as a cert file. + + Run with the ``--require_client_cert`` option. + + Example: + + .. code:: + + python -u kms_http_server.py --ca_file ../x509gen/ca.pem --cert_file ../x509gen/server.pem --port 9002 --require_client_cert + + +4. The mock `KMS KMIP server `_. + +Create the following four ``ClientEncryption`` objects. + +Configure each with ``keyVaultNamespace`` set to ``keyvault.datakeys``, and a default MongoClient as the ``keyVaultClient``. + +1. Create a ``ClientEncryption`` object named ``client_encryption_no_client_cert`` with the following KMS providers: + + .. code:: javascript + + { + "aws": { + "accessKeyId": , + "secretAccessKey": + }, + "azure": { + "tenantId": , + "clientId": , + "clientSecret": , + "identityPlatformEndpoint": "127.0.0.1:9002" + }, + "gcp": { + "email": , + "privateKey": , + "endpoint": "127.0.0.1:9002" + }, + "kmip" { + "endpoint": "127.0.0.1:5698" + } + } + + Add TLS options for the ``aws``, ``azure``, ``gcp``, and + ``kmip`` providers to use the following options: + + - ``tlsCAFile`` (or equivalent) set to `ca.pem`_. This MAY be configured system-wide. + +2. Create a ``ClientEncryption`` object named ``client_encryption_with_tls`` with the following KMS providers: + + .. code:: javascript + + { + "aws": { + "accessKeyId": , + "secretAccessKey": + }, + "azure": { + "tenantId": , + "clientId": , + "clientSecret": , + "identityPlatformEndpoint": "127.0.0.1:9002" + }, + "gcp": { + "email": , + "privateKey": , + "endpoint": "127.0.0.1:9002" + }, + "kmip" { + "endpoint": "127.0.0.1:5698" + } + } + + Add TLS options for the ``aws``, ``azure``, ``gcp``, and + ``kmip`` providers to use the following options: + + - ``tlsCAFile`` (or equivalent) set to `ca.pem`_. This MAY be configured system-wide. + - ``tlsCertificateKeyFile`` (or equivalent) set to `client.pem`_ + +3. Create a ``ClientEncryption`` object named ``client_encryption_expired`` with the following KMS providers: + + .. code:: javascript + + { + "aws": { + "accessKeyId": , + "secretAccessKey": + }, + "azure": { + "tenantId": , + "clientId": , + "clientSecret": , + "identityPlatformEndpoint": "127.0.0.1:9000" + }, + "gcp": { + "email": , + "privateKey": , + "endpoint": "127.0.0.1:9000" + }, + "kmip" { + "endpoint": "127.0.0.1:9000" + } + } + + Add TLS options for the ``aws``, ``azure``, ``gcp``, and + ``kmip`` providers to use the following options: + + - ``tlsCAFile`` (or equivalent) set to `ca.pem`_. This MAY be configured system-wide. + +4. Create a ``ClientEncryption`` object named ``client_encryption_invalid_hostname`` with the following KMS providers: + + .. code:: javascript + + { + "aws": { + "accessKeyId": , + "secretAccessKey": + }, + "azure": { + "tenantId": , + "clientId": , + "clientSecret": , + "identityPlatformEndpoint": "127.0.0.1:9001" + }, + "gcp": { + "email": , + "privateKey": , + "endpoint": "127.0.0.1:9001" + }, + "kmip" { + "endpoint": "127.0.0.1:9001" + } + } + + Add TLS options for the ``aws``, ``azure``, ``gcp``, and + ``kmip`` providers to use the following options: + + - ``tlsCAFile`` (or equivalent) set to `ca.pem`_. This MAY be configured system-wide. + +Case 1: AWS +``````````` + +Call `client_encryption_no_client_cert.createDataKey()` with "aws" as the provider and the +following masterKey: + +.. code:: javascript + + { + region: "us-east-1", + key: "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0" + endpoint: "127.0.0.1:9002" + } + +Expect an error indicating TLS handshake failed. + +Call `client_encryption_with_tls.createDataKey()` with "aws" as the provider and the +following masterKey: + +.. code:: javascript + + { + region: "us-east-1", + key: "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0" + endpoint: "127.0.0.1:9002" + } + +Expect an error from libmongocrypt with a message containing the string: "parse +error". This implies TLS handshake succeeded. + +Call `client_encryption_expired.createDataKey()` with "aws" as the provider and the +following masterKey: + +.. code:: javascript + + { + region: "us-east-1", + key: "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0" + endpoint: "127.0.0.1:9000" + } + +Expect an error indicating TLS handshake failed due to an expired certificate. + +Call `client_encryption_invalid_hostname.createDataKey()` with "aws" as the provider and the +following masterKey: + +.. code:: javascript + + { + region: "us-east-1", + key: "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0" + endpoint: "127.0.0.1:9001" + } + +Expect an error indicating TLS handshake failed due to an invalid hostname. + +Case 2: Azure +````````````` + +Call `client_encryption_no_client_cert.createDataKey()` with "azure" as the provider and the +following masterKey: + +.. code:: javascript + + { 'keyVaultEndpoint': 'doesnotexist.local', 'keyName': 'foo' } + +Expect an error indicating TLS handshake failed. + +Call `client_encryption_with_tls.createDataKey()` with "azure" as the provider +and the same masterKey. + +Expect an error from libmongocrypt with a message containing the string: "HTTP +status=404". This implies TLS handshake succeeded. + +Call `client_encryption_expired.createDataKey()` with "azure" as the provider and +the same masterKey. + +Expect an error indicating TLS handshake failed due to an expired certificate. + +Call `client_encryption_invalid_hostname.createDataKey()` with "azure" as the provider and +the same masterKey. + +Expect an error indicating TLS handshake failed due to an invalid hostname. + +Case 3: GCP +``````````` + +Call `client_encryption_no_client_cert.createDataKey()` with "gcp" as the provider and the +following masterKey: + +.. code:: javascript + + { 'projectId': 'foo', 'location': 'bar', 'keyRing': 'baz', 'keyName': 'foo' } + +Expect an error indicating TLS handshake failed. + +Call `client_encryption_with_tls.createDataKey()` with "gcp" as the provider and +the same masterKey. + +Expect an error from libmongocrypt with a message containing the string: "HTTP +status=404". This implies TLS handshake succeeded. + +Call `client_encryption_expired.createDataKey()` with "gcp" as the provider and +the same masterKey. + +Expect an error indicating TLS handshake failed due to an expired certificate. + +Call `client_encryption_invalid_hostname.createDataKey()` with "gcp" as the provider and +the same masterKey. + +Expect an error indicating TLS handshake failed due to an invalid hostname. + +Case 4: KMIP +```````````` + +Call `client_encryption_no_client_cert.createDataKey()` with "kmip" as the provider and the +following masterKey: + +.. code:: javascript + + { } + +Expect an error indicating TLS handshake failed. + +Call `client_encryption_with_tls.createDataKey()` with "kmip" as the provider +and the same masterKey. + +Expect success. + +Call `client_encryption_expired.createDataKey()` with "kmip" as the provider and +the same masterKey. + +Expect an error indicating TLS handshake failed due to an expired certificate. + +Call `client_encryption_invalid_hostname.createDataKey()` with "kmip" as the provider and +the same masterKey. + +Expect an error indicating TLS handshake failed due to an invalid hostname. + +12. Explicit Encryption +~~~~~~~~~~~~~~~~~~~~~~~ + +The Explicit Encryption tests require MongoDB server 6.0+. The tests must not run against a standalone. + +Before running each of the following test cases, perform the following Test Setup. + +Test Setup +`````````` + +Load the file `encryptedFields.json `_ as ``encryptedFields``. + +Load the file `key1-document.json `_ as ``key1Document``. + +Read the ``"_id"`` field of ``key1Document`` as ``key1ID``. + +Drop and create the collection ``db.explicit_encryption`` using ``encryptedFields`` as an option. See `FLE 2 CreateCollection() and Collection.Drop() `_. + +Drop and create the collection ``keyvault.datakeys``. + +Insert ``key1Document`` in ``keyvault.datakeys`` with majority write concern. + +Create a MongoClient named ``keyVaultClient``. + +Create a ClientEncryption object named ``clientEncryption`` with these options: + +.. code:: typescript + + ClientEncryptionOpts { + keyVaultClient: ; + keyVaultNamespace: "keyvault.datakeys"; + kmsProviders: { "local": { "key": } } + } + +Create a MongoClient named ``encryptedClient`` with these ``AutoEncryptionOpts``: + +.. code:: typescript + + AutoEncryptionOpts { + keyVaultNamespace: "keyvault.datakeys"; + kmsProviders: { "local": { "key": } } + bypassQueryAnalysis: true + } + + +Case 1: can insert encrypted indexed and find +````````````````````````````````````````````` + +Use ``clientEncryption`` to encrypt the value "encrypted indexed value" with these ``EncryptOpts``: + +.. code:: typescript + + class EncryptOpts { + keyId : + algorithm: "Indexed", + contentionFactor: 0 + } + +Store the result in ``insertPayload``. + +Use ``encryptedClient`` to insert the document ``{ "encryptedIndexed": }`` into ``db.explicit_encryption``. + +Use ``clientEncryption`` to encrypt the value "encrypted indexed value" with these ``EncryptOpts``: + +.. code:: typescript + + class EncryptOpts { + keyId : + algorithm: "Indexed", + queryType: "equality", + contentionFactor: 0 + } + +Store the result in ``findPayload``. + +Use ``encryptedClient`` to run a "find" operation on the ``db.explicit_encryption`` collection with the filter ``{ "encryptedIndexed": }``. + +Assert one document is returned containing the field ``{ "encryptedIndexed": "encrypted indexed value" }``. + +Case 2: can insert encrypted indexed and find with non-zero contention +``````````````````````````````````````````````````````````````````````` + +Use ``clientEncryption`` to encrypt the value "encrypted indexed value" with these ``EncryptOpts``: + +.. code:: typescript + + class EncryptOpts { + keyId : + algorithm: "Indexed", + contentionFactor: 10 + } + +Store the result in ``insertPayload``. + +Use ``encryptedClient`` to insert the document ``{ "encryptedIndexed": }`` into ``db.explicit_encryption``. + +Repeat the above steps 10 times to insert 10 total documents. The ``insertPayload`` must be regenerated each iteration. + +Use ``clientEncryption`` to encrypt the value "encrypted indexed value" with these ``EncryptOpts``: + +.. code:: typescript + + class EncryptOpts { + keyId : + algorithm: "Indexed", + queryType: "equality", + contentionFactor: 0 + } + +Store the result in ``findPayload``. + +Use ``encryptedClient`` to run a "find" operation on the ``db.explicit_encryption`` collection with the filter ``{ "encryptedIndexed": }``. + +Assert less than 10 documents are returned. 0 documents may be returned. Assert each returned document contains the field ``{ "encryptedIndexed": "encrypted indexed value" }``. + +Use ``clientEncryption`` to encrypt the value "encrypted indexed value" with these ``EncryptOpts``: + +.. code:: typescript + + class EncryptOpts { + keyId : + algorithm: "Indexed", + queryType: "equality", + contentionFactor: 10 + } + +Store the result in ``findPayload2``. + +Use ``encryptedClient`` to run a "find" operation on the ``db.explicit_encryption`` collection with the filter ``{ "encryptedIndexed": }``. + +Assert 10 documents are returned. Assert each returned document contains the field ``{ "encryptedIndexed": "encrypted indexed value" }``. + +Case 3: can insert encrypted unindexed +`````````````````````````````````````` + +Use ``clientEncryption`` to encrypt the value "encrypted unindexed value" with these ``EncryptOpts``: + +.. code:: typescript + + class EncryptOpts { + keyId : + algorithm: "Unindexed" + } + +Store the result in ``insertPayload``. + +Use ``encryptedClient`` to insert the document ``{ "_id": 1, "encryptedUnindexed": }`` into ``db.explicit_encryption``. + +Use ``encryptedClient`` to run a "find" operation on the ``db.explicit_encryption`` collection with the filter ``{ "_id": 1 }``. + +Assert one document is returned containing the field ``{ "encryptedUnindexed": "encrypted unindexed value" }``. + +Case 4: can roundtrip encrypted indexed +``````````````````````````````````````` + +Use ``clientEncryption`` to encrypt the value "encrypted indexed value" with these ``EncryptOpts``: + +.. code:: typescript + + class EncryptOpts { + keyId : + algorithm: "Indexed", + contentionFactor: 0 + } + +Store the result in ``payload``. + +Use ``clientEncryption`` to decrypt ``payload``. Assert the returned value equals "encrypted indexed value". + +Case 5: can roundtrip encrypted unindexed +````````````````````````````````````````` + +Use ``clientEncryption`` to encrypt the value "encrypted unindexed value" with these ``EncryptOpts``: + +.. code:: typescript + + class EncryptOpts { + keyId : + algorithm: "Unindexed", + } + +Store the result in ``payload``. + +Use ``clientEncryption`` to decrypt ``payload``. Assert the returned value equals "encrypted unindexed value". + +13. Unique Index on keyAltNames +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The following setup must occur before running each of the following test cases. + +Setup +````` + +1. Create a ``MongoClient`` object (referred to as ``client``). + +2. Using ``client``, drop the collection ``keyvault.datakeys``. + +3. Using ``client``, create a unique index on ``keyAltNames`` with a partial index filter for only documents where ``keyAltNames`` exists using writeConcern "majority". + +The command should be equivalent to: + +.. code:: typescript + + db.runCommand( + { + createIndexes: "datakeys", + indexes: [ + { + name: "keyAltNames_1", + key: { "keyAltNames": 1 }, + unique: true, + partialFilterExpression: { keyAltNames: { $exists: true } } + } + ], + writeConcern: { w: "majority" } + } + ) + +4. Create a ``ClientEncryption`` object (referred to as ``client_encryption``) with ``client`` set as the ``keyVaultClient``. + +5. Using ``client_encryption``, create a data key with a ``local`` KMS provider and the keyAltName "def". + +Case 1: createDataKey() +``````````````````````` + +1. Use ``client_encryption`` to create a new local data key with a keyAltName "abc" and assert the operation does not fail. + +2. Repeat Step 1 and assert the operation fails due to a duplicate key server error (error code 11000). + +3. Use ``client_encryption`` to create a new local data key with a keyAltName "def" and assert the operation fails due to a duplicate key server error (error code 11000). + +Case 2: addKeyAltName() +``````````````````````` + +1. Use ``client_encryption`` to create a new local data key and assert the operation does not fail. + +2. Use ``client_encryption`` to add a keyAltName "abc" to the key created in Step 1 and assert the operation does not fail. + +3. Repeat Step 2, assert the operation does not fail, and assert the returned key document contains the keyAltName "abc" added in Step 2. + +4. Use ``client_encryption`` to add a keyAltName "def" to the key created in Step 1 and assert the operation fails due to a duplicate key server error (error code 11000). + +5. Use ``client_encryption`` to add a keyAltName "def" to the existing key, assert the operation does not fail, and assert the returned key document contains the keyAltName "def" added during Setup. + +14. Decryption Events +~~~~~~~~~~~~~~~~~~~~~ + +Before running each of the following test cases, perform the following Test Setup. + +Test Setup +`````````` + +Create a MongoClient named ``setupClient``. + +Drop and create the collection ``db.decryption_events``. + +Create a ClientEncryption object named ``clientEncryption`` with these options: + +.. code:: typescript + + ClientEncryptionOpts { + keyVaultClient: , + keyVaultNamespace: "keyvault.datakeys", + kmsProviders: { "local": { "key": } } + } + +Create a data key with the "local" KMS provider. Storing the result in a variable named ``keyID``. + +Use ``clientEncryption`` to encrypt the string "hello" with the following ``EncryptOpts``: + +.. code:: typescript + + EncryptOpts { + keyId: , + algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + +Store the result in a variable named ``ciphertext``. + +Copy ``ciphertext`` into a variable named ``malformedCiphertext``. Change the +last byte to a different value. This will produce an invalid HMAC tag. + +Create a MongoClient named ``encryptedClient`` with these ``AutoEncryptionOpts``: + +.. code:: typescript + + AutoEncryptionOpts { + keyVaultNamespace: "keyvault.datakeys"; + kmsProviders: { "local": { "key": } } + } + +Configure ``encryptedClient`` with "retryReads=false". +Register a listener for CommandSucceeded events on ``encryptedClient``. +The listener must store the most recent ``CommandSucceededEvent`` reply for the "aggregate" command. +The listener must store the most recent ``CommandFailedEvent`` error for the "aggregate" command. + +Case 1: Command Error +````````````````````` + +Use ``setupClient`` to configure the following failpoint: + +.. code:: typescript + + { + "configureFailPoint": "failCommand", + "mode": { + "times": 1 + }, + "data": { + "errorCode": 123, + "failCommands": [ + "aggregate" + ] + } + } + +Use ``encryptedClient`` to run an aggregate on ``db.decryption_events``. + +Expect an exception to be thrown from the command error. Expect a ``CommandFailedEvent``. + +Case 2: Network Error +````````````````````` + +Use ``setupClient`` to configure the following failpoint: + +.. code:: typescript + + { + "configureFailPoint": "failCommand", + "mode": { + "times": 1 + }, + "data": { + "errorCode": 123, + "closeConnection": true, + "failCommands": [ + "aggregate" + ] + } + } + +Use ``encryptedClient`` to run an aggregate on ``db.decryption_events``. + +Expect an exception to be thrown from the network error. Expect a ``CommandFailedEvent``. + +Case 3: Decrypt Error +````````````````````` + +Use ``encryptedClient`` to insert the document ``{ "encrypted": }`` into ``db.decryption_events``. + +Use ``encryptedClient`` to run an aggregate on ``db.decryption_events`` with an empty pipeline. + +Expect an exception to be thrown from the decryption error. +Expect a ``CommandSucceededEvent``. Expect the ``CommandSucceededEvent.reply`` to contain BSON binary for the field ``cursor.firstBatch.encrypted``. + +Case 4: Decrypt Success +``````````````````````` + +Use ``encryptedClient`` to insert the document ``{ "encrypted": }`` into ``db.decryption_events``. + +Use ``encryptedClient`` to run an aggregate on ``db.decryption_events`` with an empty pipeline. + +Expect no exception. +Expect a ``CommandSucceededEvent``. Expect the ``CommandSucceededEvent.reply`` to contain BSON binary for the field ``cursor.firstBatch.encrypted``. + + +15. On-demand AWS Credentials +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +These tests require valid AWS credentials. Refer: `Automatic AWS Credentials`_. + +For these cases, create a ClientEncryption_ object :math:`C` with the following +options: + +.. code-block:: typescript + + ClientEncryptionOpts { + keyVaultClient: , + keyVaultNamespace: "keyvault.datakeys", + kmsProviders: { "aws": {} }, + } + +Case 1: Failure +``````````````` + +Do not run this test case in an environment where AWS credentials are available +(e.g. via environment variables or a metadata URL). (Refer: +`Obtaining credentials for AWS `_) + +Attempt to create a datakey with :math:`C` using the ``"aws"`` KMS provider. +Expect this to fail due to a lack of KMS provider credentials. + +Case 2: Success +``````````````` + +For this test case, the environment variables ``AWS_ACCESS_KEY_ID`` and +``AWS_SECRET_ACCESS_KEY`` must be defined and set to a valid set of AWS +credentials. + +Use the client encryption to create a datakey using the ``"aws"`` KMS provider. +This should successfully load and use the AWS credentials that were defined in +the environment. + +.. _Automatic AWS Credentials: ../client-side-encryption.rst#automatic-aws-credentials +.. _ClientEncryption: ../client-side-encryption.rst#clientencryption +.. _auth-aws: ../../auth/auth.rst#obtaining-credentials + +16. Rewrap +~~~~~~~~~~ + +Case 1: Rewrap with separate ClientEncryption +````````````````````````````````````````````` + +When the following test case requests setting ``masterKey``, use the following values based on the KMS provider: + +For "aws": + +.. code:: javascript + + { + "region": "us-east-1", + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0" + } + +For "azure": + +.. code:: javascript + + { + "keyVaultEndpoint": "key-vault-csfle.vault.azure.net", + "keyName": "key-name-csfle" + } + +For "gcp": + +.. code:: javascript + + { + "projectId": "devprod-drivers", + "location": "global", + "keyRing": "key-ring-csfle", + "keyName": "key-name-csfle" + } + +For "kmip": + +.. code:: javascript + + {} + +For "local", do not set a masterKey document. + +Run the following test case for each pair of KMS providers (referred to as ``srcProvider`` and ``dstProvider``). +Include pairs where ``srcProvider`` equals ``dstProvider``. + +1. Drop the collection ``keyvault.datakeys``. + +2. Create a ``ClientEncryption`` object named ``clientEncryption1`` with these options: + + .. code:: typescript + + ClientEncryptionOpts { + keyVaultClient: ; + keyVaultNamespace: "keyvault.datakeys"; + kmsProviders: + } + +3. Call ``clientEncryption1.createDataKey`` with ``srcProvider`` and these options: + + .. code:: typescript + + class DataKeyOpts { + masterKey: + } + + Store the return value in ``keyID``. + +4. Call ``clientEncryption1.encrypt`` with the value "test" and these options: + + .. code:: typescript + + class EncryptOpts { + keyId : keyID, + algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + + Store the return value in ``ciphertext``. + +5. Create a ``ClientEncryption`` object named ``clientEncryption2`` with these options: + + .. code:: typescript + + ClientEncryptionOpts { + keyVaultClient: ; + keyVaultNamespace: "keyvault.datakeys"; + kmsProviders: + } + +6. Call ``clientEncryption2.rewrapManyDataKey`` with an empty ``filter`` and these options: + + .. code:: typescript + + class RewrapManyDataKeyOpts { + provider: dstProvider + masterKey: + } + + Assert that the returned ``RewrapManyDataKeyResult.bulkWriteResult.modifiedCount`` is 1. + +7. Call ``clientEncryption1.decrypt`` with the ``ciphertext``. Assert the return value is "test". + +8. Call ``clientEncryption2.decrypt`` with the ``ciphertext``. Assert the return value is "test". + + +17. On-demand GCP Credentials +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Refer: `Automatic GCP Credentials`_. + +For these cases, create a ClientEncryption_ object :math:`C` with the following +options: + +.. code-block:: typescript + + ClientEncryptionOpts { + keyVaultClient: , + keyVaultNamespace: "keyvault.datakeys", + kmsProviders: { "gcp": {} }, + } + +Case 1: Failure +``````````````` + +Do not run this test case in an environment with a GCP service account is +attached (e.g. any `GCE equivalent runtime +`_). This may be run in an AWS EC2 instance. + +Attempt to create a datakey with :math:`C` using the ``"gcp"`` KMS provider and +following ``DataKeyOpts``: + +.. code-block:: typescript + + class DataKeyOpts { + masterKey: { + "projectId": "devprod-drivers", + "location": "global", + "keyRing": "key-ring-csfle", + "keyName": "key-name-csfle" + } + } + +Expect the attempt to obtain ``"gcp"`` credentials from the environment to fail. + +Case 2: Success +``````````````` + +This test case must run in a Google Compute Engine (GCE) Virtual Machine with a +service account attached. See `drivers-evergreen-tools/.evergreen/csfle/gcpkms +`_ +for scripts to create a GCE instance for testing. The Evergreen task SHOULD set a +``batchtime`` of 14 days to reduce how often this test case runs. + +Attempt to create a datakey with :math:`C` using the ``"gcp"`` KMS provider and +following ``DataKeyOpts``: + +.. code-block:: typescript + + class DataKeyOpts { + masterKey: { + "projectId": "devprod-drivers", + "location": "global", + "keyRing": "key-ring-csfle", + "keyName": "key-name-csfle" + } + } + +This should successfully load and use the GCP credentials of the service account +attached to the virtual machine. + +Expect the key to be successfully created. + +.. _Automatic GCP Credentials: ../client-side-encryption.rst#automatic-gcp-credentials + + +18. Azure IMDS Credentials +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Refer: `Automatic Azure Credentials `_ + +.. _auto-azure: ../client-side-encryption.rst#obtaining-an-access-token-for-azure-key-vault + +The test cases for IMDS communication are specially designed to not require an +Azure environment, while still exercising the core of the functionality. The +design of these test cases encourages an implementation to separate the concerns +of IMDS communication from the logic of KMS key manipulation. The purpose of +these test cases is to ensure drivers will behave appropriately regardless of +the behavior of the IMDS server. + +For these IMDS credentials tests, a simple stand-in IMDS-imitating HTTP server +is available in drivers-evergreen-tools, at ``.evergreen/csfle/fake_azure.py``. +``fake_azure.py`` is a very simple ``bottle.py`` application. For the easiest +use, it is recommended to execute it through ``bottle.py`` (which is a sibling +file in the same directory):: + + python .evergreen/csfle/bottle.py fake_azure:imds + +This will run the ``imds`` Bottle application defined in the ``fake_azure`` +Python module. ``bottle.py`` accepts additional command line arguments to +control the bind host and TCP port (use ``--help`` for more information). + +For each test case, follow the process for obtaining the token as outlined in +the `automatic Azure credentials section `_ with the following +changes: + +1. Instead of the standard IMDS TCP endpoint of `169.254.169.254:80`, + communicate with the running ``fake_azure`` HTTP server. + +2. For each test case, the behavior of the server may be controlled by attaching + an additional HTTP header to the sent request: ``X-MongoDB-HTTP-TestParams``. + + +Case 1: Success +``````````````` + +Do not set an ``X-MongoDB-HTTP-TestParams`` header. + +Upon receiving a response from ``fake_azure``, the driver must decode the +following information: + +1. HTTP status will be ``200 Okay``. +2. The HTTP body will be a valid JSON string. +3. The access token will be the string ``"magic-cookie"``. +4. The expiry duration of the token will be seventy seconds. +5. The token will have a resource of ``"https://vault.azure.net"`` + + +Case 2: Empty JSON +`````````````````` + +This case addresses a server returning valid JSON with invalid content. + +Set ``X-MongoDB-HTTP-TestParams`` to ``case=empty-json``. + +Upon receiving a response: + +1. HTTP status will be ``200 Okay`` +2. The HTTP body will be a valid JSON string. +3. There will be no access token, expiry duration, or resource. + +The test case should ensure that this error condition is handled gracefully. + + +Case 3: Bad JSON +```````````````` + +This case addresses a server returning malformed JSON. + +Set ``X-MongoDB-HTTP-TestParams`` to ``case=bad-json``. + +Upon receiving a response: + +1. HTTP status will be ``200 Okay`` +2. The response body will contain a malformed JSON string. + +The test case should ensure that this error condition is handled gracefully. + + +Case 4: HTTP 404 +```````````````` + +This case addresses a server returning a "Not Found" response. This is +documented to occur spuriously within an Azure environment. + +Set ``X-MongoDB-HTTP-TestParams`` to ``case=404``. + +Upon receiving a response: + +1. HTTP status will be ``404 Not Found``. +2. The response body is unspecified. + +The test case should ensure that this error condition is handled gracefully. + + +Case 5: HTTP 500 +```````````````` + +This case addresses an IMDS server reporting an internal error. This is +documented to occur spuriously within an Azure environment. + +Set ``X-MongoDB-HTTP-TestParams`` to ``case=500``. + +Upon receiving a response: + +1. HTTP status code will be ``500``. +2. The response body is unspecified. + +The test case should ensure that this error condition is handled gracefully. + + +Case 6: Slow Response +````````````````````` + +This case addresses an IMDS server responding very slowly. Drivers should not +halt the application waiting on a peer to communicate. + +Set ``X-MongoDB-HTTP-TestParams`` to ``case=slow``. + +The HTTP response from the ``fake_azure`` server will take at least 1000 seconds +to complete. The request should fail with a timeout. + +19. Azure IMDS Credentials Integration Test +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Refer: `Automatic Azure Credentials `_ + +.. _auto-azure: ../client-side-encryption.rst#obtaining-an-access-token-for-azure-key-vault + +For these cases, create a ClientEncryption_ object :math:`C` with the following +options: + +.. code-block:: typescript + + ClientEncryptionOpts { + keyVaultClient: , + keyVaultNamespace: "keyvault.datakeys", + kmsProviders: { "azure": {} }, + } + +Case 1: Failure +``````````````` + +Do not run this test case in an Azure environment with an attached identity. +This may be run in an AWS EC2 instance. + +Attempt to create a datakey with :math:`C` using the ``"azure"`` KMS provider and +following ``DataKeyOpts``: + +.. code-block:: typescript + + class DataKeyOpts { + masterKey: { + "keyVaultEndpoint": "https://keyvault-drivers-2411.vault.azure.net/keys/", + "keyName": "KEY-NAME" + } + } + +Expect the attempt to obtain ``"azure"`` credentials from the environment to fail. + +Case 2: Success +``````````````` + +This test case must run in an Azure environment with an attached identity. +See `drivers-evergreen-tools/.evergreen/csfle/azurekms +`_ +for scripts to create a Azure instance for testing. The Evergreen task SHOULD set a +``batchtime`` of 14 days to reduce how often this test case runs. + +Attempt to create a datakey with :math:`C` using the ``"azure"`` KMS provider and +following ``DataKeyOpts``: + +.. code-block:: typescript + + class DataKeyOpts { + masterKey: { + "keyVaultEndpoint": "https://keyvault-drivers-2411.vault.azure.net/keys/", + "keyName": "KEY-NAME" + } + } + +This should successfully load and use the Azure credentials of the service account +attached to the virtual machine. + +Expect the key to be successfully created. diff --git a/src/test/spec/json/client-side-encryption/legacy/aggregate.json b/src/test/spec/json/client-side-encryption/legacy/aggregate.json new file mode 100644 index 000000000..7de725b71 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/aggregate.json @@ -0,0 +1,390 @@ +{ + "runOn": [ + { + "minServerVersion": "4.1.10" + } + ], + "database_name": "default", + "collection_name": "default", + "data": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + } + ], + "json_schema": { + "properties": { + "encrypted_w_altname": { + "encrypt": { + "keyId": "/altname", + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "random": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string_equivalent": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + }, + "key_vault_data": [ + { + "status": 1, + "_id": { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + }, + "masterKey": { + "provider": "aws", + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "region": "us-east-1" + }, + "updateDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyMaterial": { + "$binary": { + "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyAltNames": [ + "altname", + "another_altname" + ] + } + ], + "tests": [ + { + "description": "Aggregate with deterministic encryption", + "skipReason": "SERVER-39395", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "aggregate", + "arguments": { + "pipeline": [ + { + "$match": { + "encrypted_string": "457-55-5642" + } + } + ] + }, + "result": [ + { + "_id": 1, + "encrypted_string": "string0" + } + ] + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "default" + } + }, + "command_name": "listCollections" + } + }, + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "aggregate": "default", + "pipeline": [ + { + "$match": { + "encrypted_string": "457-55-5642" + } + } + ] + }, + "command_name": "aggregate" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + } + ] + } + } + }, + { + "description": "Aggregate with empty pipeline", + "skipReason": "SERVER-40829 hides agg support behind enableTestCommands flag.", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "aggregate", + "arguments": { + "pipeline": [] + }, + "result": [ + { + "_id": 1, + "encrypted_string": "string0" + } + ] + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "default" + } + }, + "command_name": "listCollections" + } + }, + { + "command_started_event": { + "command": { + "aggregate": "default", + "pipeline": [], + "cursor": {} + }, + "command_name": "aggregate" + } + }, + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + } + ] + } + } + }, + { + "description": "Aggregate should fail with random encryption", + "skipReason": "SERVER-39395", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "aggregate", + "arguments": { + "pipeline": [ + { + "$match": { + "random": "abc" + } + } + ] + }, + "result": { + "errorContains": "Cannot query on fields encrypted with the randomized encryption" + } + } + ] + }, + { + "description": "Database aggregate should fail", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "aggregate", + "object": "database", + "arguments": { + "pipeline": [ + { + "$currentOp": { + "allUsers": false, + "idleConnections": false, + "localOps": true + } + }, + { + "$match": { + "command.aggregate": { + "$eq": 1 + } + } + }, + { + "$project": { + "command": 1 + } + }, + { + "$project": { + "command.lsid": 0 + } + } + ] + }, + "result": { + "errorContains": "non-collection command not supported for auto encryption: aggregate" + } + } + ] + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/aggregate.yml b/src/test/spec/json/client-side-encryption/legacy/aggregate.yml new file mode 100644 index 000000000..64ad5efa6 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/aggregate.yml @@ -0,0 +1,120 @@ +runOn: + - minServerVersion: "4.1.10" +database_name: &database_name "default" +collection_name: &collection_name "default" + +data: + - &doc0_encrypted { _id: 1, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==', 'subType': '06'}} } +json_schema: {'properties': {'encrypted_w_altname': {'encrypt': {'keyId': '/altname', 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'random': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string_equivalent': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} +key_vault_data: [{'status': 1, '_id': {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}, 'masterKey': {'provider': 'aws', 'key': 'arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0', 'region': 'us-east-1'}, 'updateDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyMaterial': {'$binary': {'base64': 'AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO', 'subType': '00'}}, 'creationDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyAltNames': ['altname', 'another_altname']}] + +tests: + - description: "Aggregate with deterministic encryption" + skipReason: "SERVER-39395" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: aggregate + arguments: + pipeline: + - { $match: { encrypted_string: "457-55-5642" } } + result: + - &doc0 { _id: 1, encrypted_string: "string0" } + expectations: + # Auto encryption will request the collection info. + - command_started_event: + command: + listCollections: 1 + filter: + name: *collection_name + command_name: listCollections + # Then key is fetched from the key vault. + - command_started_event: + command: + find: datakeys + filter: {"$or": [{"_id": {"$in": [ {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}} ] }}, {"keyAltNames": {"$in": []}}]} + $db: keyvault + readConcern: { level: "majority" } + command_name: find + - command_started_event: + command: + aggregate: *collection_name + pipeline: + - { $match: { encrypted_string: "457-55-5642" } } + command_name: aggregate + outcome: + collection: + # Outcome is checked using a separate MongoClient without auto encryption. + data: + - *doc0_encrypted + - description: "Aggregate with empty pipeline" + skipReason: "SERVER-40829 hides agg support behind enableTestCommands flag." + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: aggregate + arguments: + pipeline: [] + result: + - { _id: 1, encrypted_string: "string0" } + expectations: + # Auto encryption will request the collection info. + - command_started_event: + command: + listCollections: 1 + filter: + name: *collection_name + command_name: listCollections + - command_started_event: + command: + aggregate: *collection_name + pipeline: [] + cursor: {} + command_name: aggregate + # Needs to fetch key when decrypting results + # Then key is fetched from the key vault. + - command_started_event: + command: + find: datakeys + filter: {"$or": [{"_id": {"$in": [ {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}} ] }}, {"keyAltNames": {"$in": []}}]} + $db: keyvault + readConcern: { level: "majority" } + command_name: find + outcome: + collection: + # Outcome is checked using a separate MongoClient without auto encryption. + data: + - *doc0_encrypted + - description: "Aggregate should fail with random encryption" + skipReason: "SERVER-39395" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: aggregate + arguments: + pipeline: + - { $match: { random: "abc" } } + result: + errorContains: "Cannot query on fields encrypted with the randomized encryption" + - description: "Database aggregate should fail" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: aggregate + object: database + arguments: + pipeline: + - $currentOp: { allUsers: false, idleConnections: false, localOps: true } + - $match: { command.aggregate: { $eq: 1 } } + - $project: { command: 1 } + - $project: { command.lsid: 0 } + result: + errorContains: "non-collection command not supported for auto encryption: aggregate" \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/awsTemporary.json b/src/test/spec/json/client-side-encryption/legacy/awsTemporary.json new file mode 100644 index 000000000..10eb85fee --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/awsTemporary.json @@ -0,0 +1,225 @@ +{ + "runOn": [ + { + "minServerVersion": "4.1.10" + } + ], + "database_name": "default", + "collection_name": "default", + "data": [], + "json_schema": { + "properties": { + "encrypted_w_altname": { + "encrypt": { + "keyId": "/altname", + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "random": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string_equivalent": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + }, + "key_vault_data": [ + { + "status": 1, + "_id": { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + }, + "masterKey": { + "provider": "aws", + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "region": "us-east-1" + }, + "updateDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyMaterial": { + "$binary": { + "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyAltNames": [ + "altname", + "another_altname" + ] + } + ], + "tests": [ + { + "description": "Insert a document with auto encryption using the AWS provider with temporary credentials", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "awsTemporary": {} + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encrypted_string": "string0" + } + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "default" + } + }, + "command_name": "listCollections" + } + }, + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault" + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "insert": "default", + "documents": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + } + ], + "ordered": true + }, + "command_name": "insert" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + } + ] + } + } + }, + { + "description": "Insert with invalid temporary credentials", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "awsTemporaryNoSessionToken": {} + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encrypted_string": "string0" + } + }, + "result": { + "errorContains": "security token" + } + } + ] + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/awsTemporary.yml b/src/test/spec/json/client-side-encryption/legacy/awsTemporary.yml new file mode 100644 index 000000000..cc787530a --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/awsTemporary.yml @@ -0,0 +1,57 @@ +runOn: + - minServerVersion: "4.1.10" +database_name: &database_name "default" +collection_name: &collection_name "default" + +data: [] +json_schema: {'properties': {'encrypted_w_altname': {'encrypt': {'keyId': '/altname', 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'random': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string_equivalent': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} +key_vault_data: [{'status': 1, '_id': {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}, 'masterKey': {'provider': 'aws', 'key': 'arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0', 'region': 'us-east-1'}, 'updateDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyMaterial': {'$binary': {'base64': 'AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO', 'subType': '00'}}, 'creationDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyAltNames': ['altname', 'another_altname']}] + +tests: + - description: "Insert a document with auto encryption using the AWS provider with temporary credentials" + clientOptions: + autoEncryptOpts: + kmsProviders: + awsTemporary: {} + operations: + - name: insertOne + arguments: + document: &doc0 { _id: 1, encrypted_string: "string0" } + expectations: + # Auto encryption will request the collection info. + - command_started_event: + command: + listCollections: 1 + filter: + name: *collection_name + command_name: listCollections + # Then key is fetched from the key vault. + - command_started_event: + command: + find: datakeys + filter: { $or: [ { _id: { $in: [ {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}} ] } }, { keyAltNames: { $in: [] } } ] } + $db: keyvault + command_name: find + - command_started_event: + command: + insert: *collection_name + documents: + - &doc0_encrypted { _id: 1, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==', 'subType': '06'}} } + ordered: true + command_name: insert + outcome: + collection: + # Outcome is checked using a separate MongoClient without auto encryption. + data: + - *doc0_encrypted + - description: "Insert with invalid temporary credentials" + clientOptions: + autoEncryptOpts: + kmsProviders: + awsTemporaryNoSessionToken: {} + operations: + - name: insertOne + arguments: + document: *doc0 + result: + errorContains: "security token" \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/azureKMS.json b/src/test/spec/json/client-side-encryption/legacy/azureKMS.json new file mode 100644 index 000000000..afecf40b0 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/azureKMS.json @@ -0,0 +1,224 @@ +{ + "runOn": [ + { + "minServerVersion": "4.1.10" + } + ], + "database_name": "default", + "collection_name": "default", + "data": [], + "json_schema": { + "properties": { + "encrypted_string_aws": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "encrypted_string_azure": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AZURE+AAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "encrypted_string_gcp": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "GCP+AAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "encrypted_string_local": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "encrypted_string_kmip": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "dBHpr8aITfeBQ15grpbLpQ==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + }, + "key_vault_data": [ + { + "_id": { + "$binary": { + "base64": "AZURE+AAAAAAAAAAAAAAAA==", + "subType": "04" + } + }, + "keyMaterial": { + "$binary": { + "base64": "n+HWZ0ZSVOYA3cvQgP7inN4JSXfOH85IngmeQxRpQHjCCcqT3IFqEWNlrsVHiz3AELimHhX4HKqOLWMUeSIT6emUDDoQX9BAv8DR1+E1w4nGs/NyEneac78EYFkK3JysrFDOgl2ypCCTKAypkn9CkAx1if4cfgQE93LW4kczcyHdGiH36CIxrCDGv1UzAvERN5Qa47DVwsM6a+hWsF2AAAJVnF0wYLLJU07TuRHdMrrphPWXZsFgyV+lRqJ7DDpReKNO8nMPLV/mHqHBHGPGQiRdb9NoJo8CvokGz4+KE8oLwzKf6V24dtwZmRkrsDV4iOhvROAzz+Euo1ypSkL3mw==", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1601573901680" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1601573901680" + } + }, + "status": { + "$numberInt": "0" + }, + "masterKey": { + "provider": "azure", + "keyVaultEndpoint": "key-vault-csfle.vault.azure.net", + "keyName": "key-name-csfle" + }, + "keyAltNames": [ + "altname", + "azure_altname" + ] + } + ], + "tests": [ + { + "description": "Insert a document with auto encryption using Azure KMS provider", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "azure": {} + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encrypted_string_azure": "string0" + } + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "default" + } + }, + "command_name": "listCollections" + } + }, + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "AZURE+AAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault" + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "insert": "default", + "documents": [ + { + "_id": 1, + "encrypted_string_azure": { + "$binary": { + "base64": "AQGVERPgAAAAAAAAAAAAAAAC5DbBSwPwfSlBrDtRuglvNvCXD1KzDuCKY2P+4bRFtHDjpTOE2XuytPAUaAbXf1orsPq59PVZmsbTZbt2CB8qaQ==", + "subType": "06" + } + } + } + ], + "ordered": true + }, + "command_name": "insert" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "encrypted_string_azure": { + "$binary": { + "base64": "AQGVERPgAAAAAAAAAAAAAAAC5DbBSwPwfSlBrDtRuglvNvCXD1KzDuCKY2P+4bRFtHDjpTOE2XuytPAUaAbXf1orsPq59PVZmsbTZbt2CB8qaQ==", + "subType": "06" + } + } + } + ] + } + } + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/azureKMS.yml b/src/test/spec/json/client-side-encryption/legacy/azureKMS.yml new file mode 100644 index 000000000..b3c1f6947 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/azureKMS.yml @@ -0,0 +1,46 @@ +runOn: + - minServerVersion: "4.1.10" +database_name: &database_name "default" +collection_name: &collection_name "default" + +data: [] +json_schema: {'properties': {'encrypted_string_aws': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'encrypted_string_azure': {'encrypt': {'keyId': [{'$binary': {'base64': 'AZURE+AAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'encrypted_string_gcp': {'encrypt': {'keyId': [{'$binary': {'base64': 'GCP+AAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'encrypted_string_local': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'encrypted_string_kmip': {'encrypt': {'keyId': [{'$binary': {'base64': 'dBHpr8aITfeBQ15grpbLpQ==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} +key_vault_data: [{'_id': {'$binary': {'base64': 'AZURE+AAAAAAAAAAAAAAAA==', 'subType': '04'}}, 'keyMaterial': {'$binary': {'base64': 'n+HWZ0ZSVOYA3cvQgP7inN4JSXfOH85IngmeQxRpQHjCCcqT3IFqEWNlrsVHiz3AELimHhX4HKqOLWMUeSIT6emUDDoQX9BAv8DR1+E1w4nGs/NyEneac78EYFkK3JysrFDOgl2ypCCTKAypkn9CkAx1if4cfgQE93LW4kczcyHdGiH36CIxrCDGv1UzAvERN5Qa47DVwsM6a+hWsF2AAAJVnF0wYLLJU07TuRHdMrrphPWXZsFgyV+lRqJ7DDpReKNO8nMPLV/mHqHBHGPGQiRdb9NoJo8CvokGz4+KE8oLwzKf6V24dtwZmRkrsDV4iOhvROAzz+Euo1ypSkL3mw==', 'subType': '00'}}, 'creationDate': {'$date': {'$numberLong': '1601573901680'}}, 'updateDate': {'$date': {'$numberLong': '1601573901680'}}, 'status': {'$numberInt': '0'}, 'masterKey': {'provider': 'azure', 'keyVaultEndpoint': 'key-vault-csfle.vault.azure.net', 'keyName': 'key-name-csfle'}, 'keyAltNames': ['altname', 'azure_altname']}] + +tests: + - description: "Insert a document with auto encryption using Azure KMS provider" + clientOptions: + autoEncryptOpts: + kmsProviders: + azure: {} + operations: + - name: insertOne + arguments: + document: &doc0 { _id: 1, encrypted_string_azure: "string0" } + expectations: + # Auto encryption will request the collection info. + - command_started_event: + command: + listCollections: 1 + filter: + name: *collection_name + command_name: listCollections + # Then key is fetched from the key vault. + - command_started_event: + command: + find: datakeys + filter: { $or: [ { _id: { $in: [ {'$binary': {'base64': 'AZURE+AAAAAAAAAAAAAAAA==', 'subType': '04'}} ] } }, { keyAltNames: { $in: [] } } ] } + $db: keyvault + command_name: find + - command_started_event: + command: + insert: *collection_name + documents: + - &doc0_encrypted { _id: 1, encrypted_string_azure: {'$binary': {'base64': 'AQGVERPgAAAAAAAAAAAAAAAC5DbBSwPwfSlBrDtRuglvNvCXD1KzDuCKY2P+4bRFtHDjpTOE2XuytPAUaAbXf1orsPq59PVZmsbTZbt2CB8qaQ==', 'subType': '06'}} } + ordered: true + command_name: insert + outcome: + collection: + # Outcome is checked using a separate MongoClient without auto encryption. + data: + - *doc0_encrypted \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/badQueries.json b/src/test/spec/json/client-side-encryption/legacy/badQueries.json new file mode 100644 index 000000000..4968307ba --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/badQueries.json @@ -0,0 +1,1446 @@ +{ + "runOn": [ + { + "minServerVersion": "4.1.10" + } + ], + "database_name": "default", + "collection_name": "default", + "data": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + }, + { + "_id": 2, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", + "subType": "06" + } + } + } + ], + "json_schema": { + "properties": { + "encrypted_w_altname": { + "encrypt": { + "keyId": "/altname", + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "random": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string_equivalent": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + }, + "key_vault_data": [ + { + "status": 1, + "_id": { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + }, + "masterKey": { + "provider": "aws", + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "region": "us-east-1" + }, + "updateDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyMaterial": { + "$binary": { + "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyAltNames": [ + "altname", + "another_altname" + ] + } + ], + "tests": [ + { + "description": "$text unconditionally fails", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "find", + "arguments": { + "filter": { + "$text": { + "$search": "search text" + } + } + }, + "result": { + "errorContains": "Unsupported match expression operator for encryption" + } + } + ] + }, + { + "description": "$where unconditionally fails", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "find", + "arguments": { + "filter": { + "$where": { + "$code": "function() { return true }" + } + } + }, + "result": { + "errorContains": "Unsupported match expression operator for encryption" + } + } + ] + }, + { + "description": "$bit operators succeed on unencrypted, error on encrypted", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "find", + "arguments": { + "filter": { + "unencrypted": { + "$bitsAllClear": 35 + } + } + }, + "result": [] + }, + { + "name": "find", + "arguments": { + "filter": { + "encrypted_string": { + "$bitsAllClear": 35 + } + } + }, + "result": { + "errorContains": "Invalid match expression operator on encrypted field" + } + }, + { + "name": "find", + "arguments": { + "filter": { + "unencrypted": { + "$bitsAllSet": 35 + } + } + }, + "result": [] + }, + { + "name": "find", + "arguments": { + "filter": { + "encrypted_string": { + "$bitsAllSet": 35 + } + } + }, + "result": { + "errorContains": "Invalid match expression operator on encrypted field" + } + }, + { + "name": "find", + "arguments": { + "filter": { + "unencrypted": { + "$bitsAnyClear": 35 + } + } + }, + "result": [] + }, + { + "name": "find", + "arguments": { + "filter": { + "encrypted_string": { + "$bitsAnyClear": 35 + } + } + }, + "result": { + "errorContains": "Invalid match expression operator on encrypted field" + } + }, + { + "name": "find", + "arguments": { + "filter": { + "unencrypted": { + "$bitsAnySet": 35 + } + } + }, + "result": [] + }, + { + "name": "find", + "arguments": { + "filter": { + "encrypted_string": { + "$bitsAnySet": 35 + } + } + }, + "result": { + "errorContains": "Invalid match expression operator on encrypted field" + } + } + ] + }, + { + "description": "geo operators succeed on unencrypted, error on encrypted", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "find", + "arguments": { + "filter": { + "unencrypted": { + "$near": [ + 0, + 0 + ] + } + } + }, + "result": { + "errorContains": "unable to find index" + } + }, + { + "name": "find", + "arguments": { + "filter": { + "encrypted_string": { + "$near": [ + 0, + 0 + ] + } + } + }, + "result": { + "errorContains": "Invalid match expression operator on encrypted field" + } + }, + { + "name": "find", + "arguments": { + "filter": { + "unencrypted": { + "$nearSphere": [ + 0, + 0 + ] + } + } + }, + "result": { + "errorContains": "unable to find index" + } + }, + { + "name": "find", + "arguments": { + "filter": { + "encrypted_string": { + "$nearSphere": [ + 0, + 0 + ] + } + } + }, + "result": { + "errorContains": "Invalid match expression operator on encrypted field" + } + }, + { + "name": "find", + "arguments": { + "filter": { + "unencrypted": { + "$geoIntersects": { + "$geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 0, + 0 + ], + [ + 1, + 0 + ], + [ + 1, + 1 + ], + [ + 0, + 0 + ] + ] + ] + } + } + } + } + }, + "result": [] + }, + { + "name": "find", + "arguments": { + "filter": { + "encrypted_string": { + "$geoIntersects": { + "$geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 0, + 0 + ], + [ + 1, + 0 + ], + [ + 1, + 1 + ], + [ + 0, + 0 + ] + ] + ] + } + } + } + } + }, + "result": { + "errorContains": "Invalid match expression operator on encrypted field" + } + }, + { + "name": "find", + "arguments": { + "filter": { + "unencrypted": { + "$geoWithin": { + "$geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 0, + 0 + ], + [ + 1, + 0 + ], + [ + 1, + 1 + ], + [ + 0, + 0 + ] + ] + ] + } + } + } + } + }, + "result": [] + }, + { + "name": "find", + "arguments": { + "filter": { + "encrypted_string": { + "$geoWithin": { + "$geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + 0, + 0 + ], + [ + 1, + 0 + ], + [ + 1, + 1 + ], + [ + 0, + 0 + ] + ] + ] + } + } + } + } + }, + "result": { + "errorContains": "Invalid match expression operator on encrypted field" + } + } + ] + }, + { + "description": "inequality operators succeed on unencrypted, error on encrypted", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "find", + "arguments": { + "filter": { + "unencrypted": { + "$gt": 1 + } + } + }, + "result": [] + }, + { + "name": "find", + "arguments": { + "filter": { + "encrypted_string": { + "$gt": 1 + } + } + }, + "result": { + "errorContains": "Invalid match expression operator on encrypted field" + } + }, + { + "name": "find", + "arguments": { + "filter": { + "unencrypted": { + "$lt": 1 + } + } + }, + "result": [] + }, + { + "name": "find", + "arguments": { + "filter": { + "encrypted_string": { + "$lt": 1 + } + } + }, + "result": { + "errorContains": "Invalid match expression operator on encrypted field" + } + }, + { + "name": "find", + "arguments": { + "filter": { + "unencrypted": { + "$gte": 1 + } + } + }, + "result": [] + }, + { + "name": "find", + "arguments": { + "filter": { + "encrypted_string": { + "$gte": 1 + } + } + }, + "result": { + "errorContains": "Invalid match expression operator on encrypted field" + } + }, + { + "name": "find", + "arguments": { + "filter": { + "unencrypted": { + "$lte": 1 + } + } + }, + "result": [] + }, + { + "name": "find", + "arguments": { + "filter": { + "encrypted_string": { + "$lte": 1 + } + } + }, + "result": { + "errorContains": "Invalid match expression operator on encrypted field" + } + } + ] + }, + { + "description": "other misc operators succeed on unencrypted, error on encrypted", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "find", + "arguments": { + "filter": { + "unencrypted": { + "$mod": [ + 3, + 1 + ] + } + } + }, + "result": [] + }, + { + "name": "find", + "arguments": { + "filter": { + "encrypted_string": { + "$mod": [ + 3, + 1 + ] + } + } + }, + "result": { + "errorContains": "Invalid match expression operator on encrypted field" + } + }, + { + "name": "find", + "arguments": { + "filter": { + "unencrypted": { + "$regex": "pattern", + "$options": "" + } + } + }, + "result": [] + }, + { + "name": "find", + "arguments": { + "filter": { + "encrypted_string": { + "$regex": "pattern", + "$options": "" + } + } + }, + "result": { + "errorContains": "Invalid match expression operator on encrypted field" + } + }, + { + "name": "find", + "arguments": { + "filter": { + "unencrypted": { + "$size": 2 + } + } + }, + "result": [] + }, + { + "name": "find", + "arguments": { + "filter": { + "encrypted_string": { + "$size": 2 + } + } + }, + "result": { + "errorContains": "Invalid match expression operator on encrypted field" + } + }, + { + "name": "find", + "arguments": { + "filter": { + "unencrypted": { + "$type": 2 + } + } + }, + "result": [] + }, + { + "name": "find", + "arguments": { + "filter": { + "encrypted_string": { + "$type": 2 + } + } + }, + "result": { + "errorContains": "Invalid match expression operator on encrypted field" + } + }, + { + "name": "find", + "arguments": { + "filter": { + "unencrypted": { + "$eq": null + } + } + }, + "result": [ + { + "_id": 1, + "encrypted_string": "string0" + }, + { + "_id": 2, + "encrypted_string": "string1" + } + ] + }, + { + "name": "find", + "arguments": { + "filter": { + "encrypted_string": { + "$eq": null + } + } + }, + "result": { + "errorContains": "Illegal equality to null predicate for encrypted field" + } + }, + { + "name": "find", + "arguments": { + "filter": { + "unencrypted": { + "$in": [ + null + ] + } + } + }, + "result": [ + { + "_id": 1, + "encrypted_string": "string0" + }, + { + "_id": 2, + "encrypted_string": "string1" + } + ] + }, + { + "name": "find", + "arguments": { + "filter": { + "encrypted_string": { + "$in": [ + null + ] + } + } + }, + "result": { + "errorContains": "Illegal equality to null inside $in against an encrypted field" + } + } + ] + }, + { + "description": "$addToSet succeeds on unencrypted, error on encrypted", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "updateOne", + "arguments": { + "filter": {}, + "update": { + "$addToSet": { + "unencrypted": [ + "a" + ] + } + } + }, + "result": { + "matchedCount": 1, + "modifiedCount": 1, + "upsertedCount": 0 + } + }, + { + "name": "updateOne", + "arguments": { + "filter": {}, + "update": { + "$addToSet": { + "encrypted_string": [ + "a" + ] + } + } + }, + "result": { + "errorContains": "$addToSet not allowed on encrypted values" + } + } + ] + }, + { + "description": "$inc succeeds on unencrypted, error on encrypted", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "updateOne", + "arguments": { + "filter": {}, + "update": { + "$inc": { + "unencrypted": 1 + } + } + }, + "result": { + "matchedCount": 1, + "modifiedCount": 1, + "upsertedCount": 0 + } + }, + { + "name": "updateOne", + "arguments": { + "filter": {}, + "update": { + "$inc": { + "encrypted_string": 1 + } + } + }, + "result": { + "errorContains": "$inc and $mul not allowed on encrypted values" + } + } + ] + }, + { + "description": "$mul succeeds on unencrypted, error on encrypted", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "updateOne", + "arguments": { + "filter": {}, + "update": { + "$mul": { + "unencrypted": 1 + } + } + }, + "result": { + "matchedCount": 1, + "modifiedCount": 1, + "upsertedCount": 0 + } + }, + { + "name": "updateOne", + "arguments": { + "filter": {}, + "update": { + "$mul": { + "encrypted_string": 1 + } + } + }, + "result": { + "errorContains": "$inc and $mul not allowed on encrypted values" + } + } + ] + }, + { + "description": "$max succeeds on unencrypted, error on encrypted", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "updateOne", + "arguments": { + "filter": {}, + "update": { + "$max": { + "unencrypted": 1 + } + } + }, + "result": { + "matchedCount": 1, + "modifiedCount": 1, + "upsertedCount": 0 + } + }, + { + "name": "updateOne", + "arguments": { + "filter": {}, + "update": { + "$max": { + "encrypted_string": 1 + } + } + }, + "result": { + "errorContains": "$max and $min not allowed on encrypted values" + } + } + ] + }, + { + "description": "$min succeeds on unencrypted, error on encrypted", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "updateOne", + "arguments": { + "filter": {}, + "update": { + "$min": { + "unencrypted": 1 + } + } + }, + "result": { + "matchedCount": 1, + "modifiedCount": 1, + "upsertedCount": 0 + } + }, + { + "name": "updateOne", + "arguments": { + "filter": {}, + "update": { + "$min": { + "encrypted_string": 1 + } + } + }, + "result": { + "errorContains": "$max and $min not allowed on encrypted values" + } + } + ] + }, + { + "description": "$currentDate succeeds on unencrypted, error on encrypted", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "updateOne", + "arguments": { + "filter": {}, + "update": { + "$currentDate": { + "unencrypted": true + } + } + }, + "result": { + "matchedCount": 1, + "modifiedCount": 1, + "upsertedCount": 0 + } + }, + { + "name": "updateOne", + "arguments": { + "filter": {}, + "update": { + "$currentDate": { + "encrypted_string": true + } + } + }, + "result": { + "errorContains": "$currentDate not allowed on encrypted values" + } + } + ] + }, + { + "description": "$pop succeeds on unencrypted, error on encrypted", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "updateOne", + "arguments": { + "filter": {}, + "update": { + "$pop": { + "unencrypted": 1 + } + } + }, + "result": { + "matchedCount": 1, + "modifiedCount": 0, + "upsertedCount": 0 + } + }, + { + "name": "updateOne", + "arguments": { + "filter": {}, + "update": { + "$pop": { + "encrypted_string": 1 + } + } + }, + "result": { + "errorContains": "$pop not allowed on encrypted values" + } + } + ] + }, + { + "description": "$pull succeeds on unencrypted, error on encrypted", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "updateOne", + "arguments": { + "filter": {}, + "update": { + "$pull": { + "unencrypted": 1 + } + } + }, + "result": { + "matchedCount": 1, + "modifiedCount": 0, + "upsertedCount": 0 + } + }, + { + "name": "updateOne", + "arguments": { + "filter": {}, + "update": { + "$pull": { + "encrypted_string": 1 + } + } + }, + "result": { + "errorContains": "$pull not allowed on encrypted values" + } + } + ] + }, + { + "description": "$pullAll succeeds on unencrypted, error on encrypted", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "updateOne", + "arguments": { + "filter": {}, + "update": { + "$pullAll": { + "unencrypted": [ + 1 + ] + } + } + }, + "result": { + "matchedCount": 1, + "modifiedCount": 0, + "upsertedCount": 0 + } + }, + { + "name": "updateOne", + "arguments": { + "filter": {}, + "update": { + "$pullAll": { + "encrypted_string": [ + 1 + ] + } + } + }, + "result": { + "errorContains": "$pullAll not allowed on encrypted values" + } + } + ] + }, + { + "description": "$push succeeds on unencrypted, error on encrypted", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "updateOne", + "arguments": { + "filter": {}, + "update": { + "$push": { + "unencrypted": 1 + } + } + }, + "result": { + "matchedCount": 1, + "modifiedCount": 1, + "upsertedCount": 0 + } + }, + { + "name": "updateOne", + "arguments": { + "filter": {}, + "update": { + "$push": { + "encrypted_string": 1 + } + } + }, + "result": { + "errorContains": "$push not allowed on encrypted values" + } + } + ] + }, + { + "description": "array filters on encrypted fields does not error in mongocryptd, but errors in mongod", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "updateOne", + "arguments": { + "filter": {}, + "update": { + "$set": { + "encrypted_string.$[i].x": 1 + } + }, + "arrayFilters": [ + { + "i.x": 1 + } + ] + }, + "result": { + "errorContains": "Array update operations not allowed on encrypted values" + } + } + ] + }, + { + "description": "positional operator succeeds on unencrypted, errors on encrypted", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "updateOne", + "arguments": { + "filter": { + "unencrypted": 1 + }, + "update": { + "$set": { + "unencrypted.$": 1 + } + } + }, + "result": { + "matchedCount": 0, + "modifiedCount": 0, + "upsertedCount": 0 + } + }, + { + "name": "updateOne", + "arguments": { + "filter": { + "encrypted_string": "abc" + }, + "update": { + "$set": { + "encrypted_string.$": "abc" + } + } + }, + "result": { + "errorContains": "Cannot encrypt fields below '$' positional update operator" + } + } + ] + }, + { + "description": "an update that would produce an array on an encrypted field errors", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "updateOne", + "arguments": { + "filter": {}, + "update": { + "$set": { + "encrypted_string": [ + 1, + 2 + ] + } + } + }, + "result": { + "errorContains": "Cannot encrypt element of type" + } + } + ] + }, + { + "description": "an insert with encrypted field on _id errors", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + }, + "schemaMap": { + "default.default": { + "properties": { + "_id": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + } + } + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1 + } + }, + "result": { + "errorContains": "Invalid schema containing the 'encrypt' keyword." + } + } + ] + }, + { + "description": "an insert with an array value for an encrypted field fails", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "encrypted_string": [ + "123", + "456" + ] + } + }, + "result": { + "errorContains": "Cannot encrypt element of type" + } + } + ] + }, + { + "description": "an insert with a Timestamp(0,0) value in the top-level fails", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "random": { + "$timestamp": { + "t": 0, + "i": 0 + } + } + } + }, + "result": { + "errorContains": "A command that inserts cannot supply Timestamp(0, 0) for an encrypted" + } + } + ] + }, + { + "description": "distinct with the key referring to a field where the keyID is a JSON Pointer errors", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "distinct", + "arguments": { + "filter": {}, + "fieldName": "encrypted_w_altname" + }, + "result": { + "errorContains": "The distinct key is not allowed to be marked for encryption with a non-UUID keyId" + } + } + ] + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/badQueries.yml b/src/test/spec/json/client-side-encryption/legacy/badQueries.yml new file mode 100644 index 000000000..893622c4c --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/badQueries.yml @@ -0,0 +1,536 @@ +runOn: + - minServerVersion: "4.1.10" +database_name: &database_name "default" +collection_name: &collection_name "default" + +data: + - &doc0_encrypted { _id: 1, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==', 'subType': '06'}} } + - &doc1_encrypted { _id: 2, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==', 'subType': '06'}} } +json_schema: {'properties': {'encrypted_w_altname': {'encrypt': {'keyId': '/altname', 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'random': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string_equivalent': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} +key_vault_data: [{'status': 1, '_id': {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}, 'masterKey': {'provider': 'aws', 'key': 'arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0', 'region': 'us-east-1'}, 'updateDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyMaterial': {'$binary': {'base64': 'AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO', 'subType': '00'}}, 'creationDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyAltNames': ['altname', 'another_altname']}] + +# TODO: I could see an argument against having these tests of mongocryptd as part +# of driver tests. When mongocryptd introduces support for these operators, these +# tests will fail. But it's also easy enough to remove these tests when that happens. + +tests: + - description: "$text unconditionally fails" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: find + arguments: + filter: + { $text: { $search: "search text" } } + result: + errorContains: "Unsupported match expression operator for encryption" + - description: "$where unconditionally fails" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: find + arguments: + filter: + { $where: { $code: "function() { return true }" } } + result: + errorContains: "Unsupported match expression operator for encryption" + - description: "$bit operators succeed on unencrypted, error on encrypted" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: find + arguments: + filter: { unencrypted: { $bitsAllClear: 35 }} + result: [] + - name: find + arguments: + filter: { encrypted_string: { $bitsAllClear: 35 }} + result: + errorContains: "Invalid match expression operator on encrypted field" + - name: find + arguments: + filter: { unencrypted: { $bitsAllSet: 35 }} + result: [] + - name: find + arguments: + filter: { encrypted_string: { $bitsAllSet: 35 }} + result: + errorContains: "Invalid match expression operator on encrypted field" + - name: find + arguments: + filter: { unencrypted: { $bitsAnyClear: 35 }} + result: [] + - name: find + arguments: + filter: { encrypted_string: { $bitsAnyClear: 35 }} + result: + errorContains: "Invalid match expression operator on encrypted field" + - name: find + arguments: + filter: { unencrypted: { $bitsAnySet: 35 }} + result: [] + - name: find + arguments: + filter: { encrypted_string: { $bitsAnySet: 35 }} + result: + errorContains: "Invalid match expression operator on encrypted field" + - description: "geo operators succeed on unencrypted, error on encrypted" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: find + arguments: + filter: { unencrypted: { $near: [0,0] }} + result: + # Still an error because no geo index, but from mongod - not mongocryptd. + errorContains: "unable to find index" + - name: find + arguments: + filter: { encrypted_string: { $near: [0,0] }} + result: + errorContains: "Invalid match expression operator on encrypted field" + - name: find + arguments: + filter: { unencrypted: { $nearSphere: [0,0] }} + result: + # Still an error because no geo index, but from mongod - not mongocryptd. + errorContains: "unable to find index" + - name: find + arguments: + filter: { encrypted_string: { $nearSphere: [0,0] }} + result: + errorContains: "Invalid match expression operator on encrypted field" + - name: find + arguments: + filter: { unencrypted: { $geoIntersects: { $geometry: { type: "Polygon", coordinates: [[ [0,0], [1,0], [1,1], [0,0] ]] }} }} + result: [] + - name: find + arguments: + filter: { encrypted_string: { $geoIntersects: { $geometry: { type: "Polygon", coordinates: [[ [0,0], [1,0], [1,1], [0,0] ]] }} }} + result: + errorContains: "Invalid match expression operator on encrypted field" + - name: find + arguments: + filter: { unencrypted: { $geoWithin: { $geometry: { type: "Polygon", coordinates: [[ [0,0], [1,0], [1,1], [0,0] ]] }} }} + result: [] + - name: find + arguments: + filter: { encrypted_string: { $geoWithin: { $geometry: { type: "Polygon", coordinates: [[ [0,0], [1,0], [1,1], [0,0] ]] }} }} + result: + errorContains: "Invalid match expression operator on encrypted field" + - description: "inequality operators succeed on unencrypted, error on encrypted" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: find + arguments: + filter: { unencrypted: { $gt: 1 }} + result: [] + - name: find + arguments: + filter: { encrypted_string: { $gt: 1 }} + result: + errorContains: "Invalid match expression operator on encrypted field" + - name: find + arguments: + filter: { unencrypted: { $lt: 1 }} + result: [] + - name: find + arguments: + filter: { encrypted_string: { $lt: 1 }} + result: + errorContains: "Invalid match expression operator on encrypted field" + - name: find + arguments: + filter: { unencrypted: { $gte: 1 }} + result: [] + - name: find + arguments: + filter: { encrypted_string: { $gte: 1 }} + result: + errorContains: "Invalid match expression operator on encrypted field" + - name: find + arguments: + filter: { unencrypted: { $lte: 1 }} + result: [] + - name: find + arguments: + filter: { encrypted_string: { $lte: 1 }} + result: + errorContains: "Invalid match expression operator on encrypted field" + - description: "other misc operators succeed on unencrypted, error on encrypted" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: find + arguments: + filter: { unencrypted: { $mod: [3, 1] }} + result: [] + - name: find + arguments: + filter: { encrypted_string: { $mod: [3, 1] }} + result: + errorContains: "Invalid match expression operator on encrypted field" + - name: find + arguments: + filter: { unencrypted: { $regex: "pattern", $options: "" }} + result: [] + - name: find + arguments: + filter: { encrypted_string: { $regex: "pattern", $options: "" }} + result: + errorContains: "Invalid match expression operator on encrypted field" + - name: find + arguments: + filter: { unencrypted: { $size: 2 }} + result: [] + - name: find + arguments: + filter: { encrypted_string: { $size: 2 }} + result: + errorContains: "Invalid match expression operator on encrypted field" + - name: find + arguments: + filter: { unencrypted: { $type: 2 }} + result: [] + - name: find + arguments: + filter: { encrypted_string: { $type: 2 }} + result: + errorContains: "Invalid match expression operator on encrypted field" + - name: find + arguments: + filter: { unencrypted: { $eq: null }} + result: + - &doc0 { _id: 1, encrypted_string: "string0" } + - &doc1 { _id: 2, encrypted_string: "string1" } + - name: find + arguments: + filter: { encrypted_string: { $eq: null }} + result: + errorContains: "Illegal equality to null predicate for encrypted field" + - name: find + arguments: + filter: { unencrypted: { $in: [null] }} + result: + - *doc0 + - *doc1 + - name: find + arguments: + filter: { encrypted_string: { $in: [null] }} + result: + errorContains: "Illegal equality to null inside $in against an encrypted field" + - description: "$addToSet succeeds on unencrypted, error on encrypted" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: updateOne + arguments: + filter: { } + update: { $addToSet: { "unencrypted": ["a"]}} + result: + matchedCount: 1 + modifiedCount: 1 + upsertedCount: 0 + - name: updateOne + arguments: + filter: { } + update: { $addToSet: { "encrypted_string": ["a"]}} + result: + errorContains: "$addToSet not allowed on encrypted values" + - description: "$inc succeeds on unencrypted, error on encrypted" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: updateOne + arguments: + filter: { } + update: { $inc: { "unencrypted": 1}} + result: + matchedCount: 1 + modifiedCount: 1 + upsertedCount: 0 + - name: updateOne + arguments: + filter: { } + update: { $inc: { "encrypted_string": 1}} + result: + errorContains: "$inc and $mul not allowed on encrypted values" + - description: "$mul succeeds on unencrypted, error on encrypted" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: updateOne + arguments: + filter: { } + update: { $mul: { "unencrypted": 1}} + result: + matchedCount: 1 + modifiedCount: 1 + upsertedCount: 0 + - name: updateOne + arguments: + filter: { } + update: { $mul: { "encrypted_string": 1}} + result: + errorContains: "$inc and $mul not allowed on encrypted values" + - description: "$max succeeds on unencrypted, error on encrypted" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: updateOne + arguments: + filter: { } + update: { $max: { "unencrypted": 1}} + result: + matchedCount: 1 + modifiedCount: 1 + upsertedCount: 0 + - name: updateOne + arguments: + filter: { } + update: { $max: { "encrypted_string": 1}} + result: + errorContains: "$max and $min not allowed on encrypted values" + - description: "$min succeeds on unencrypted, error on encrypted" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: updateOne + arguments: + filter: { } + update: { $min: { "unencrypted": 1}} + result: + matchedCount: 1 + modifiedCount: 1 + upsertedCount: 0 + - name: updateOne + arguments: + filter: { } + update: { $min: { "encrypted_string": 1}} + result: + errorContains: "$max and $min not allowed on encrypted values" + - description: "$currentDate succeeds on unencrypted, error on encrypted" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: updateOne + arguments: + filter: { } + update: { $currentDate: { "unencrypted": true}} + result: + matchedCount: 1 + modifiedCount: 1 + upsertedCount: 0 + - name: updateOne + arguments: + filter: { } + update: { $currentDate: { "encrypted_string": true }} + result: + errorContains: "$currentDate not allowed on encrypted values" + - description: "$pop succeeds on unencrypted, error on encrypted" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: updateOne + arguments: + filter: { } + update: { $pop: { "unencrypted": 1}} + result: + matchedCount: 1 + modifiedCount: 0 + upsertedCount: 0 + - name: updateOne + arguments: + filter: { } + update: { $pop: { "encrypted_string": 1 }} + result: + errorContains: "$pop not allowed on encrypted values" + - description: "$pull succeeds on unencrypted, error on encrypted" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: updateOne + arguments: + filter: { } + update: { $pull: { "unencrypted": 1}} + result: + matchedCount: 1 + modifiedCount: 0 + upsertedCount: 0 + - name: updateOne + arguments: + filter: { } + update: { $pull: { "encrypted_string": 1 }} + result: + errorContains: "$pull not allowed on encrypted values" + - description: "$pullAll succeeds on unencrypted, error on encrypted" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: updateOne + arguments: + filter: { } + update: { $pullAll: { "unencrypted": [1] }} + result: + matchedCount: 1 + modifiedCount: 0 + upsertedCount: 0 + - name: updateOne + arguments: + filter: { } + update: { $pullAll: { "encrypted_string": [1] }} + result: + errorContains: "$pullAll not allowed on encrypted values" + - description: "$push succeeds on unencrypted, error on encrypted" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: updateOne + arguments: + filter: { } + update: { $push: { "unencrypted": 1}} + result: + matchedCount: 1 + modifiedCount: 1 + upsertedCount: 0 + - name: updateOne + arguments: + filter: { } + update: { $push: { "encrypted_string": 1 }} + result: + errorContains: "$push not allowed on encrypted values" + - description: "array filters on encrypted fields does not error in mongocryptd, but errors in mongod" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: updateOne + arguments: + filter: { } + update: { $set : { "encrypted_string.$[i].x": 1 }} + arrayFilters: [{ i.x: 1 }] + result: + errorContains: "Array update operations not allowed on encrypted values" + - description: "positional operator succeeds on unencrypted, errors on encrypted" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: updateOne + arguments: + filter: { "unencrypted": 1 } + update: { $set : { "unencrypted.$": 1 }} + result: + matchedCount: 0 + modifiedCount: 0 + upsertedCount: 0 + - name: updateOne + arguments: + filter: { "encrypted_string": "abc" } + update: { $set : { "encrypted_string.$": "abc" }} + result: + errorContains: "Cannot encrypt fields below '$' positional update operator" + - description: "an update that would produce an array on an encrypted field errors" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: updateOne + arguments: + filter: { } + update: { $set : { "encrypted_string": [1,2] }} + result: + # DRIVERS-2272: The expected error message changed in mongocryptd 6.0. Before it was: + # "Cannot encrypt element of type array because schema requires that type is one of: [ string ]" + # After it is: + # "Cannot encrypt element of type: array" + # Only check for the common prefix. + errorContains: "Cannot encrypt element of type" + - description: "an insert with encrypted field on _id errors" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + schemaMap: + "default.default": {'properties': {'_id': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}} + operations: + - name: insertOne + arguments: + document: { _id: 1 } + result: + errorContains: "Invalid schema containing the 'encrypt' keyword." + - description: "an insert with an array value for an encrypted field fails" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: insertOne + arguments: + document: { encrypted_string: [ "123", "456"] } + result: + # DRIVERS-2272: The expected error message changed in mongocryptd 6.0. Before it was: + # "Cannot encrypt element of type array because schema requires that type is one of: [ string ]" + # After it is: + # "Cannot encrypt element of type: array" + # Only check for the common prefix. + errorContains: "Cannot encrypt element of type" + - description: "an insert with a Timestamp(0,0) value in the top-level fails" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: insertOne + arguments: + document: { random: {"$timestamp": {"t": 0, "i": 0 }} } + result: + errorContains: "A command that inserts cannot supply Timestamp(0, 0) for an encrypted" + - description: "distinct with the key referring to a field where the keyID is a JSON Pointer errors" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: distinct + arguments: + filter: {} + fieldName: "encrypted_w_altname" + result: + errorContains: "The distinct key is not allowed to be marked for encryption with a non-UUID keyId" \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/badSchema.json b/src/test/spec/json/client-side-encryption/legacy/badSchema.json new file mode 100644 index 000000000..1fd0f8ed3 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/badSchema.json @@ -0,0 +1,254 @@ +{ + "runOn": [ + { + "minServerVersion": "4.1.10" + } + ], + "database_name": "default", + "collection_name": "default", + "data": [], + "key_vault_data": [ + { + "status": 1, + "_id": { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + }, + "masterKey": { + "provider": "aws", + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "region": "us-east-1" + }, + "updateDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyMaterial": { + "$binary": { + "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyAltNames": [ + "altname", + "another_altname" + ] + } + ], + "tests": [ + { + "description": "Schema with an encrypted field in an array", + "clientOptions": { + "autoEncryptOpts": { + "schemaMap": { + "default.default": { + "properties": { + "encrypted_string": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + } + }, + "bsonType": "array" + } + }, + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encrypted_string": "string0" + } + }, + "result": { + "errorContains": "Invalid schema" + } + } + ], + "outcome": { + "collection": { + "data": [] + } + } + }, + { + "description": "Schema without specifying parent object types", + "clientOptions": { + "autoEncryptOpts": { + "schemaMap": { + "default.default": { + "properties": { + "foo": { + "properties": { + "bar": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + } + } + } + } + } + }, + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encrypted_string": "string0" + } + }, + "result": { + "errorContains": "Invalid schema" + } + } + ], + "outcome": { + "collection": { + "data": [] + } + } + }, + { + "description": "Schema with siblings of encrypt document", + "clientOptions": { + "autoEncryptOpts": { + "schemaMap": { + "default.default": { + "properties": { + "encrypted_string": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + }, + "bsonType": "object" + } + } + } + }, + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encrypted_string": "string0" + } + }, + "result": { + "errorContains": "'encrypt' cannot be used in conjunction with 'bsonType'" + } + } + ], + "outcome": { + "collection": { + "data": [] + } + } + }, + { + "description": "Schema with logical keywords", + "clientOptions": { + "autoEncryptOpts": { + "schemaMap": { + "default.default": { + "anyOf": [ + { + "properties": { + "encrypted_string": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + } + } + } + ] + } + }, + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encrypted_string": "string0" + } + }, + "result": { + "errorContains": "Invalid schema" + } + } + ], + "outcome": { + "collection": { + "data": [] + } + } + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/badSchema.yml b/src/test/spec/json/client-side-encryption/legacy/badSchema.yml new file mode 100644 index 000000000..035774de5 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/badSchema.yml @@ -0,0 +1,73 @@ +runOn: + - minServerVersion: "4.1.10" +database_name: &database_name "default" +collection_name: &collection_name "default" + +data: [] +key_vault_data: [{'status': 1, '_id': {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}, 'masterKey': {'provider': 'aws', 'key': 'arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0', 'region': 'us-east-1'}, 'updateDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyMaterial': {'$binary': {'base64': 'AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO', 'subType': '00'}}, 'creationDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyAltNames': ['altname', 'another_altname']}] + +tests: + - description: "Schema with an encrypted field in an array" + clientOptions: + autoEncryptOpts: + schemaMap: + "default.default": {'properties': {'encrypted_string': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}}, 'bsonType': 'array'} + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: insertOne + arguments: + document: &doc0 { _id: 1, encrypted_string: "string0" } + result: + errorContains: "Invalid schema" + outcome: + collection: + data: [] + - description: "Schema without specifying parent object types" + clientOptions: + autoEncryptOpts: + schemaMap: + "default.default": {'properties': {'foo': {'properties': {'bar': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}}}}} + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: insertOne + arguments: + document: *doc0 + result: + errorContains: "Invalid schema" + outcome: + collection: + data: [] + - description: "Schema with siblings of encrypt document" + clientOptions: + autoEncryptOpts: + schemaMap: + "default.default": {'properties': {'encrypted_string': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}, 'bsonType': 'object'}}} + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: insertOne + arguments: + document: *doc0 + result: + errorContains: "'encrypt' cannot be used in conjunction with 'bsonType'" + outcome: + collection: + data: [] + - description: "Schema with logical keywords" + clientOptions: + autoEncryptOpts: + schemaMap: + "default.default": {'anyOf': [{'properties': {'encrypted_string': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}}}]} + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: insertOne + arguments: + document: *doc0 + result: + errorContains: "Invalid schema" + outcome: + collection: + data: [] \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/basic.json b/src/test/spec/json/client-side-encryption/legacy/basic.json new file mode 100644 index 000000000..3ed066f53 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/basic.json @@ -0,0 +1,350 @@ +{ + "runOn": [ + { + "minServerVersion": "4.1.10" + } + ], + "database_name": "default", + "collection_name": "default", + "data": [], + "json_schema": { + "properties": { + "encrypted_w_altname": { + "encrypt": { + "keyId": "/altname", + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "random": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string_equivalent": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + }, + "key_vault_data": [ + { + "status": 1, + "_id": { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + }, + "masterKey": { + "provider": "aws", + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "region": "us-east-1" + }, + "updateDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyMaterial": { + "$binary": { + "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyAltNames": [ + "altname", + "another_altname" + ] + } + ], + "tests": [ + { + "description": "Insert with deterministic encryption, then find it", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encrypted_string": "string0" + } + } + }, + { + "name": "find", + "arguments": { + "filter": { + "_id": 1 + } + }, + "result": [ + { + "_id": 1, + "encrypted_string": "string0" + } + ] + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "default" + } + }, + "command_name": "listCollections" + } + }, + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "insert": "default", + "documents": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + } + ], + "ordered": true + }, + "command_name": "insert" + } + }, + { + "command_started_event": { + "command": { + "find": "default", + "filter": { + "_id": 1 + } + }, + "command_name": "find" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + } + ] + } + } + }, + { + "description": "Insert with randomized encryption, then find it", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "random": "123" + } + } + }, + { + "name": "find", + "arguments": { + "filter": { + "_id": 1 + } + }, + "result": [ + { + "_id": 1, + "random": "123" + } + ] + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "default" + } + }, + "command_name": "listCollections" + } + }, + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "insert": "default", + "documents": [ + { + "_id": 1, + "random": { + "$$type": "binData" + } + } + ], + "ordered": true + }, + "command_name": "insert" + } + }, + { + "command_started_event": { + "command": { + "find": "default", + "filter": { + "_id": 1 + } + }, + "command_name": "find" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "random": { + "$$type": "binData" + } + } + ] + } + } + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/basic.yml b/src/test/spec/json/client-side-encryption/legacy/basic.yml new file mode 100644 index 000000000..dfbf5270c --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/basic.yml @@ -0,0 +1,102 @@ +runOn: + - minServerVersion: "4.1.10" +database_name: &database_name "default" +collection_name: &collection_name "default" + +data: [] +json_schema: {'properties': {'encrypted_w_altname': {'encrypt': {'keyId': '/altname', 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'random': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string_equivalent': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} +key_vault_data: [{'status': 1, '_id': {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}, 'masterKey': {'provider': 'aws', 'key': 'arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0', 'region': 'us-east-1'}, 'updateDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyMaterial': {'$binary': {'base64': 'AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO', 'subType': '00'}}, 'creationDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyAltNames': ['altname', 'another_altname']}] + +tests: + - description: "Insert with deterministic encryption, then find it" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: insertOne + arguments: + document: &doc0 { _id: 1, encrypted_string: "string0" } + - name: find + arguments: + filter: { _id: 1 } + result: [*doc0] + expectations: + # Auto encryption will request the collection info. + - command_started_event: + command: + listCollections: 1 + filter: + name: *collection_name + command_name: listCollections + # Then key is fetched from the key vault. + - command_started_event: + command: + find: datakeys + filter: {"$or": [{"_id": {"$in": [ {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}} ] }}, {"keyAltNames": {"$in": []}}]} + $db: keyvault + readConcern: { level: "majority" } + command_name: find + - command_started_event: + command: + insert: *collection_name + documents: + - &doc0_encrypted { _id: 1, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==', 'subType': '06'}} } + ordered: true + command_name: insert + - command_started_event: + command: + find: *collection_name + filter: { _id: 1 } + command_name: find + outcome: + collection: + # Outcome is checked using a separate MongoClient without auto encryption. + data: + - *doc0_encrypted + - description: "Insert with randomized encryption, then find it" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: insertOne + arguments: + document: &doc1 { _id: 1, random: "123" } + - name: find + arguments: + filter: { _id: 1 } + result: [*doc1] + expectations: + # Auto encryption will request the collection info. + - command_started_event: + command: + listCollections: 1 + filter: + name: *collection_name + command_name: listCollections + # Then key is fetched from the key vault. + - command_started_event: + command: + find: datakeys + filter: {"$or": [{"_id": {"$in": [ {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}} ] }}, {"keyAltNames": {"$in": []}}]} + $db: keyvault + readConcern: { level: "majority" } + command_name: find + - command_started_event: + command: + insert: *collection_name + documents: + - { _id: 1, random: { $$type: "binData" } } + ordered: true + command_name: insert + - command_started_event: + command: + find: *collection_name + filter: { _id: 1 } + command_name: find + outcome: + collection: + # Outcome is checked using a separate MongoClient without auto encryption. + data: + - { _id: 1, random: { $$type: "binData" } } \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/bulk.json b/src/test/spec/json/client-side-encryption/legacy/bulk.json new file mode 100644 index 000000000..1b62e5e8a --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/bulk.json @@ -0,0 +1,333 @@ +{ + "runOn": [ + { + "minServerVersion": "4.1.10" + } + ], + "database_name": "default", + "collection_name": "default", + "data": [], + "json_schema": { + "properties": { + "encrypted_w_altname": { + "encrypt": { + "keyId": "/altname", + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "random": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string_equivalent": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + }, + "key_vault_data": [ + { + "status": 1, + "_id": { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + }, + "masterKey": { + "provider": "aws", + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "region": "us-east-1" + }, + "updateDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyMaterial": { + "$binary": { + "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyAltNames": [ + "altname", + "another_altname" + ] + } + ], + "tests": [ + { + "description": "Bulk write with encryption", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "bulkWrite", + "arguments": { + "requests": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encrypted_string": "string0", + "random": "abc" + } + } + }, + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 2, + "encrypted_string": "string1" + } + } + }, + { + "name": "updateOne", + "arguments": { + "filter": { + "encrypted_string": "string0" + }, + "update": { + "$set": { + "encrypted_string": "string1" + } + } + } + }, + { + "name": "deleteOne", + "arguments": { + "filter": { + "$and": [ + { + "encrypted_string": "string1" + }, + { + "_id": 2 + } + ] + } + } + } + ], + "options": { + "ordered": true + } + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "default" + } + }, + "command_name": "listCollections" + } + }, + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "insert": "default", + "documents": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + }, + "random": { + "$$type": "binData" + } + }, + { + "_id": 2, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", + "subType": "06" + } + } + } + ], + "ordered": true + }, + "command_name": "insert" + } + }, + { + "command_started_event": { + "command": { + "update": "default", + "updates": [ + { + "q": { + "encrypted_string": { + "$eq": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + } + }, + "u": { + "$set": { + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", + "subType": "06" + } + } + } + } + } + ], + "ordered": true + }, + "command_name": "update" + } + }, + { + "command_started_event": { + "command": { + "delete": "default", + "deletes": [ + { + "q": { + "$and": [ + { + "encrypted_string": { + "$eq": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", + "subType": "06" + } + } + } + }, + { + "_id": { + "$eq": 2 + } + } + ] + }, + "limit": 1 + } + ], + "ordered": true + }, + "command_name": "delete" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", + "subType": "06" + } + }, + "random": { + "$$type": "binData" + } + } + ] + } + } + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/bulk.yml b/src/test/spec/json/client-side-encryption/legacy/bulk.yml new file mode 100644 index 000000000..824ccdaa1 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/bulk.yml @@ -0,0 +1,78 @@ +runOn: + - minServerVersion: "4.1.10" +database_name: &database_name "default" +collection_name: &collection_name "default" + +data: [] +json_schema: {'properties': {'encrypted_w_altname': {'encrypt': {'keyId': '/altname', 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'random': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string_equivalent': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} +key_vault_data: [{'status': 1, '_id': {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}, 'masterKey': {'provider': 'aws', 'key': 'arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0', 'region': 'us-east-1'}, 'updateDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyMaterial': {'$binary': {'base64': 'AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO', 'subType': '00'}}, 'creationDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyAltNames': ['altname', 'another_altname']}] + +tests: + - description: "Bulk write with encryption" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: bulkWrite + arguments: + requests: + - name: insertOne + arguments: + document: &doc0 { _id: 1, encrypted_string: "string0", random: "abc" } + - name: insertOne + arguments: + document: &doc1 { _id: 2, encrypted_string: "string1" } + - name: updateOne + arguments: + filter: { encrypted_string: "string0" } + update: { $set: { encrypted_string: "string1" } } + - name: deleteOne + arguments: + filter: { $and: [{ encrypted_string: "string1" }, { _id: 2 }]} + options: { ordered: true } + expectations: + # Auto encryption will request the collection info. + - command_started_event: + command: + listCollections: 1 + filter: + name: *collection_name + command_name: listCollections + # Then key is fetched from the key vault. + - command_started_event: + command: + find: datakeys + filter: {"$or": [{"_id": {"$in": [ {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}} ] }}, {"keyAltNames": {"$in": []}}]} + $db: keyvault + readConcern: { level: "majority" } + command_name: find + - command_started_event: + command: + insert: *collection_name + documents: + - &doc0_encrypted { _id: 1, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==', 'subType': '06'}}, random: { $$type: "binData" } } + - &doc1_encrypted { _id: 2, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==', 'subType': '06'}} } + ordered: true + command_name: insert + - command_started_event: + command: + update: *collection_name + updates: + - q: { encrypted_string: { $eq: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==', 'subType': '06'}} }} + u: {$set: { encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==', 'subType': '06'}} }} + ordered: true + command_name: update + - command_started_event: + command: + delete: *collection_name + deletes: + - q: { "$and": [ { "encrypted_string": { "$eq": {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==', 'subType': '06'}} }}, { "_id": { "$eq": 2 }} ] } + limit: 1 + ordered: true + command_name: delete + outcome: + collection: + # Outcome is checked using a separate MongoClient without auto encryption. + data: + - { _id: 1, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==', 'subType': '06'}}, random: { $$type: "binData" } } \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/bypassAutoEncryption.json b/src/test/spec/json/client-side-encryption/legacy/bypassAutoEncryption.json new file mode 100644 index 000000000..9d09cb3fa --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/bypassAutoEncryption.json @@ -0,0 +1,402 @@ +{ + "runOn": [ + { + "minServerVersion": "4.1.10" + } + ], + "database_name": "default", + "collection_name": "default", + "data": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + } + ], + "json_schema": { + "properties": { + "encrypted_w_altname": { + "encrypt": { + "keyId": "/altname", + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "random": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string_equivalent": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + }, + "key_vault_data": [ + { + "status": 1, + "_id": { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + }, + "masterKey": { + "provider": "aws", + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "region": "us-east-1" + }, + "updateDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyMaterial": { + "$binary": { + "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyAltNames": [ + "altname", + "another_altname" + ] + } + ], + "tests": [ + { + "description": "Insert with bypassAutoEncryption", + "clientOptions": { + "autoEncryptOpts": { + "bypassAutoEncryption": true, + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 2, + "encrypted_string": "string0" + }, + "bypassDocumentValidation": true + } + }, + { + "name": "find", + "arguments": { + "filter": {} + }, + "result": [ + { + "_id": 1, + "encrypted_string": "string0" + }, + { + "_id": 2, + "encrypted_string": "string0" + } + ] + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "insert": "default", + "documents": [ + { + "_id": 2, + "encrypted_string": "string0" + } + ], + "ordered": true + }, + "command_name": "insert" + } + }, + { + "command_started_event": { + "command": { + "find": "default", + "filter": {} + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + }, + { + "_id": 2, + "encrypted_string": "string0" + } + ] + } + } + }, + { + "description": "Insert with bypassAutoEncryption for local schema", + "clientOptions": { + "autoEncryptOpts": { + "schemaMap": { + "default.default": { + "properties": { + "encrypted_w_altname": { + "encrypt": { + "keyId": "/altname", + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "random": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string_equivalent": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + } + }, + "bypassAutoEncryption": true, + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 2, + "encrypted_string": "string0" + }, + "bypassDocumentValidation": true + } + }, + { + "name": "find", + "arguments": { + "filter": {} + }, + "result": [ + { + "_id": 1, + "encrypted_string": "string0" + }, + { + "_id": 2, + "encrypted_string": "string0" + } + ] + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "insert": "default", + "documents": [ + { + "_id": 2, + "encrypted_string": "string0" + } + ], + "ordered": true + }, + "command_name": "insert" + } + }, + { + "command_started_event": { + "command": { + "find": "default", + "filter": {} + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + }, + { + "_id": 2, + "encrypted_string": "string0" + } + ] + } + } + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/bypassAutoEncryption.yml b/src/test/spec/json/client-side-encryption/legacy/bypassAutoEncryption.yml new file mode 100644 index 000000000..7a7bf74e1 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/bypassAutoEncryption.yml @@ -0,0 +1,100 @@ +runOn: + - minServerVersion: "4.1.10" +database_name: &database_name "default" +collection_name: &collection_name "default" + +data: [{_id: 1, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==', 'subType': '06'}} }] +json_schema: {'properties': {'encrypted_w_altname': {'encrypt': {'keyId': '/altname', 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'random': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string_equivalent': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} +key_vault_data: [{'status': 1, '_id': {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}, 'masterKey': {'provider': 'aws', 'key': 'arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0', 'region': 'us-east-1'}, 'updateDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyMaterial': {'$binary': {'base64': 'AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO', 'subType': '00'}}, 'creationDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyAltNames': ['altname', 'another_altname']}] + +tests: + - description: "Insert with bypassAutoEncryption" + clientOptions: + autoEncryptOpts: + bypassAutoEncryption: true + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: insertOne + arguments: + document: { _id: 2, encrypted_string: "string0" } + bypassDocumentValidation: true + - name: find + arguments: + filter: { } + result: + - { _id: 1, encrypted_string: "string0" } + - { _id: 2, encrypted_string: "string0" } + expectations: + - command_started_event: + command: + insert: *collection_name + documents: + # No encryption. + - { _id: 2, encrypted_string: "string0" } + ordered: true + command_name: insert + - command_started_event: + command: + find: *collection_name + filter: { } + command_name: find + - command_started_event: + command: + find: datakeys + filter: {"$or": [{"_id": {"$in": [ {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}} ] }}, {"keyAltNames": {"$in": []}}]} + $db: keyvault + readConcern: { level: "majority" } + command_name: find + outcome: + collection: + # Outcome is checked using a separate MongoClient without auto encryption. + data: + - { _id: 1, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==', 'subType': '06'}} } + - { _id: 2, encrypted_string: "string0" } + - description: "Insert with bypassAutoEncryption for local schema" + clientOptions: + autoEncryptOpts: + schemaMap: + "default.default": {'properties': {'encrypted_w_altname': {'encrypt': {'keyId': '/altname', 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'random': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string_equivalent': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} + bypassAutoEncryption: true + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: insertOne + arguments: + document: { _id: 2, encrypted_string: "string0" } + bypassDocumentValidation: true + - name: find + arguments: + filter: { } + result: + - { _id: 1, encrypted_string: "string0" } + - { _id: 2, encrypted_string: "string0" } + expectations: + - command_started_event: + command: + insert: *collection_name + documents: + # No encryption. + - { _id: 2, encrypted_string: "string0" } + ordered: true + command_name: insert + - command_started_event: + command: + find: *collection_name + filter: { } + command_name: find + - command_started_event: + command: + find: datakeys + filter: {"$or": [{"_id": {"$in": [ {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}} ] }}, {"keyAltNames": {"$in": []}}]} + $db: keyvault + readConcern: { level: "majority" } + command_name: find + outcome: + collection: + # Outcome is checked using a separate MongoClient without auto encryption. + data: + - { _id: 1, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==', 'subType': '06'}} } + - { _id: 2, encrypted_string: "string0" } \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/bypassedCommand.json b/src/test/spec/json/client-side-encryption/legacy/bypassedCommand.json new file mode 100644 index 000000000..bd0b1c565 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/bypassedCommand.json @@ -0,0 +1,106 @@ +{ + "runOn": [ + { + "minServerVersion": "4.1.10" + } + ], + "database_name": "default", + "collection_name": "default", + "data": [], + "json_schema": {}, + "key_vault_data": [ + { + "status": 1, + "_id": { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + }, + "masterKey": { + "provider": "aws", + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "region": "us-east-1" + }, + "updateDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyMaterial": { + "$binary": { + "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyAltNames": [ + "altname", + "another_altname" + ] + } + ], + "tests": [ + { + "description": "ping is bypassed", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "runCommand", + "object": "database", + "command_name": "ping", + "arguments": { + "command": { + "ping": 1 + } + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "ping": 1 + }, + "command_name": "ping" + } + } + ] + }, + { + "description": "current op is not bypassed", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "runCommand", + "object": "database", + "command_name": "currentOp", + "arguments": { + "command": { + "currentOp": 1 + } + }, + "result": { + "errorContains": "command not supported for auto encryption: currentOp" + } + } + ] + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/bypassedCommand.yml b/src/test/spec/json/client-side-encryption/legacy/bypassedCommand.yml new file mode 100644 index 000000000..7057abd59 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/bypassedCommand.yml @@ -0,0 +1,42 @@ +runOn: + - minServerVersion: "4.1.10" +database_name: &database_name "default" +collection_name: &collection_name "default" + +data: [] +json_schema: {} +key_vault_data: [{'status': 1, '_id': {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}, 'masterKey': {'provider': 'aws', 'key': 'arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0', 'region': 'us-east-1'}, 'updateDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyMaterial': {'$binary': {'base64': 'AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO', 'subType': '00'}}, 'creationDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyAltNames': ['altname', 'another_altname']}] + +tests: + - description: "ping is bypassed" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: runCommand + object: database + command_name: ping + arguments: + command: + ping: 1 + expectations: + # No listCollections, no mongocryptd command, just the ping. + - command_started_event: + command: + ping: 1 + command_name: ping + - description: "current op is not bypassed" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: runCommand + object: database + command_name: currentOp + arguments: + command: + currentOp: 1 + result: + errorContains: "command not supported for auto encryption: currentOp" \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/count.json b/src/test/spec/json/client-side-encryption/legacy/count.json new file mode 100644 index 000000000..9df8cd639 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/count.json @@ -0,0 +1,229 @@ +{ + "runOn": [ + { + "minServerVersion": "4.1.10" + } + ], + "database_name": "default", + "collection_name": "default", + "data": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + }, + { + "_id": 2, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + } + ], + "json_schema": { + "properties": { + "encrypted_w_altname": { + "encrypt": { + "keyId": "/altname", + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "random": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string_equivalent": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + }, + "key_vault_data": [ + { + "status": 1, + "_id": { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + }, + "masterKey": { + "provider": "aws", + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "region": "us-east-1" + }, + "updateDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyMaterial": { + "$binary": { + "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyAltNames": [ + "altname", + "another_altname" + ] + } + ], + "tests": [ + { + "description": "Count with deterministic encryption", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "count", + "arguments": { + "filter": { + "encrypted_string": "string0" + } + }, + "result": 2 + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "default" + } + }, + "command_name": "listCollections" + } + }, + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "count": "default", + "query": { + "encrypted_string": { + "$eq": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + } + } + }, + "command_name": "count" + } + } + ] + }, + { + "description": "Count fails when filtering on a random encrypted field", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "count", + "arguments": { + "filter": { + "random": "abc" + } + }, + "result": { + "errorContains": "Cannot query on fields encrypted with the randomized encryption" + } + } + ] + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/count.yml b/src/test/spec/json/client-side-encryption/legacy/count.yml new file mode 100644 index 000000000..b8c436a4c --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/count.yml @@ -0,0 +1,54 @@ +runOn: + - minServerVersion: "4.1.10" +database_name: &database_name "default" +collection_name: &collection_name "default" + +data: + - &doc0_encrypted { _id: 1, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==', 'subType': '06'}} } + - &doc1_encrypted { _id: 2, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==', 'subType': '06'}} } +json_schema: {'properties': {'encrypted_w_altname': {'encrypt': {'keyId': '/altname', 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'random': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string_equivalent': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} +key_vault_data: [{'status': 1, '_id': {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}, 'masterKey': {'provider': 'aws', 'key': 'arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0', 'region': 'us-east-1'}, 'updateDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyMaterial': {'$binary': {'base64': 'AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO', 'subType': '00'}}, 'creationDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyAltNames': ['altname', 'another_altname']}] + +tests: + - description: "Count with deterministic encryption" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: count + arguments: + filter: { encrypted_string: "string0" } + result: 2 + expectations: + # Auto encryption will request the collection info. + - command_started_event: + command: + listCollections: 1 + filter: + name: *collection_name + command_name: listCollections + # Then key is fetched from the key vault. + - command_started_event: + command: + find: datakeys + filter: {"$or": [{"_id": {"$in": [ {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}} ] }}, {"keyAltNames": {"$in": []}}]} + $db: keyvault + readConcern: { level: "majority" } + command_name: find + - command_started_event: + command: + count: *collection_name + query: { encrypted_string: { $eq: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==', 'subType': '06'}} } } + command_name: count + - description: "Count fails when filtering on a random encrypted field" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment + operations: + - name: count + arguments: + filter: { random: "abc" } + result: + errorContains: "Cannot query on fields encrypted with the randomized encryption" \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/countDocuments.json b/src/test/spec/json/client-side-encryption/legacy/countDocuments.json new file mode 100644 index 000000000..07ff97f26 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/countDocuments.json @@ -0,0 +1,241 @@ +{ + "runOn": [ + { + "minServerVersion": "4.1.10" + } + ], + "database_name": "default", + "collection_name": "default", + "data": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + }, + { + "_id": 2, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", + "subType": "06" + } + } + } + ], + "json_schema": { + "properties": { + "encrypted_w_altname": { + "encrypt": { + "keyId": "/altname", + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "random": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string_equivalent": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + }, + "key_vault_data": [ + { + "status": 1, + "_id": { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + }, + "masterKey": { + "provider": "aws", + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "region": "us-east-1" + }, + "updateDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyMaterial": { + "$binary": { + "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyAltNames": [ + "altname", + "another_altname" + ] + } + ], + "tests": [ + { + "description": "countDocuments with deterministic encryption", + "skipReason": "waiting on SERVER-39395", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "countDocuments", + "arguments": { + "filter": { + "encrypted_string": "string0" + } + }, + "result": 1 + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "default" + } + }, + "command_name": "listCollections" + } + }, + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "aggregate": "default", + "pipeline": [ + { + "$match": { + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + } + }, + { + "$group": { + "_id": 1, + "n": { + "$sum": 1 + } + } + } + ] + }, + "command_name": "aggregate" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + }, + { + "_id": 2, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", + "subType": "06" + } + } + } + ] + } + } + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/countDocuments.yml b/src/test/spec/json/client-side-encryption/legacy/countDocuments.yml new file mode 100644 index 000000000..e28b478c0 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/countDocuments.yml @@ -0,0 +1,52 @@ +runOn: + - minServerVersion: "4.1.10" +database_name: &database_name "default" +collection_name: &collection_name "default" + +data: + - &doc0_encrypted { _id: 1, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==', 'subType': '06'}} } + - &doc1_encrypted { _id: 2, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==', 'subType': '06'}} } +json_schema: {'properties': {'encrypted_w_altname': {'encrypt': {'keyId': '/altname', 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'random': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string_equivalent': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} +key_vault_data: [{'status': 1, '_id': {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}, 'masterKey': {'provider': 'aws', 'key': 'arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0', 'region': 'us-east-1'}, 'updateDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyMaterial': {'$binary': {'base64': 'AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO', 'subType': '00'}}, 'creationDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyAltNames': ['altname', 'another_altname']}] + +tests: + - description: "countDocuments with deterministic encryption" + skipReason: "waiting on SERVER-39395" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: countDocuments + arguments: + filter: { encrypted_string: "string0" } + result: 1 + expectations: + # Auto encryption will request the collection info. + - command_started_event: + command: + listCollections: 1 + filter: + name: *collection_name + command_name: listCollections + # Then key is fetched from the key vault. + - command_started_event: + command: + find: datakeys + filter: {"$or": [{"_id": {"$in": [ {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}} ] }}, {"keyAltNames": {"$in": []}}]} + $db: keyvault + readConcern: { level: "majority" } + command_name: find + - command_started_event: + command: + aggregate: *collection_name + pipeline: + - { $match: { encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==', 'subType': '06'}} }} + - { $group: { _id: 1, n: { $sum: 1 }}} + command_name: aggregate + outcome: + collection: + # Outcome is checked using a separate MongoClient without auto encryption. + data: + - *doc0_encrypted + - *doc1_encrypted \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/create-and-createIndexes.json b/src/test/spec/json/client-side-encryption/legacy/create-and-createIndexes.json new file mode 100644 index 000000000..48638a97c --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/create-and-createIndexes.json @@ -0,0 +1,115 @@ +{ + "runOn": [ + { + "minServerVersion": "4.1.10" + } + ], + "database_name": "default", + "collection_name": "default", + "data": [], + "tests": [ + { + "description": "create is OK", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "local": { + "key": { + "$binary": { + "base64": "Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk", + "subType": "00" + } + } + } + } + } + }, + "operations": [ + { + "name": "dropCollection", + "object": "database", + "arguments": { + "collection": "unencryptedCollection" + } + }, + { + "name": "createCollection", + "object": "database", + "arguments": { + "collection": "unencryptedCollection", + "validator": { + "unencrypted_string": "foo" + } + } + }, + { + "name": "assertCollectionExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "unencryptedCollection" + } + } + ] + }, + { + "description": "createIndexes is OK", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "local": { + "key": { + "$binary": { + "base64": "Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk", + "subType": "00" + } + } + } + } + } + }, + "operations": [ + { + "name": "dropCollection", + "object": "database", + "arguments": { + "collection": "unencryptedCollection" + } + }, + { + "name": "createCollection", + "object": "database", + "arguments": { + "collection": "unencryptedCollection" + } + }, + { + "name": "runCommand", + "object": "database", + "arguments": { + "command": { + "createIndexes": "unencryptedCollection", + "indexes": [ + { + "name": "name", + "key": { + "name": 1 + } + } + ] + } + } + }, + { + "name": "assertIndexExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "unencryptedCollection", + "index": "name" + } + } + ] + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/create-and-createIndexes.yml b/src/test/spec/json/client-side-encryption/legacy/create-and-createIndexes.yml new file mode 100644 index 000000000..2d9f5ef71 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/create-and-createIndexes.yml @@ -0,0 +1,58 @@ +runOn: + - minServerVersion: "4.1.10" +database_name: &database_name "default" +collection_name: &collection_name "default" + +data: [] +tests: + - description: "create is OK" + clientOptions: + autoEncryptOpts: + kmsProviders: + local: {'key': {'$binary': {'base64': 'Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk', 'subType': '00'}}} + operations: + # Drop to remove a collection that may exist from previous test runs. + - name: dropCollection + object: database + arguments: + collection: "unencryptedCollection" + - name: createCollection + object: database + arguments: + collection: "unencryptedCollection" + validator: + unencrypted_string: "foo" + - name: assertCollectionExists + object: testRunner + arguments: + database: *database_name + collection: "unencryptedCollection" + - description: "createIndexes is OK" + clientOptions: + autoEncryptOpts: + kmsProviders: + local: {'key': {'$binary': {'base64': 'Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk', 'subType': '00'}}} + operations: + # Drop to remove a collection that may exist from previous test runs. + - name: dropCollection + object: database + arguments: + collection: "unencryptedCollection" + - name: createCollection + object: database + arguments: + collection: "unencryptedCollection" + - name: runCommand + object: database + arguments: + command: + createIndexes: "unencryptedCollection" + indexes: + - name: "name" + key: { name: 1 } + - name: assertIndexExists + object: testRunner + arguments: + database: *database_name + collection: "unencryptedCollection" + index: name \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/delete.json b/src/test/spec/json/client-side-encryption/legacy/delete.json new file mode 100644 index 000000000..a6f4ffde9 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/delete.json @@ -0,0 +1,340 @@ +{ + "runOn": [ + { + "minServerVersion": "4.1.10" + } + ], + "database_name": "default", + "collection_name": "default", + "data": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + }, + { + "_id": 2, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", + "subType": "06" + } + } + } + ], + "json_schema": { + "properties": { + "encrypted_w_altname": { + "encrypt": { + "keyId": "/altname", + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "random": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string_equivalent": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + }, + "key_vault_data": [ + { + "status": 1, + "_id": { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + }, + "masterKey": { + "provider": "aws", + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "region": "us-east-1" + }, + "updateDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyMaterial": { + "$binary": { + "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyAltNames": [ + "altname", + "another_altname" + ] + } + ], + "tests": [ + { + "description": "deleteOne with deterministic encryption", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "deleteOne", + "arguments": { + "filter": { + "encrypted_string": "string0" + } + }, + "result": { + "deletedCount": 1 + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "default" + } + }, + "command_name": "listCollections" + } + }, + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "delete": "default", + "deletes": [ + { + "q": { + "encrypted_string": { + "$eq": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + } + }, + "limit": 1 + } + ], + "ordered": true + }, + "command_name": "delete" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 2, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", + "subType": "06" + } + } + } + ] + } + } + }, + { + "description": "deleteMany with deterministic encryption", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "deleteMany", + "arguments": { + "filter": { + "encrypted_string": { + "$in": [ + "string0", + "string1" + ] + } + } + }, + "result": { + "deletedCount": 2 + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "default" + } + }, + "command_name": "listCollections" + } + }, + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "delete": "default", + "deletes": [ + { + "q": { + "encrypted_string": { + "$in": [ + { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + }, + { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", + "subType": "06" + } + } + ] + } + }, + "limit": 0 + } + ], + "ordered": true + }, + "command_name": "delete" + } + } + ], + "outcome": { + "collection": { + "data": [] + } + } + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/delete.yml b/src/test/spec/json/client-side-encryption/legacy/delete.yml new file mode 100644 index 000000000..60810d063 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/delete.yml @@ -0,0 +1,91 @@ +runOn: + - minServerVersion: "4.1.10" +database_name: &database_name "default" +collection_name: &collection_name "default" + +data: + - &doc0_encrypted { _id: 1, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==', 'subType': '06'}} } + - &doc1_encrypted { _id: 2, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==', 'subType': '06'}} } +json_schema: {'properties': {'encrypted_w_altname': {'encrypt': {'keyId': '/altname', 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'random': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string_equivalent': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} +key_vault_data: [{'status': 1, '_id': {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}, 'masterKey': {'provider': 'aws', 'key': 'arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0', 'region': 'us-east-1'}, 'updateDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyMaterial': {'$binary': {'base64': 'AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO', 'subType': '00'}}, 'creationDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyAltNames': ['altname', 'another_altname']}] + +tests: + - description: "deleteOne with deterministic encryption" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: deleteOne + arguments: + filter: { encrypted_string: "string0" } + result: + deletedCount: 1 + expectations: + # Auto encryption will request the collection info. + - command_started_event: + command: + listCollections: 1 + filter: + name: *collection_name + command_name: listCollections + # Then key is fetched from the key vault. + - command_started_event: + command: + find: datakeys + filter: {"$or": [{"_id": {"$in": [ {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}} ] }}, {"keyAltNames": {"$in": []}}]} + $db: keyvault + readConcern: { level: "majority" } + command_name: find + - command_started_event: + command: + delete: *collection_name + deletes: + - q: { encrypted_string: { $eq: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==', 'subType': '06'}} } } + limit: 1 + ordered: true + command_name: delete + outcome: + collection: + # Outcome is checked using a separate MongoClient without auto encryption. + data: + - *doc1_encrypted + - description: "deleteMany with deterministic encryption" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: deleteMany + arguments: + filter: { encrypted_string: { $in: [ "string0", "string1" ] } } + result: + deletedCount: 2 + expectations: + # Auto encryption will request the collection info. + - command_started_event: + command: + listCollections: 1 + filter: + name: *collection_name + command_name: listCollections + # Then key is fetched from the key vault. + - command_started_event: + command: + find: datakeys + filter: {"$or": [{"_id": {"$in": [ {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}} ] }}, {"keyAltNames": {"$in": []}}]} + $db: keyvault + readConcern: { level: "majority" } + command_name: find + - command_started_event: + command: + delete: *collection_name + deletes: + - q: { encrypted_string: { $in : [ {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==', 'subType': '06'}}, {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==', 'subType': '06'}} ] } } + limit: 0 + ordered: true + command_name: delete + outcome: + collection: + # Outcome is checked using a separate MongoClient without auto encryption. + data: [] \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/distinct.json b/src/test/spec/json/client-side-encryption/legacy/distinct.json new file mode 100644 index 000000000..9786b0781 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/distinct.json @@ -0,0 +1,276 @@ +{ + "runOn": [ + { + "minServerVersion": "4.1.10" + } + ], + "database_name": "default", + "collection_name": "default", + "data": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + }, + { + "_id": 2, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + }, + { + "_id": 3, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", + "subType": "06" + } + } + } + ], + "json_schema": { + "properties": { + "encrypted_w_altname": { + "encrypt": { + "keyId": "/altname", + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "random": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string_equivalent": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + }, + "key_vault_data": [ + { + "status": 1, + "_id": { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + }, + "masterKey": { + "provider": "aws", + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "region": "us-east-1" + }, + "updateDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyMaterial": { + "$binary": { + "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyAltNames": [ + "altname", + "another_altname" + ] + } + ], + "tests": [ + { + "description": "distinct with deterministic encryption", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "distinct", + "arguments": { + "filter": { + "encrypted_string": "string0" + }, + "fieldName": "encrypted_string" + }, + "result": [ + "string0" + ] + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "default" + } + }, + "command_name": "listCollections" + } + }, + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "distinct": "default", + "key": "encrypted_string", + "query": { + "encrypted_string": { + "$eq": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + } + } + }, + "command_name": "distinct" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + }, + { + "_id": 2, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + }, + { + "_id": 3, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", + "subType": "06" + } + } + } + ] + } + } + }, + { + "description": "Distinct fails when filtering on a random encrypted field", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "distinct", + "arguments": { + "filter": { + "random": "abc" + }, + "fieldName": "encrypted_string" + }, + "result": { + "errorContains": "Cannot query on fields encrypted with the randomized encryption" + } + } + ] + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/distinct.yml b/src/test/spec/json/client-side-encryption/legacy/distinct.yml new file mode 100644 index 000000000..ca1d8fbf6 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/distinct.yml @@ -0,0 +1,66 @@ +runOn: + - minServerVersion: "4.1.10" +database_name: &database_name "default" +collection_name: &collection_name "default" + +data: + - &doc0_encrypted { _id: 1, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==', 'subType': '06'}} } + - &doc1_encrypted { _id: 2, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==', 'subType': '06'}} } + - &doc2_encrypted { _id: 3, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==', 'subType': '06'}} } +json_schema: {'properties': {'encrypted_w_altname': {'encrypt': {'keyId': '/altname', 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'random': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string_equivalent': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} +key_vault_data: [{'status': 1, '_id': {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}, 'masterKey': {'provider': 'aws', 'key': 'arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0', 'region': 'us-east-1'}, 'updateDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyMaterial': {'$binary': {'base64': 'AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO', 'subType': '00'}}, 'creationDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyAltNames': ['altname', 'another_altname']}] + +tests: + - description: "distinct with deterministic encryption" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: distinct + arguments: + filter: { encrypted_string: "string0" } + fieldName: "encrypted_string" + result: + - "string0" + expectations: + # Auto encryption will request the collection info. + - command_started_event: + command: + listCollections: 1 + filter: + name: *collection_name + command_name: listCollections + # Then key is fetched from the key vault. + - command_started_event: + command: + find: datakeys + filter: {"$or": [{"_id": {"$in": [ {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}} ] }}, {"keyAltNames": {"$in": []}}]} + $db: keyvault + readConcern: { level: "majority" } + command_name: find + - command_started_event: + command: + distinct: *collection_name + key: encrypted_string + query: { encrypted_string: {$eq: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==', 'subType': '06'}} } } + command_name: distinct + outcome: + collection: + # Outcome is checked using a separate MongoClient without auto encryption. + data: + - *doc0_encrypted + - *doc1_encrypted + - *doc2_encrypted + - description: "Distinct fails when filtering on a random encrypted field" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment + operations: + - name: distinct + arguments: + filter: { random: "abc" } + fieldName: "encrypted_string" + result: + errorContains: "Cannot query on fields encrypted with the randomized encryption" \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/explain.json b/src/test/spec/json/client-side-encryption/legacy/explain.json new file mode 100644 index 000000000..0e451e481 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/explain.json @@ -0,0 +1,239 @@ +{ + "runOn": [ + { + "minServerVersion": "4.1.10" + } + ], + "database_name": "default", + "collection_name": "default", + "data": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + }, + { + "_id": 2, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", + "subType": "06" + } + } + } + ], + "json_schema": { + "properties": { + "encrypted_w_altname": { + "encrypt": { + "keyId": "/altname", + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "random": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string_equivalent": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + }, + "key_vault_data": [ + { + "status": 1, + "_id": { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + }, + "masterKey": { + "provider": "aws", + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "region": "us-east-1" + }, + "updateDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyMaterial": { + "$binary": { + "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyAltNames": [ + "altname", + "another_altname" + ] + } + ], + "tests": [ + { + "description": "Explain a find with deterministic encryption", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "runCommand", + "object": "database", + "command_name": "explain", + "arguments": { + "command": { + "explain": { + "find": "default", + "filter": { + "encrypted_string": "string1" + } + } + } + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "default" + } + }, + "command_name": "listCollections" + } + }, + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "explain": { + "find": "default", + "filter": { + "encrypted_string": { + "$eq": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", + "subType": "06" + } + } + } + } + }, + "verbosity": "allPlansExecution" + }, + "command_name": "explain" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + }, + { + "_id": 2, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", + "subType": "06" + } + } + } + ] + } + } + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/explain.yml b/src/test/spec/json/client-side-encryption/legacy/explain.yml new file mode 100644 index 000000000..c0dd9c57c --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/explain.yml @@ -0,0 +1,57 @@ +runOn: + - minServerVersion: "4.1.10" +database_name: &database_name "default" +collection_name: &collection_name "default" + +data: + - &doc0_encrypted { _id: 1, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==', 'subType': '06'}} } + - &doc1_encrypted { _id: 2, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==', 'subType': '06'}} } +json_schema: {'properties': {'encrypted_w_altname': {'encrypt': {'keyId': '/altname', 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'random': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string_equivalent': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} +key_vault_data: [{'status': 1, '_id': {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}, 'masterKey': {'provider': 'aws', 'key': 'arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0', 'region': 'us-east-1'}, 'updateDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyMaterial': {'$binary': {'base64': 'AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO', 'subType': '00'}}, 'creationDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyAltNames': ['altname', 'another_altname']}] + +tests: + - description: "Explain a find with deterministic encryption" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: runCommand + object: database + command_name: explain + arguments: + command: + explain: + find: *collection_name + filter: { encrypted_string : "string1" } + + expectations: + # Auto encryption will request the collection info. + - command_started_event: + command: + listCollections: 1 + filter: + name: *collection_name + command_name: listCollections + # Then key is fetched from the key vault. + - command_started_event: + command: + find: datakeys + filter: {"$or": [{"_id": {"$in": [ {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}} ] }}, {"keyAltNames": {"$in": []}}]} + $db: keyvault + readConcern: { level: "majority" } + command_name: find + - command_started_event: + command: + explain: + find: *collection_name + filter: + { encrypted_string: { $eq: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==', 'subType': '06'}} } } + verbosity: "allPlansExecution" + command_name: explain + outcome: + collection: + # Outcome is checked using a separate MongoClient without auto encryption. + data: + - *doc0_encrypted + - *doc1_encrypted \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/find.json b/src/test/spec/json/client-side-encryption/legacy/find.json new file mode 100644 index 000000000..1feddab0e --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/find.json @@ -0,0 +1,408 @@ +{ + "runOn": [ + { + "minServerVersion": "4.1.10" + } + ], + "database_name": "default", + "collection_name": "default", + "data": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + }, + { + "_id": 2, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", + "subType": "06" + } + }, + "random": { + "$binary": { + "base64": "AgAAAAAAAAAAAAAAAAAAAAACyfp+lXvKOi7f5vh6ZsCijLEaXFKq1X06RmyS98ZvmMQGixTw8HM1f/bGxZjGwvYwjXOkIEb7Exgb8p2KCDI5TQ==", + "subType": "06" + } + } + } + ], + "json_schema": { + "properties": { + "encrypted_w_altname": { + "encrypt": { + "keyId": "/altname", + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "random": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string_equivalent": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + }, + "key_vault_data": [ + { + "status": 1, + "_id": { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + }, + "masterKey": { + "provider": "aws", + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "region": "us-east-1" + }, + "updateDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyMaterial": { + "$binary": { + "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyAltNames": [ + "altname", + "another_altname" + ] + } + ], + "tests": [ + { + "description": "Find with deterministic encryption", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "find", + "arguments": { + "filter": { + "encrypted_string": "string0" + } + }, + "result": [ + { + "_id": 1, + "encrypted_string": "string0" + } + ] + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "default" + } + }, + "command_name": "listCollections" + } + }, + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "find": "default", + "filter": { + "encrypted_string": { + "$eq": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + } + } + }, + "command_name": "find" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + }, + { + "_id": 2, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", + "subType": "06" + } + }, + "random": { + "$binary": { + "base64": "AgAAAAAAAAAAAAAAAAAAAAACyfp+lXvKOi7f5vh6ZsCijLEaXFKq1X06RmyS98ZvmMQGixTw8HM1f/bGxZjGwvYwjXOkIEb7Exgb8p2KCDI5TQ==", + "subType": "06" + } + } + } + ] + } + } + }, + { + "description": "Find with $in with deterministic encryption", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "find", + "arguments": { + "filter": { + "encrypted_string": { + "$in": [ + "string0", + "string1" + ] + } + } + }, + "result": [ + { + "_id": 1, + "encrypted_string": "string0" + }, + { + "_id": 2, + "encrypted_string": "string1", + "random": "abc" + } + ] + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "default" + } + }, + "command_name": "listCollections" + } + }, + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "find": "default", + "filter": { + "encrypted_string": { + "$in": [ + { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + }, + { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", + "subType": "06" + } + } + ] + } + } + }, + "command_name": "find" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + }, + { + "_id": 2, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", + "subType": "06" + } + }, + "random": { + "$binary": { + "base64": "AgAAAAAAAAAAAAAAAAAAAAACyfp+lXvKOi7f5vh6ZsCijLEaXFKq1X06RmyS98ZvmMQGixTw8HM1f/bGxZjGwvYwjXOkIEb7Exgb8p2KCDI5TQ==", + "subType": "06" + } + } + } + ] + } + } + }, + { + "description": "Find fails when filtering on a random encrypted field", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "find", + "arguments": { + "filter": { + "random": "abc" + } + }, + "result": { + "errorContains": "Cannot query on fields encrypted with the randomized encryption" + } + } + ] + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/find.yml b/src/test/spec/json/client-side-encryption/legacy/find.yml new file mode 100644 index 000000000..20179a314 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/find.yml @@ -0,0 +1,105 @@ +runOn: + - minServerVersion: "4.1.10" +database_name: &database_name "default" +collection_name: &collection_name "default" + +data: + - &doc0_encrypted { _id: 1, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==', 'subType': '06'}} } + - &doc1_encrypted { _id: 2, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==', 'subType': '06'}} , random: {'$binary': {'base64': 'AgAAAAAAAAAAAAAAAAAAAAACyfp+lXvKOi7f5vh6ZsCijLEaXFKq1X06RmyS98ZvmMQGixTw8HM1f/bGxZjGwvYwjXOkIEb7Exgb8p2KCDI5TQ==', 'subType': '06'}} } +json_schema: {'properties': {'encrypted_w_altname': {'encrypt': {'keyId': '/altname', 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'random': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string_equivalent': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} +key_vault_data: [{'status': 1, '_id': {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}, 'masterKey': {'provider': 'aws', 'key': 'arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0', 'region': 'us-east-1'}, 'updateDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyMaterial': {'$binary': {'base64': 'AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO', 'subType': '00'}}, 'creationDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyAltNames': ['altname', 'another_altname']}] + +tests: + - description: "Find with deterministic encryption" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: find + arguments: + filter: + { encrypted_string: "string0" } + result: + - &doc0 { _id: 1, encrypted_string: "string0" } + expectations: + # Auto encryption will request the collection info. + - command_started_event: + command: + listCollections: 1 + filter: + name: *collection_name + command_name: listCollections + # Then key is fetched from the key vault. + - command_started_event: + command: + find: datakeys + filter: {"$or": [{"_id": {"$in": [ {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}} ] }}, {"keyAltNames": {"$in": []}}]} + $db: keyvault + readConcern: { level: "majority" } + command_name: find + - command_started_event: + command: + find: *collection_name + filter: + { encrypted_string: { $eq: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==', 'subType': '06'}} } } + command_name: find + outcome: + collection: + # Outcome is checked using a separate MongoClient without auto encryption. + data: + - *doc0_encrypted + - *doc1_encrypted + - description: "Find with $in with deterministic encryption" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: find + arguments: + filter: + { encrypted_string: { $in: [ "string0", "string1" ] } } + result: + - { _id: 1, encrypted_string: "string0" } + - &doc1 { _id: 2, encrypted_string: "string1", random: "abc" } + expectations: + # Auto encryption will request the collection info. + - command_started_event: + command: + listCollections: 1 + filter: + name: *collection_name + command_name: listCollections + # Then key is fetched from the key vault. + - command_started_event: + command: + find: datakeys + filter: {"$or": [{"_id": {"$in": [ {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}} ] }}, {"keyAltNames": {"$in": []}}]} + $db: keyvault + readConcern: { level: "majority" } + command_name: find + - command_started_event: + command: + find: *collection_name + filter: + # Note, the values are re-ordered, but this is logically equivalent. + { encrypted_string: { $in: [ {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==', 'subType': '06'}}, {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==', 'subType': '06'}} ] } } + command_name: find + outcome: + collection: + # Outcome is checked using a separate MongoClient without auto encryption. + data: + - *doc0_encrypted + - *doc1_encrypted + - description: "Find fails when filtering on a random encrypted field" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment + operations: + - name: find + arguments: + filter: { random: "abc" } + result: + errorContains: "Cannot query on fields encrypted with the randomized encryption" \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/findOneAndDelete.json b/src/test/spec/json/client-side-encryption/legacy/findOneAndDelete.json new file mode 100644 index 000000000..e418a4581 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/findOneAndDelete.json @@ -0,0 +1,221 @@ +{ + "runOn": [ + { + "minServerVersion": "4.1.10" + } + ], + "database_name": "default", + "collection_name": "default", + "data": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + }, + { + "_id": 2, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", + "subType": "06" + } + } + } + ], + "json_schema": { + "properties": { + "encrypted_w_altname": { + "encrypt": { + "keyId": "/altname", + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "random": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string_equivalent": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + }, + "key_vault_data": [ + { + "status": 1, + "_id": { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + }, + "masterKey": { + "provider": "aws", + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "region": "us-east-1" + }, + "updateDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyMaterial": { + "$binary": { + "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyAltNames": [ + "altname", + "another_altname" + ] + } + ], + "tests": [ + { + "description": "findOneAndDelete with deterministic encryption", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "findOneAndDelete", + "arguments": { + "filter": { + "encrypted_string": "string0" + } + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "default" + } + }, + "command_name": "listCollections" + } + }, + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "findAndModify": "default", + "query": { + "encrypted_string": { + "$eq": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + } + }, + "remove": true + }, + "command_name": "findAndModify" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 2, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", + "subType": "06" + } + } + } + ] + } + } + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/findOneAndDelete.yml b/src/test/spec/json/client-side-encryption/legacy/findOneAndDelete.yml new file mode 100644 index 000000000..6650f2132 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/findOneAndDelete.yml @@ -0,0 +1,50 @@ +runOn: + - minServerVersion: "4.1.10" +database_name: &database_name "default" +collection_name: &collection_name "default" + +data: + - &doc0_encrypted { _id: 1, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==', 'subType': '06'}} } + - &doc1_encrypted { _id: 2, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==', 'subType': '06'}} } +json_schema: {'properties': {'encrypted_w_altname': {'encrypt': {'keyId': '/altname', 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'random': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string_equivalent': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} +key_vault_data: [{'status': 1, '_id': {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}, 'masterKey': {'provider': 'aws', 'key': 'arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0', 'region': 'us-east-1'}, 'updateDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyMaterial': {'$binary': {'base64': 'AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO', 'subType': '00'}}, 'creationDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyAltNames': ['altname', 'another_altname']}] + +tests: + - description: "findOneAndDelete with deterministic encryption" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: findOneAndDelete + arguments: + filter: + { encrypted_string: "string0" } + expectations: + # Auto encryption will request the collection info. + - command_started_event: + command: + listCollections: 1 + filter: + name: *collection_name + command_name: listCollections + # Then key is fetched from the key vault. + - command_started_event: + command: + find: datakeys + filter: {"$or": [{"_id": {"$in": [ {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}} ] }}, {"keyAltNames": {"$in": []}}]} + $db: keyvault + readConcern: { level: "majority" } + command_name: find + - command_started_event: + command: + findAndModify: *collection_name + query: + { encrypted_string: { $eq: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==', 'subType': '06'}} } } + remove: true + command_name: findAndModify + outcome: + collection: + # Outcome is checked using a separate MongoClient without auto encryption. + data: + - *doc1_encrypted \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/findOneAndReplace.json b/src/test/spec/json/client-side-encryption/legacy/findOneAndReplace.json new file mode 100644 index 000000000..78baca843 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/findOneAndReplace.json @@ -0,0 +1,227 @@ +{ + "runOn": [ + { + "minServerVersion": "4.1.10" + } + ], + "database_name": "default", + "collection_name": "default", + "data": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + } + ], + "json_schema": { + "properties": { + "encrypted_w_altname": { + "encrypt": { + "keyId": "/altname", + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "random": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string_equivalent": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + }, + "key_vault_data": [ + { + "status": 1, + "_id": { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + }, + "masterKey": { + "provider": "aws", + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "region": "us-east-1" + }, + "updateDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyMaterial": { + "$binary": { + "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyAltNames": [ + "altname", + "another_altname" + ] + } + ], + "tests": [ + { + "description": "findOneAndReplace with deterministic encryption", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "findOneAndReplace", + "arguments": { + "filter": { + "encrypted_string": "string0" + }, + "replacement": { + "encrypted_string": "string1" + }, + "returnDocument": "Before" + }, + "result": { + "_id": 1, + "encrypted_string": "string0" + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "default" + } + }, + "command_name": "listCollections" + } + }, + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "findAndModify": "default", + "query": { + "encrypted_string": { + "$eq": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + } + }, + "update": { + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", + "subType": "06" + } + } + } + }, + "command_name": "findAndModify" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", + "subType": "06" + } + } + } + ] + } + } + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/findOneAndReplace.yml b/src/test/spec/json/client-side-encryption/legacy/findOneAndReplace.yml new file mode 100644 index 000000000..f39f3c0fb --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/findOneAndReplace.yml @@ -0,0 +1,50 @@ +runOn: + - minServerVersion: "4.1.10" +database_name: &database_name "default" +collection_name: &collection_name "default" + +data: + - &doc0_encrypted { _id: 1, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==', 'subType': '06'}} } +json_schema: {'properties': {'encrypted_w_altname': {'encrypt': {'keyId': '/altname', 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'random': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string_equivalent': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} +key_vault_data: [{'status': 1, '_id': {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}, 'masterKey': {'provider': 'aws', 'key': 'arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0', 'region': 'us-east-1'}, 'updateDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyMaterial': {'$binary': {'base64': 'AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO', 'subType': '00'}}, 'creationDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyAltNames': ['altname', 'another_altname']}] + +tests: + - description: "findOneAndReplace with deterministic encryption" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: findOneAndReplace + arguments: + filter: { encrypted_string: "string0" } + replacement: { encrypted_string: "string1" } + returnDocument: Before + result: { _id: 1, encrypted_string: "string0" } + expectations: + # Auto encryption will request the collection info. + - command_started_event: + command: + listCollections: 1 + filter: + name: *collection_name + command_name: listCollections + # Then key is fetched from the key vault. + - command_started_event: + command: + find: datakeys + filter: {"$or": [{"_id": {"$in": [ {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}} ] }}, {"keyAltNames": {"$in": []}}]} + $db: keyvault + readConcern: { level: "majority" } + command_name: find + - command_started_event: + command: + findAndModify: *collection_name + query: { encrypted_string: { $eq: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==', 'subType': '06'}} } } + update: { encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==', 'subType': '06'}} } + command_name: findAndModify + outcome: + collection: + # Outcome is checked using a separate MongoClient without auto encryption. + data: + - { _id: 1, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==', 'subType': '06'}} } \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/findOneAndUpdate.json b/src/test/spec/json/client-side-encryption/legacy/findOneAndUpdate.json new file mode 100644 index 000000000..1d8585115 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/findOneAndUpdate.json @@ -0,0 +1,231 @@ +{ + "runOn": [ + { + "minServerVersion": "4.1.10" + } + ], + "database_name": "default", + "collection_name": "default", + "data": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + } + ], + "json_schema": { + "properties": { + "encrypted_w_altname": { + "encrypt": { + "keyId": "/altname", + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "random": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string_equivalent": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + }, + "key_vault_data": [ + { + "status": 1, + "_id": { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + }, + "masterKey": { + "provider": "aws", + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "region": "us-east-1" + }, + "updateDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyMaterial": { + "$binary": { + "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyAltNames": [ + "altname", + "another_altname" + ] + } + ], + "tests": [ + { + "description": "findOneAndUpdate with deterministic encryption", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "findOneAndUpdate", + "arguments": { + "filter": { + "encrypted_string": "string0" + }, + "update": { + "$set": { + "encrypted_string": "string1" + } + }, + "returnDocument": "Before" + }, + "result": { + "_id": 1, + "encrypted_string": "string0" + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "default" + } + }, + "command_name": "listCollections" + } + }, + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "findAndModify": "default", + "query": { + "encrypted_string": { + "$eq": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + } + }, + "update": { + "$set": { + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", + "subType": "06" + } + } + } + } + }, + "command_name": "findAndModify" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", + "subType": "06" + } + } + } + ] + } + } + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/findOneAndUpdate.yml b/src/test/spec/json/client-side-encryption/legacy/findOneAndUpdate.yml new file mode 100644 index 000000000..459902fd4 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/findOneAndUpdate.yml @@ -0,0 +1,50 @@ +runOn: + - minServerVersion: "4.1.10" +database_name: &database_name "default" +collection_name: &collection_name "default" + +data: + - &doc0_encrypted { _id: 1, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==', 'subType': '06'}} } +json_schema: {'properties': {'encrypted_w_altname': {'encrypt': {'keyId': '/altname', 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'random': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string_equivalent': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} +key_vault_data: [{'status': 1, '_id': {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}, 'masterKey': {'provider': 'aws', 'key': 'arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0', 'region': 'us-east-1'}, 'updateDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyMaterial': {'$binary': {'base64': 'AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO', 'subType': '00'}}, 'creationDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyAltNames': ['altname', 'another_altname']}] + +tests: + - description: "findOneAndUpdate with deterministic encryption" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: findOneAndUpdate + arguments: + filter: { encrypted_string: "string0" } + update: { $set: { encrypted_string: "string1" } } + returnDocument: Before + result: { _id: 1, encrypted_string: "string0" } + expectations: + # Auto encryption will request the collection info. + - command_started_event: + command: + listCollections: 1 + filter: + name: *collection_name + command_name: listCollections + # Then key is fetched from the key vault. + - command_started_event: + command: + find: datakeys + filter: {"$or": [{"_id": {"$in": [ {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}} ] }}, {"keyAltNames": {"$in": []}}]} + $db: keyvault + readConcern: { level: "majority" } + command_name: find + - command_started_event: + command: + findAndModify: *collection_name + query: { encrypted_string: { $eq: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==', 'subType': '06'}} } } + update: { $set: { encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==', 'subType': '06'}} } } + command_name: findAndModify + outcome: + collection: + # Outcome is checked using a separate MongoClient without auto encryption. + data: + - { _id: 1, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==', 'subType': '06'}} } \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/fle2-BypassQueryAnalysis.json b/src/test/spec/json/client-side-encryption/legacy/fle2-BypassQueryAnalysis.json new file mode 100644 index 000000000..b8d06e8bc --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/fle2-BypassQueryAnalysis.json @@ -0,0 +1,290 @@ +{ + "runOn": [ + { + "minServerVersion": "6.0.0", + "topology": [ + "replicaset", + "sharded", + "load-balanced" + ] + } + ], + "database_name": "default", + "collection_name": "default", + "data": [], + "encrypted_fields": { + "escCollection": "enxcol_.default.esc", + "eccCollection": "enxcol_.default.ecc", + "ecocCollection": "enxcol_.default.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedIndexed", + "bsonType": "string", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + }, + { + "keyId": { + "$binary": { + "base64": "q83vqxI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedUnindexed", + "bsonType": "string" + } + ] + }, + "key_vault_data": [ + { + "_id": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "keyMaterial": { + "$binary": { + "base64": "sHe0kz57YW7v8g9VP9sf/+K1ex4JqKc5rf/URX3n3p8XdZ6+15uXPaSayC6adWbNxkFskuMCOifDoTT+rkqMtFkDclOy884RuGGtUysq3X7zkAWYTKi8QAfKkajvVbZl2y23UqgVasdQu3OVBQCrH/xY00nNAs/52e958nVjBuzQkSb1T8pKJAyjZsHJ60+FtnfafDZSTAIBJYn7UWBCwQ==", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1648914851981" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1648914851981" + } + }, + "status": { + "$numberInt": "0" + }, + "masterKey": { + "provider": "local" + } + }, + { + "_id": { + "$binary": { + "base64": "q83vqxI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "keyMaterial": { + "$binary": { + "base64": "HBk9BWihXExNDvTp1lUxOuxuZK2Pe2ZdVdlsxPEBkiO1bS4mG5NNDsQ7zVxJAH8BtdOYp72Ku4Y3nwc0BUpIKsvAKX4eYXtlhv5zUQxWdeNFhg9qK7qb8nqhnnLeT0f25jFSqzWJoT379hfwDeu0bebJHr35QrJ8myZdPMTEDYF08QYQ48ShRBli0S+QzBHHAQiM2iJNr4svg2WR8JSeWQ==", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1648914851981" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1648914851981" + } + }, + "status": { + "$numberInt": "0" + }, + "masterKey": { + "provider": "local" + } + } + ], + "tests": [ + { + "description": "BypassQueryAnalysis decrypts", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "local": { + "key": { + "$binary": { + "base64": "Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk", + "subType": "00" + } + } + } + }, + "bypassQueryAnalysis": true + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encryptedIndexed": { + "$binary": { + "base64": "BHEBAAAFZAAgAAAAAHb62aV7+mqmaGcotPLdG3KP7S8diFwWMLM/5rYtqLrEBXMAIAAAAAAVJ6OWHRv3OtCozHpt3ZzfBhaxZirLv3B+G8PuaaO4EgVjACAAAAAAsZXWOWA+UiCBbrJNB6bHflB/cn7pWSvwWN2jw4FPeIUFcABQAAAAAMdD1nV2nqeI1eXEQNskDflCy8I7/HvvqDKJ6XxjhrPQWdLqjz+8GosGUsB7A8ee/uG9/guENuL25XD+Fxxkv1LLXtavHOlLF7iW0u9yabqqBXUAEAAAAAQSNFZ4EjSYdhI0EjRWeJASEHQAAgAAAAV2AE0AAAAAq83vqxI0mHYSNBI0VniQEkzZZBBDgeZh+h+gXEmOrSFtVvkUcnHWj/rfPW7iJ0G3UJ8zpuBmUM/VjOMJCY4+eDqdTiPIwX+/vNXegc8FZQAgAAAAAOuac/eRLYakKX6B0vZ1r3QodOQFfjqJD+xlGiPu4/PsAA==", + "subType": "06" + } + } + } + } + }, + { + "name": "find", + "arguments": { + "filter": { + "_id": 1 + } + }, + "result": [ + { + "_id": 1, + "encryptedIndexed": "value123" + } + ] + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "default" + } + }, + "command_name": "listCollections" + } + }, + { + "command_started_event": { + "command": { + "insert": "default", + "documents": [ + { + "_id": 1, + "encryptedIndexed": { + "$binary": { + "base64": "BHEBAAAFZAAgAAAAAHb62aV7+mqmaGcotPLdG3KP7S8diFwWMLM/5rYtqLrEBXMAIAAAAAAVJ6OWHRv3OtCozHpt3ZzfBhaxZirLv3B+G8PuaaO4EgVjACAAAAAAsZXWOWA+UiCBbrJNB6bHflB/cn7pWSvwWN2jw4FPeIUFcABQAAAAAMdD1nV2nqeI1eXEQNskDflCy8I7/HvvqDKJ6XxjhrPQWdLqjz+8GosGUsB7A8ee/uG9/guENuL25XD+Fxxkv1LLXtavHOlLF7iW0u9yabqqBXUAEAAAAAQSNFZ4EjSYdhI0EjRWeJASEHQAAgAAAAV2AE0AAAAAq83vqxI0mHYSNBI0VniQEkzZZBBDgeZh+h+gXEmOrSFtVvkUcnHWj/rfPW7iJ0G3UJ8zpuBmUM/VjOMJCY4+eDqdTiPIwX+/vNXegc8FZQAgAAAAAOuac/eRLYakKX6B0vZ1r3QodOQFfjqJD+xlGiPu4/PsAA==", + "subType": "06" + } + } + } + ], + "ordered": true + }, + "command_name": "insert" + } + }, + { + "command_started_event": { + "command": { + "find": "default", + "filter": { + "_id": 1 + } + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "q83vqxI0mHYSNBI0VniQEg==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "encryptedIndexed": { + "$$type": "binData" + }, + "__safeContent__": [ + { + "$binary": { + "base64": "ThpoKfQ8AkOzkFfNC1+9PF0pY2nIzfXvRdxQgjkNbBw=", + "subType": "00" + } + } + ] + } + ] + } + } + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/fle2-BypassQueryAnalysis.yml b/src/test/spec/json/client-side-encryption/legacy/fle2-BypassQueryAnalysis.yml new file mode 100644 index 000000000..e6b3d6650 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/fle2-BypassQueryAnalysis.yml @@ -0,0 +1,101 @@ +runOn: + - minServerVersion: "6.0.0" + # FLE 2 Encrypted collections are not supported on standalone. + topology: [ "replicaset", "sharded", "load-balanced" ] +database_name: &database_name "default" +collection_name: &collection_name "default" +data: [] +encrypted_fields: &encrypted_fields {'escCollection': 'enxcol_.default.esc', 'eccCollection': 'enxcol_.default.ecc', 'ecocCollection': 'enxcol_.default.ecoc', 'fields': [{'keyId': {'$binary': {'base64': 'EjRWeBI0mHYSNBI0VniQEg==', 'subType': '04'}}, 'path': 'encryptedIndexed', 'bsonType': 'string', 'queries': {'queryType': 'equality', 'contention': {'$numberLong': '0'}}}, {'keyId': {'$binary': {'base64': 'q83vqxI0mHYSNBI0VniQEg==', 'subType': '04'}}, 'path': 'encryptedUnindexed', 'bsonType': 'string'}]} +key_vault_data: [{'_id': {'$binary': {'base64': 'EjRWeBI0mHYSNBI0VniQEg==', 'subType': '04'}}, 'keyMaterial': {'$binary': {'base64': 'sHe0kz57YW7v8g9VP9sf/+K1ex4JqKc5rf/URX3n3p8XdZ6+15uXPaSayC6adWbNxkFskuMCOifDoTT+rkqMtFkDclOy884RuGGtUysq3X7zkAWYTKi8QAfKkajvVbZl2y23UqgVasdQu3OVBQCrH/xY00nNAs/52e958nVjBuzQkSb1T8pKJAyjZsHJ60+FtnfafDZSTAIBJYn7UWBCwQ==', 'subType': '00'}}, 'creationDate': {'$date': {'$numberLong': '1648914851981'}}, 'updateDate': {'$date': {'$numberLong': '1648914851981'}}, 'status': {'$numberInt': '0'}, 'masterKey': {'provider': 'local'}}, {'_id': {'$binary': {'base64': 'q83vqxI0mHYSNBI0VniQEg==', 'subType': '04'}}, 'keyMaterial': {'$binary': {'base64': 'HBk9BWihXExNDvTp1lUxOuxuZK2Pe2ZdVdlsxPEBkiO1bS4mG5NNDsQ7zVxJAH8BtdOYp72Ku4Y3nwc0BUpIKsvAKX4eYXtlhv5zUQxWdeNFhg9qK7qb8nqhnnLeT0f25jFSqzWJoT379hfwDeu0bebJHr35QrJ8myZdPMTEDYF08QYQ48ShRBli0S+QzBHHAQiM2iJNr4svg2WR8JSeWQ==', 'subType': '00'}}, 'creationDate': {'$date': {'$numberLong': '1648914851981'}}, 'updateDate': {'$date': {'$numberLong': '1648914851981'}}, 'status': {'$numberInt': '0'}, 'masterKey': {'provider': 'local'}} ] + +tests: + - description: "BypassQueryAnalysis decrypts" + clientOptions: + autoEncryptOpts: + kmsProviders: + local: {'key': {'$binary': {'base64': 'Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk', 'subType': '00'}}} + bypassQueryAnalysis: true + operations: + - name: insertOne + arguments: + document: &doc0_encrypted { + "_id": 1, + "encryptedIndexed": { + "$binary": { + # Payload has an IndexKey of key1 and UserKey of key2. + "base64": "BHEBAAAFZAAgAAAAAHb62aV7+mqmaGcotPLdG3KP7S8diFwWMLM/5rYtqLrEBXMAIAAAAAAVJ6OWHRv3OtCozHpt3ZzfBhaxZirLv3B+G8PuaaO4EgVjACAAAAAAsZXWOWA+UiCBbrJNB6bHflB/cn7pWSvwWN2jw4FPeIUFcABQAAAAAMdD1nV2nqeI1eXEQNskDflCy8I7/HvvqDKJ6XxjhrPQWdLqjz+8GosGUsB7A8ee/uG9/guENuL25XD+Fxxkv1LLXtavHOlLF7iW0u9yabqqBXUAEAAAAAQSNFZ4EjSYdhI0EjRWeJASEHQAAgAAAAV2AE0AAAAAq83vqxI0mHYSNBI0VniQEkzZZBBDgeZh+h+gXEmOrSFtVvkUcnHWj/rfPW7iJ0G3UJ8zpuBmUM/VjOMJCY4+eDqdTiPIwX+/vNXegc8FZQAgAAAAAOuac/eRLYakKX6B0vZ1r3QodOQFfjqJD+xlGiPu4/PsAA==", + "subType": "06" + } + } + } + - name: find + arguments: + filter: { "_id": 1 } + result: [{"_id": 1, "encryptedIndexed": "value123" }] + expectations: + - command_started_event: + command: + listCollections: 1 + filter: + name: *collection_name + command_name: listCollections + - command_started_event: + command: + insert: *collection_name + documents: + - *doc0_encrypted + ordered: true + command_name: insert + - command_started_event: + command: + find: *collection_name + filter: { "_id": 1 } + command_name: find + - command_started_event: + command: + find: datakeys + filter: { + "$or": [ + { + "_id": { + "$in": [ + {'$binary': {'base64': 'EjRWeBI0mHYSNBI0VniQEg==', 'subType': '04'}} + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + } + $db: keyvault + readConcern: { level: "majority" } + command_name: find + - command_started_event: + command: + find: datakeys + filter: { + "$or": [ + { + "_id": { + "$in": [ + {'$binary': {'base64': 'q83vqxI0mHYSNBI0VniQEg==', 'subType': '04'}} + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + } + $db: keyvault + readConcern: { level: "majority" } + command_name: find + outcome: + collection: + data: + - {"_id": 1, "encryptedIndexed": { "$$type": "binData" }, "__safeContent__": [{ "$binary" : { "base64" : "ThpoKfQ8AkOzkFfNC1+9PF0pY2nIzfXvRdxQgjkNbBw=", "subType" : "00" } }] } \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/fle2-Compact.json b/src/test/spec/json/client-side-encryption/legacy/fle2-Compact.json new file mode 100644 index 000000000..6ca0f9ba0 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/fle2-Compact.json @@ -0,0 +1,233 @@ +{ + "runOn": [ + { + "minServerVersion": "6.0.0", + "topology": [ + "replicaset", + "sharded", + "load-balanced" + ] + } + ], + "database_name": "default", + "collection_name": "default", + "data": [], + "encrypted_fields": { + "escCollection": "enxcol_.default.esc", + "eccCollection": "enxcol_.default.ecc", + "ecocCollection": "enxcol_.default.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedIndexed", + "bsonType": "string", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + }, + { + "keyId": { + "$binary": { + "base64": "q83vqxI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedUnindexed", + "bsonType": "string" + } + ] + }, + "key_vault_data": [ + { + "_id": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "keyMaterial": { + "$binary": { + "base64": "sHe0kz57YW7v8g9VP9sf/+K1ex4JqKc5rf/URX3n3p8XdZ6+15uXPaSayC6adWbNxkFskuMCOifDoTT+rkqMtFkDclOy884RuGGtUysq3X7zkAWYTKi8QAfKkajvVbZl2y23UqgVasdQu3OVBQCrH/xY00nNAs/52e958nVjBuzQkSb1T8pKJAyjZsHJ60+FtnfafDZSTAIBJYn7UWBCwQ==", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1648914851981" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1648914851981" + } + }, + "status": { + "$numberInt": "0" + }, + "masterKey": { + "provider": "local" + } + }, + { + "_id": { + "$binary": { + "base64": "q83vqxI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "keyMaterial": { + "$binary": { + "base64": "HBk9BWihXExNDvTp1lUxOuxuZK2Pe2ZdVdlsxPEBkiO1bS4mG5NNDsQ7zVxJAH8BtdOYp72Ku4Y3nwc0BUpIKsvAKX4eYXtlhv5zUQxWdeNFhg9qK7qb8nqhnnLeT0f25jFSqzWJoT379hfwDeu0bebJHr35QrJ8myZdPMTEDYF08QYQ48ShRBli0S+QzBHHAQiM2iJNr4svg2WR8JSeWQ==", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1648914851981" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1648914851981" + } + }, + "status": { + "$numberInt": "0" + }, + "masterKey": { + "provider": "local" + } + } + ], + "tests": [ + { + "description": "Compact works", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "local": { + "key": { + "$binary": { + "base64": "Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk", + "subType": "00" + } + } + } + } + } + }, + "operations": [ + { + "name": "runCommand", + "object": "database", + "command_name": "compactStructuredEncryptionData", + "arguments": { + "command": { + "compactStructuredEncryptionData": "default" + } + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "default" + } + }, + "command_name": "listCollections" + } + }, + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + { + "$binary": { + "base64": "q83vqxI0mHYSNBI0VniQEg==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "compactStructuredEncryptionData": "default", + "compactionTokens": { + "encryptedIndexed": { + "$binary": { + "base64": "noN+05JsuO1oDg59yypIGj45i+eFH6HOTXOPpeZ//Mk=", + "subType": "00" + } + }, + "encryptedUnindexed": { + "$binary": { + "base64": "SWO8WEoZ2r2Kx/muQKb7+COizy85nIIUFiHh4K9kcvA=", + "subType": "00" + } + } + } + }, + "command_name": "compactStructuredEncryptionData" + } + } + ] + }, + { + "description": "Compact errors on an unencrypted client", + "operations": [ + { + "name": "runCommand", + "object": "database", + "command_name": "compactStructuredEncryptionData", + "arguments": { + "command": { + "compactStructuredEncryptionData": "default" + } + }, + "result": { + "errorContains": "'compactStructuredEncryptionData.compactionTokens' is missing" + } + } + ] + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/fle2-Compact.yml b/src/test/spec/json/client-side-encryption/legacy/fle2-Compact.yml new file mode 100644 index 000000000..6e3a198d0 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/fle2-Compact.yml @@ -0,0 +1,80 @@ +runOn: + - minServerVersion: "6.0.0" + # FLE 2 Encrypted collections are not supported on standalone. + topology: [ "replicaset", "sharded", "load-balanced" ] +database_name: &database_name "default" +collection_name: &collection_name "default" +data: [] +encrypted_fields: &encrypted_fields {'escCollection': 'enxcol_.default.esc', 'eccCollection': 'enxcol_.default.ecc', 'ecocCollection': 'enxcol_.default.ecoc', 'fields': [{'keyId': {'$binary': {'base64': 'EjRWeBI0mHYSNBI0VniQEg==', 'subType': '04'}}, 'path': 'encryptedIndexed', 'bsonType': 'string', 'queries': {'queryType': 'equality', 'contention': {'$numberLong': '0'}}}, {'keyId': {'$binary': {'base64': 'q83vqxI0mHYSNBI0VniQEg==', 'subType': '04'}}, 'path': 'encryptedUnindexed', 'bsonType': 'string'}]} +key_vault_data: [ {'_id': {'$binary': {'base64': 'EjRWeBI0mHYSNBI0VniQEg==', 'subType': '04'}}, 'keyMaterial': {'$binary': {'base64': 'sHe0kz57YW7v8g9VP9sf/+K1ex4JqKc5rf/URX3n3p8XdZ6+15uXPaSayC6adWbNxkFskuMCOifDoTT+rkqMtFkDclOy884RuGGtUysq3X7zkAWYTKi8QAfKkajvVbZl2y23UqgVasdQu3OVBQCrH/xY00nNAs/52e958nVjBuzQkSb1T8pKJAyjZsHJ60+FtnfafDZSTAIBJYn7UWBCwQ==', 'subType': '00'}}, 'creationDate': {'$date': {'$numberLong': '1648914851981'}}, 'updateDate': {'$date': {'$numberLong': '1648914851981'}}, 'status': {'$numberInt': '0'}, 'masterKey': {'provider': 'local'}}, {'_id': {'$binary': {'base64': 'q83vqxI0mHYSNBI0VniQEg==', 'subType': '04'}}, 'keyMaterial': {'$binary': {'base64': 'HBk9BWihXExNDvTp1lUxOuxuZK2Pe2ZdVdlsxPEBkiO1bS4mG5NNDsQ7zVxJAH8BtdOYp72Ku4Y3nwc0BUpIKsvAKX4eYXtlhv5zUQxWdeNFhg9qK7qb8nqhnnLeT0f25jFSqzWJoT379hfwDeu0bebJHr35QrJ8myZdPMTEDYF08QYQ48ShRBli0S+QzBHHAQiM2iJNr4svg2WR8JSeWQ==', 'subType': '00'}}, 'creationDate': {'$date': {'$numberLong': '1648914851981'}}, 'updateDate': {'$date': {'$numberLong': '1648914851981'}}, 'status': {'$numberInt': '0'}, 'masterKey': {'provider': 'local'}} ] +tests: + - description: "Compact works" + clientOptions: + autoEncryptOpts: + kmsProviders: + local: {'key': {'$binary': {'base64': 'Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk', 'subType': '00'}}} + operations: + - name: runCommand + object: database + command_name: compactStructuredEncryptionData + arguments: + command: + compactStructuredEncryptionData: *collection_name + expectations: + - command_started_event: + command: + listCollections: 1 + filter: + name: *collection_name + command_name: listCollections + - command_started_event: + command: + find: datakeys + filter: { + "$or": [ + { + "_id": { + "$in": [ + {'$binary': {'base64': 'EjRWeBI0mHYSNBI0VniQEg==', 'subType': '04'}}, + {'$binary': {'base64': 'q83vqxI0mHYSNBI0VniQEg==', 'subType': '04'}} + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + } + $db: keyvault + readConcern: { level: "majority" } + command_name: find + - command_started_event: + command: + compactStructuredEncryptionData: *collection_name + compactionTokens: { + "encryptedIndexed": { + "$binary": { + "base64": "noN+05JsuO1oDg59yypIGj45i+eFH6HOTXOPpeZ//Mk=", + "subType": "00" + } + }, + "encryptedUnindexed": { + "$binary": { + "base64": "SWO8WEoZ2r2Kx/muQKb7+COizy85nIIUFiHh4K9kcvA=", + "subType": "00" + } + } + } + command_name: compactStructuredEncryptionData + - description: "Compact errors on an unencrypted client" + operations: + - name: runCommand + object: database + command_name: compactStructuredEncryptionData + arguments: + command: + compactStructuredEncryptionData: *collection_name + result: + errorContains: "'compactStructuredEncryptionData.compactionTokens' is missing" \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/fle2-CreateCollection.json b/src/test/spec/json/client-side-encryption/legacy/fle2-CreateCollection.json new file mode 100644 index 000000000..9f8db41f8 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/fle2-CreateCollection.json @@ -0,0 +1,2240 @@ +{ + "runOn": [ + { + "minServerVersion": "6.0.0", + "topology": [ + "replicaset", + "sharded", + "load-balanced" + ] + } + ], + "database_name": "default", + "collection_name": "default", + "tests": [ + { + "description": "state collections and index are created", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + }, + "encryptedFieldsMap": { + "default.encryptedCollection": { + "escCollection": "encryptedCollection.esc", + "eccCollection": "encryptedCollection.ecc", + "ecocCollection": "encryptedCollection.ecoc", + "fields": [ + { + "path": "firstName", + "bsonType": "string", + "keyId": { + "$binary": { + "subType": "04", + "base64": "AAAAAAAAAAAAAAAAAAAAAA==" + } + } + } + ] + } + } + } + }, + "operations": [ + { + "name": "dropCollection", + "object": "database", + "arguments": { + "collection": "encryptedCollection" + } + }, + { + "name": "createCollection", + "object": "database", + "arguments": { + "collection": "encryptedCollection" + } + }, + { + "name": "assertCollectionExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection.esc" + } + }, + { + "name": "assertCollectionExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection.ecc" + } + }, + { + "name": "assertCollectionExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection.ecoc" + } + }, + { + "name": "assertCollectionExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection" + } + }, + { + "name": "assertIndexExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection", + "index": "__safeContent___1" + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "drop": "encryptedCollection.esc" + }, + "command_name": "drop", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "drop": "encryptedCollection.ecc" + }, + "command_name": "drop", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "drop": "encryptedCollection.ecoc" + }, + "command_name": "drop", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "drop": "encryptedCollection" + }, + "command_name": "drop", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "create": "encryptedCollection.esc", + "clusteredIndex": { + "key": { + "_id": 1 + }, + "unique": true + } + }, + "command_name": "create", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "create": "encryptedCollection.ecc", + "clusteredIndex": { + "key": { + "_id": 1 + }, + "unique": true + } + }, + "command_name": "create", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "create": "encryptedCollection.ecoc", + "clusteredIndex": { + "key": { + "_id": 1 + }, + "unique": true + } + }, + "command_name": "create", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "create": "encryptedCollection", + "encryptedFields": { + "escCollection": "encryptedCollection.esc", + "eccCollection": "encryptedCollection.ecc", + "ecocCollection": "encryptedCollection.ecoc", + "fields": [ + { + "path": "firstName", + "bsonType": "string", + "keyId": { + "$binary": { + "subType": "04", + "base64": "AAAAAAAAAAAAAAAAAAAAAA==" + } + } + } + ] + } + }, + "command_name": "create", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "createIndexes": "encryptedCollection", + "indexes": [ + { + "name": "__safeContent___1", + "key": { + "__safeContent__": 1 + } + } + ] + }, + "command_name": "createIndexes", + "database_name": "default" + } + } + ] + }, + { + "description": "default state collection names are applied", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + }, + "encryptedFieldsMap": { + "default.encryptedCollection": { + "fields": [ + { + "path": "firstName", + "bsonType": "string", + "keyId": { + "$binary": { + "subType": "04", + "base64": "AAAAAAAAAAAAAAAAAAAAAA==" + } + }, + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + } + ] + } + } + } + }, + "operations": [ + { + "name": "dropCollection", + "object": "database", + "arguments": { + "collection": "encryptedCollection" + } + }, + { + "name": "createCollection", + "object": "database", + "arguments": { + "collection": "encryptedCollection" + } + }, + { + "name": "assertCollectionExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "enxcol_.encryptedCollection.esc" + } + }, + { + "name": "assertCollectionExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "enxcol_.encryptedCollection.ecc" + } + }, + { + "name": "assertCollectionExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "enxcol_.encryptedCollection.ecoc" + } + }, + { + "name": "assertCollectionExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection" + } + }, + { + "name": "assertIndexExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection", + "index": "__safeContent___1" + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "drop": "enxcol_.encryptedCollection.esc" + }, + "command_name": "drop", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "drop": "enxcol_.encryptedCollection.ecc" + }, + "command_name": "drop", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "drop": "enxcol_.encryptedCollection.ecoc" + }, + "command_name": "drop", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "drop": "encryptedCollection" + }, + "command_name": "drop", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "create": "enxcol_.encryptedCollection.esc", + "clusteredIndex": { + "key": { + "_id": 1 + }, + "unique": true + } + }, + "command_name": "create", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "create": "enxcol_.encryptedCollection.ecc", + "clusteredIndex": { + "key": { + "_id": 1 + }, + "unique": true + } + }, + "command_name": "create", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "create": "enxcol_.encryptedCollection.ecoc", + "clusteredIndex": { + "key": { + "_id": 1 + }, + "unique": true + } + }, + "command_name": "create", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "create": "encryptedCollection", + "encryptedFields": { + "fields": [ + { + "path": "firstName", + "bsonType": "string", + "keyId": { + "$binary": { + "subType": "04", + "base64": "AAAAAAAAAAAAAAAAAAAAAA==" + } + }, + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + } + ] + } + }, + "command_name": "create", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "createIndexes": "encryptedCollection", + "indexes": [ + { + "name": "__safeContent___1", + "key": { + "__safeContent__": 1 + } + } + ] + }, + "command_name": "createIndexes", + "database_name": "default" + } + } + ] + }, + { + "description": "drop removes all state collections", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + }, + "encryptedFieldsMap": { + "default.encryptedCollection": { + "fields": [ + { + "path": "firstName", + "bsonType": "string", + "keyId": { + "$binary": { + "subType": "04", + "base64": "AAAAAAAAAAAAAAAAAAAAAA==" + } + }, + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + } + ] + } + } + } + }, + "operations": [ + { + "name": "dropCollection", + "object": "database", + "arguments": { + "collection": "encryptedCollection" + } + }, + { + "name": "createCollection", + "object": "database", + "arguments": { + "collection": "encryptedCollection" + } + }, + { + "name": "assertCollectionExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "enxcol_.encryptedCollection.esc" + } + }, + { + "name": "assertCollectionExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "enxcol_.encryptedCollection.ecc" + } + }, + { + "name": "assertCollectionExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "enxcol_.encryptedCollection.ecoc" + } + }, + { + "name": "assertCollectionExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection" + } + }, + { + "name": "assertIndexExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection", + "index": "__safeContent___1" + } + }, + { + "name": "dropCollection", + "object": "database", + "arguments": { + "collection": "encryptedCollection" + } + }, + { + "name": "assertCollectionNotExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "enxcol_.encryptedCollection.ecc" + } + }, + { + "name": "assertCollectionNotExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "enxcol_.encryptedCollection.ecoc" + } + }, + { + "name": "assertCollectionNotExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection" + } + }, + { + "name": "assertIndexNotExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection", + "index": "__safeContent___1" + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "drop": "enxcol_.encryptedCollection.esc" + }, + "command_name": "drop", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "drop": "enxcol_.encryptedCollection.ecc" + }, + "command_name": "drop", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "drop": "enxcol_.encryptedCollection.ecoc" + }, + "command_name": "drop", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "drop": "encryptedCollection" + }, + "command_name": "drop", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "create": "enxcol_.encryptedCollection.esc", + "clusteredIndex": { + "key": { + "_id": 1 + }, + "unique": true + } + }, + "command_name": "create", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "create": "enxcol_.encryptedCollection.ecc", + "clusteredIndex": { + "key": { + "_id": 1 + }, + "unique": true + } + }, + "command_name": "create", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "create": "enxcol_.encryptedCollection.ecoc", + "clusteredIndex": { + "key": { + "_id": 1 + }, + "unique": true + } + }, + "command_name": "create", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "create": "encryptedCollection", + "encryptedFields": { + "fields": [ + { + "path": "firstName", + "bsonType": "string", + "keyId": { + "$binary": { + "subType": "04", + "base64": "AAAAAAAAAAAAAAAAAAAAAA==" + } + }, + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + } + ] + } + }, + "command_name": "create", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "createIndexes": "encryptedCollection", + "indexes": [ + { + "name": "__safeContent___1", + "key": { + "__safeContent__": 1 + } + } + ] + }, + "command_name": "createIndexes", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "drop": "enxcol_.encryptedCollection.esc" + }, + "command_name": "drop", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "drop": "enxcol_.encryptedCollection.ecc" + }, + "command_name": "drop", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "drop": "enxcol_.encryptedCollection.ecoc" + }, + "command_name": "drop", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "drop": "encryptedCollection" + }, + "command_name": "drop", + "database_name": "default" + } + } + ] + }, + { + "description": "encryptedFieldsMap with cyclic entries does not loop", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + }, + "encryptedFieldsMap": { + "default.encryptedCollection": { + "escCollection": "encryptedCollection.esc", + "eccCollection": "encryptedCollection.ecc", + "ecocCollection": "encryptedCollection.ecoc", + "fields": [ + { + "path": "firstName", + "bsonType": "string", + "keyId": { + "$binary": { + "subType": "04", + "base64": "AAAAAAAAAAAAAAAAAAAAAA==" + } + } + } + ] + }, + "default.encryptedCollection.esc": { + "escCollection": "encryptedCollection", + "eccCollection": "encryptedCollection.ecc", + "ecocCollection": "encryptedCollection.ecoc", + "fields": [ + { + "path": "firstName", + "bsonType": "string", + "keyId": { + "$binary": { + "subType": "04", + "base64": "AAAAAAAAAAAAAAAAAAAAAA==" + } + } + } + ] + } + } + } + }, + "operations": [ + { + "name": "dropCollection", + "object": "database", + "arguments": { + "collection": "encryptedCollection" + } + }, + { + "name": "createCollection", + "object": "database", + "arguments": { + "collection": "encryptedCollection" + } + }, + { + "name": "assertCollectionExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection.esc" + } + }, + { + "name": "assertCollectionExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection.ecc" + } + }, + { + "name": "assertCollectionExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection.ecoc" + } + }, + { + "name": "assertCollectionExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection" + } + }, + { + "name": "assertIndexExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection", + "index": "__safeContent___1" + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "drop": "encryptedCollection.esc" + }, + "command_name": "drop", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "drop": "encryptedCollection.ecc" + }, + "command_name": "drop", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "drop": "encryptedCollection.ecoc" + }, + "command_name": "drop", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "drop": "encryptedCollection" + }, + "command_name": "drop", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "create": "encryptedCollection.esc", + "clusteredIndex": { + "key": { + "_id": 1 + }, + "unique": true + } + }, + "command_name": "create", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "create": "encryptedCollection.ecc", + "clusteredIndex": { + "key": { + "_id": 1 + }, + "unique": true + } + }, + "command_name": "create", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "create": "encryptedCollection.ecoc", + "clusteredIndex": { + "key": { + "_id": 1 + }, + "unique": true + } + }, + "command_name": "create", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "create": "encryptedCollection", + "encryptedFields": { + "escCollection": "encryptedCollection.esc", + "eccCollection": "encryptedCollection.ecc", + "ecocCollection": "encryptedCollection.ecoc", + "fields": [ + { + "path": "firstName", + "bsonType": "string", + "keyId": { + "$binary": { + "subType": "04", + "base64": "AAAAAAAAAAAAAAAAAAAAAA==" + } + } + } + ] + } + }, + "command_name": "create", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "createIndexes": "encryptedCollection", + "indexes": [ + { + "name": "__safeContent___1", + "key": { + "__safeContent__": 1 + } + } + ] + }, + "command_name": "createIndexes", + "database_name": "default" + } + } + ] + }, + { + "description": "CreateCollection without encryptedFields.", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + }, + "encryptedFieldsMap": { + "default.encryptedCollection": { + "escCollection": "encryptedCollection.esc", + "eccCollection": "encryptedCollection.ecc", + "ecocCollection": "encryptedCollection.ecoc", + "fields": [ + { + "path": "firstName", + "bsonType": "string", + "keyId": { + "$binary": { + "subType": "04", + "base64": "AAAAAAAAAAAAAAAAAAAAAA==" + } + } + } + ] + } + } + } + }, + "operations": [ + { + "name": "dropCollection", + "object": "database", + "arguments": { + "collection": "plaintextCollection" + } + }, + { + "name": "createCollection", + "object": "database", + "arguments": { + "collection": "plaintextCollection" + } + }, + { + "name": "assertCollectionExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "plaintextCollection" + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "plaintextCollection" + } + }, + "command_name": "listCollections", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "drop": "plaintextCollection" + }, + "command_name": "drop", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "create": "plaintextCollection" + }, + "command_name": "create", + "database_name": "default" + } + } + ] + }, + { + "description": "CreateCollection from encryptedFieldsMap.", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + }, + "encryptedFieldsMap": { + "default.encryptedCollection": { + "escCollection": "encryptedCollection.esc", + "eccCollection": "encryptedCollection.ecc", + "ecocCollection": "encryptedCollection.ecoc", + "fields": [ + { + "path": "firstName", + "bsonType": "string", + "keyId": { + "$binary": { + "subType": "04", + "base64": "AAAAAAAAAAAAAAAAAAAAAA==" + } + } + } + ] + } + } + } + }, + "operations": [ + { + "name": "dropCollection", + "object": "database", + "arguments": { + "collection": "encryptedCollection" + } + }, + { + "name": "createCollection", + "object": "database", + "arguments": { + "collection": "encryptedCollection" + } + }, + { + "name": "assertCollectionExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection.esc" + } + }, + { + "name": "assertCollectionExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection.ecc" + } + }, + { + "name": "assertCollectionExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection.ecoc" + } + }, + { + "name": "assertCollectionExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection" + } + }, + { + "name": "assertIndexExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection", + "index": "__safeContent___1" + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "drop": "encryptedCollection.esc" + }, + "command_name": "drop", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "drop": "encryptedCollection.ecc" + }, + "command_name": "drop", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "drop": "encryptedCollection.ecoc" + }, + "command_name": "drop", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "drop": "encryptedCollection" + }, + "command_name": "drop", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "create": "encryptedCollection.esc", + "clusteredIndex": { + "key": { + "_id": 1 + }, + "unique": true + } + }, + "command_name": "create", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "create": "encryptedCollection.ecc", + "clusteredIndex": { + "key": { + "_id": 1 + }, + "unique": true + } + }, + "command_name": "create", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "create": "encryptedCollection.ecoc", + "clusteredIndex": { + "key": { + "_id": 1 + }, + "unique": true + } + }, + "command_name": "create", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "create": "encryptedCollection", + "encryptedFields": { + "escCollection": "encryptedCollection.esc", + "eccCollection": "encryptedCollection.ecc", + "ecocCollection": "encryptedCollection.ecoc", + "fields": [ + { + "path": "firstName", + "bsonType": "string", + "keyId": { + "$binary": { + "subType": "04", + "base64": "AAAAAAAAAAAAAAAAAAAAAA==" + } + } + } + ] + } + }, + "command_name": "create", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "createIndexes": "encryptedCollection", + "indexes": [ + { + "name": "__safeContent___1", + "key": { + "__safeContent__": 1 + } + } + ] + }, + "command_name": "createIndexes", + "database_name": "default" + } + } + ] + }, + { + "description": "CreateCollection from encryptedFields.", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "dropCollection", + "object": "database", + "arguments": { + "collection": "encryptedCollection", + "encryptedFields": { + "escCollection": "encryptedCollection.esc", + "eccCollection": "encryptedCollection.ecc", + "ecocCollection": "encryptedCollection.ecoc", + "fields": [ + { + "path": "firstName", + "bsonType": "string", + "keyId": { + "$binary": { + "subType": "04", + "base64": "AAAAAAAAAAAAAAAAAAAAAA==" + } + } + } + ] + } + } + }, + { + "name": "createCollection", + "object": "database", + "arguments": { + "collection": "encryptedCollection", + "encryptedFields": { + "escCollection": "encryptedCollection.esc", + "eccCollection": "encryptedCollection.ecc", + "ecocCollection": "encryptedCollection.ecoc", + "fields": [ + { + "path": "firstName", + "bsonType": "string", + "keyId": { + "$binary": { + "subType": "04", + "base64": "AAAAAAAAAAAAAAAAAAAAAA==" + } + } + } + ] + } + } + }, + { + "name": "assertCollectionExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection.esc" + } + }, + { + "name": "assertCollectionExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection.ecc" + } + }, + { + "name": "assertCollectionExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection.ecoc" + } + }, + { + "name": "assertCollectionExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection" + } + }, + { + "name": "assertIndexExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection", + "index": "__safeContent___1" + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "drop": "encryptedCollection.esc" + }, + "command_name": "drop", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "drop": "encryptedCollection.ecc" + }, + "command_name": "drop", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "drop": "encryptedCollection.ecoc" + }, + "command_name": "drop", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "drop": "encryptedCollection" + }, + "command_name": "drop", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "create": "encryptedCollection.esc", + "clusteredIndex": { + "key": { + "_id": 1 + }, + "unique": true + } + }, + "command_name": "create", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "create": "encryptedCollection.ecc", + "clusteredIndex": { + "key": { + "_id": 1 + }, + "unique": true + } + }, + "command_name": "create", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "create": "encryptedCollection.ecoc", + "clusteredIndex": { + "key": { + "_id": 1 + }, + "unique": true + } + }, + "command_name": "create", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "create": "encryptedCollection", + "encryptedFields": { + "escCollection": "encryptedCollection.esc", + "eccCollection": "encryptedCollection.ecc", + "ecocCollection": "encryptedCollection.ecoc", + "fields": [ + { + "path": "firstName", + "bsonType": "string", + "keyId": { + "$binary": { + "subType": "04", + "base64": "AAAAAAAAAAAAAAAAAAAAAA==" + } + } + } + ] + } + }, + "command_name": "create", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "encryptedCollection" + } + }, + "command_name": "listCollections", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "createIndexes": "encryptedCollection", + "indexes": [ + { + "name": "__safeContent___1", + "key": { + "__safeContent__": 1 + } + } + ] + }, + "command_name": "createIndexes", + "database_name": "default" + } + } + ] + }, + { + "description": "DropCollection from encryptedFieldsMap", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + }, + "encryptedFieldsMap": { + "default.encryptedCollection": { + "escCollection": "encryptedCollection.esc", + "eccCollection": "encryptedCollection.ecc", + "ecocCollection": "encryptedCollection.ecoc", + "fields": [ + { + "path": "firstName", + "bsonType": "string", + "keyId": { + "$binary": { + "subType": "04", + "base64": "AAAAAAAAAAAAAAAAAAAAAA==" + } + } + } + ] + } + } + } + }, + "operations": [ + { + "name": "dropCollection", + "object": "database", + "arguments": { + "collection": "encryptedCollection" + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "drop": "encryptedCollection.esc" + }, + "command_name": "drop", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "drop": "encryptedCollection.ecc" + }, + "command_name": "drop", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "drop": "encryptedCollection.ecoc" + }, + "command_name": "drop", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "drop": "encryptedCollection" + }, + "command_name": "drop", + "database_name": "default" + } + } + ] + }, + { + "description": "DropCollection from encryptedFields", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + }, + "encryptedFieldsMap": {} + } + }, + "operations": [ + { + "name": "dropCollection", + "object": "database", + "arguments": { + "collection": "encryptedCollection", + "encryptedFields": { + "escCollection": "encryptedCollection.esc", + "eccCollection": "encryptedCollection.ecc", + "ecocCollection": "encryptedCollection.ecoc", + "fields": [ + { + "path": "firstName", + "bsonType": "string", + "keyId": { + "$binary": { + "subType": "04", + "base64": "AAAAAAAAAAAAAAAAAAAAAA==" + } + } + } + ] + } + } + }, + { + "name": "createCollection", + "object": "database", + "arguments": { + "collection": "encryptedCollection", + "encryptedFields": { + "escCollection": "encryptedCollection.esc", + "eccCollection": "encryptedCollection.ecc", + "ecocCollection": "encryptedCollection.ecoc", + "fields": [ + { + "path": "firstName", + "bsonType": "string", + "keyId": { + "$binary": { + "subType": "04", + "base64": "AAAAAAAAAAAAAAAAAAAAAA==" + } + } + } + ] + } + } + }, + { + "name": "assertCollectionExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection.esc" + } + }, + { + "name": "assertCollectionExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection.ecc" + } + }, + { + "name": "assertCollectionExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection.ecoc" + } + }, + { + "name": "assertCollectionExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection" + } + }, + { + "name": "assertIndexExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection", + "index": "__safeContent___1" + } + }, + { + "name": "dropCollection", + "object": "database", + "arguments": { + "collection": "encryptedCollection", + "encryptedFields": { + "escCollection": "encryptedCollection.esc", + "eccCollection": "encryptedCollection.ecc", + "ecocCollection": "encryptedCollection.ecoc", + "fields": [ + { + "path": "firstName", + "bsonType": "string", + "keyId": { + "$binary": { + "subType": "04", + "base64": "AAAAAAAAAAAAAAAAAAAAAA==" + } + } + } + ] + } + } + }, + { + "name": "assertCollectionNotExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection.esc" + } + }, + { + "name": "assertCollectionNotExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection.ecc" + } + }, + { + "name": "assertCollectionNotExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection.ecoc" + } + }, + { + "name": "assertCollectionNotExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection" + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "drop": "encryptedCollection.esc" + }, + "command_name": "drop", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "drop": "encryptedCollection.ecc" + }, + "command_name": "drop", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "drop": "encryptedCollection.ecoc" + }, + "command_name": "drop", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "drop": "encryptedCollection" + }, + "command_name": "drop", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "create": "encryptedCollection.esc", + "clusteredIndex": { + "key": { + "_id": 1 + }, + "unique": true + } + }, + "command_name": "create", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "create": "encryptedCollection.ecc", + "clusteredIndex": { + "key": { + "_id": 1 + }, + "unique": true + } + }, + "command_name": "create", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "create": "encryptedCollection.ecoc", + "clusteredIndex": { + "key": { + "_id": 1 + }, + "unique": true + } + }, + "command_name": "create", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "create": "encryptedCollection", + "encryptedFields": { + "escCollection": "encryptedCollection.esc", + "eccCollection": "encryptedCollection.ecc", + "ecocCollection": "encryptedCollection.ecoc", + "fields": [ + { + "path": "firstName", + "bsonType": "string", + "keyId": { + "$binary": { + "subType": "04", + "base64": "AAAAAAAAAAAAAAAAAAAAAA==" + } + } + } + ] + } + }, + "command_name": "create", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "encryptedCollection" + } + }, + "command_name": "listCollections", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "createIndexes": "encryptedCollection", + "indexes": [ + { + "name": "__safeContent___1", + "key": { + "__safeContent__": 1 + } + } + ] + }, + "command_name": "createIndexes", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "drop": "encryptedCollection.esc" + }, + "command_name": "drop", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "drop": "encryptedCollection.ecc" + }, + "command_name": "drop", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "drop": "encryptedCollection.ecoc" + }, + "command_name": "drop", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "drop": "encryptedCollection" + }, + "command_name": "drop", + "database_name": "default" + } + } + ] + }, + { + "description": "DropCollection from remote encryptedFields", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + }, + "encryptedFieldsMap": {} + } + }, + "operations": [ + { + "name": "dropCollection", + "object": "database", + "arguments": { + "collection": "encryptedCollection", + "encryptedFields": { + "escCollection": "encryptedCollection.esc", + "eccCollection": "encryptedCollection.ecc", + "ecocCollection": "encryptedCollection.ecoc", + "fields": [ + { + "path": "firstName", + "bsonType": "string", + "keyId": { + "$binary": { + "subType": "04", + "base64": "AAAAAAAAAAAAAAAAAAAAAA==" + } + } + } + ] + } + } + }, + { + "name": "createCollection", + "object": "database", + "arguments": { + "collection": "encryptedCollection", + "encryptedFields": { + "escCollection": "encryptedCollection.esc", + "eccCollection": "encryptedCollection.ecc", + "ecocCollection": "encryptedCollection.ecoc", + "fields": [ + { + "path": "firstName", + "bsonType": "string", + "keyId": { + "$binary": { + "subType": "04", + "base64": "AAAAAAAAAAAAAAAAAAAAAA==" + } + } + } + ] + } + } + }, + { + "name": "assertCollectionExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection.esc" + } + }, + { + "name": "assertCollectionExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection.ecc" + } + }, + { + "name": "assertCollectionExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection.ecoc" + } + }, + { + "name": "assertCollectionExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection" + } + }, + { + "name": "assertIndexExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection", + "index": "__safeContent___1" + } + }, + { + "name": "dropCollection", + "object": "database", + "arguments": { + "collection": "encryptedCollection" + } + }, + { + "name": "assertCollectionNotExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection.esc" + } + }, + { + "name": "assertCollectionNotExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection.ecc" + } + }, + { + "name": "assertCollectionNotExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection.ecoc" + } + }, + { + "name": "assertCollectionNotExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection" + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "drop": "encryptedCollection.esc" + }, + "command_name": "drop", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "drop": "encryptedCollection.ecc" + }, + "command_name": "drop", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "drop": "encryptedCollection.ecoc" + }, + "command_name": "drop", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "drop": "encryptedCollection" + }, + "command_name": "drop", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "create": "encryptedCollection.esc", + "clusteredIndex": { + "key": { + "_id": 1 + }, + "unique": true + } + }, + "command_name": "create", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "create": "encryptedCollection.ecc", + "clusteredIndex": { + "key": { + "_id": 1 + }, + "unique": true + } + }, + "command_name": "create", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "create": "encryptedCollection.ecoc", + "clusteredIndex": { + "key": { + "_id": 1 + }, + "unique": true + } + }, + "command_name": "create", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "create": "encryptedCollection", + "encryptedFields": { + "escCollection": "encryptedCollection.esc", + "eccCollection": "encryptedCollection.ecc", + "ecocCollection": "encryptedCollection.ecoc", + "fields": [ + { + "path": "firstName", + "bsonType": "string", + "keyId": { + "$binary": { + "subType": "04", + "base64": "AAAAAAAAAAAAAAAAAAAAAA==" + } + } + } + ] + } + }, + "command_name": "create", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "encryptedCollection" + } + }, + "command_name": "listCollections", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "createIndexes": "encryptedCollection", + "indexes": [ + { + "name": "__safeContent___1", + "key": { + "__safeContent__": 1 + } + } + ] + }, + "command_name": "createIndexes", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "encryptedCollection" + } + }, + "command_name": "listCollections", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "drop": "encryptedCollection.esc" + }, + "command_name": "drop", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "drop": "encryptedCollection.ecc" + }, + "command_name": "drop", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "drop": "encryptedCollection.ecoc" + }, + "command_name": "drop", + "database_name": "default" + } + }, + { + "command_started_event": { + "command": { + "drop": "encryptedCollection" + }, + "command_name": "drop", + "database_name": "default" + } + } + ] + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/fle2-CreateCollection.yml b/src/test/spec/json/client-side-encryption/legacy/fle2-CreateCollection.yml new file mode 100644 index 000000000..78d7e55e0 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/fle2-CreateCollection.yml @@ -0,0 +1,1263 @@ +# This test requires libmongocrypt 1.5.0-alpha2. +runOn: + - minServerVersion: "6.0.0" + # FLE 2 Encrypted collections are not supported on standalone. + topology: [ "replicaset", "sharded", "load-balanced" ] + +database_name: &database_name "default" +collection_name: &collection_name "default" + +tests: + - description: "state collections and index are created" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + encryptedFieldsMap: + default.encryptedCollection: &encrypted_fields0 { + "escCollection": "encryptedCollection.esc", + "eccCollection": "encryptedCollection.ecc", + "ecocCollection": "encryptedCollection.ecoc", + "fields": [ + { + "path": "firstName", + "bsonType": "string", + "keyId": { "$binary": { "subType": "04", "base64": "AAAAAAAAAAAAAAAAAAAAAA==" }} + } + ] + } + + operations: + # Do an initial drop to remove collections that may exist from previous test runs. + - name: dropCollection + object: database + arguments: + collection: "encryptedCollection" + - name: createCollection + object: database + arguments: + collection: "encryptedCollection" + - name: assertCollectionExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection.esc" + - name: assertCollectionExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection.ecc" + - name: assertCollectionExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection.ecoc" + - name: assertCollectionExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection" + - name: assertIndexExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection" + index: __safeContent___1 + + expectations: + # events from dropCollection ... begin + - command_started_event: + command: + drop: "encryptedCollection.esc" + command_name: drop + database_name: *database_name + - command_started_event: + command: + drop: "encryptedCollection.ecc" + command_name: drop + database_name: *database_name + - command_started_event: + command: + drop: "encryptedCollection.ecoc" + command_name: drop + database_name: *database_name + - command_started_event: + command: + drop: "encryptedCollection" + command_name: drop + database_name: *database_name + # events from dropCollection ... end + # events from createCollection ... begin + # State collections are created first. + - command_started_event: + command: + create: "encryptedCollection.esc" + clusteredIndex: {key: {_id: 1}, unique: true} + command_name: create + database_name: *database_name + - command_started_event: + command: + create: "encryptedCollection.ecc" + clusteredIndex: {key: {_id: 1}, unique: true} + command_name: create + database_name: *database_name + - command_started_event: + command: + create: "encryptedCollection.ecoc" + clusteredIndex: {key: {_id: 1}, unique: true} + command_name: create + database_name: *database_name + # Data collection is created after. + - command_started_event: + command: + create: "encryptedCollection" + encryptedFields: *encrypted_fields0 + command_name: create + database_name: *database_name + # Index on __safeContents__ is then created. + - command_started_event: + command: + createIndexes: "encryptedCollection" + indexes: + - name: __safeContent___1 + key: { __safeContent__: 1 } + command_name: createIndexes + database_name: *database_name + # events from createCollection ... end + - description: "default state collection names are applied" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + encryptedFieldsMap: + default.encryptedCollection: &encrypted_fields1 { + "fields": [ + { + "path": "firstName", + "bsonType": "string", + "keyId": { "$binary": { "subType": "04", "base64": "AAAAAAAAAAAAAAAAAAAAAA==" }}, + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + } + ] + } + + operations: + # Do an initial drop to remove collections that may exist from previous test runs. + - name: dropCollection + object: database + arguments: + collection: "encryptedCollection" + - name: createCollection + object: database + arguments: + collection: "encryptedCollection" + - name: assertCollectionExists + object: testRunner + arguments: + database: *database_name + collection: "enxcol_.encryptedCollection.esc" + - name: assertCollectionExists + object: testRunner + arguments: + database: *database_name + collection: "enxcol_.encryptedCollection.ecc" + - name: assertCollectionExists + object: testRunner + arguments: + database: *database_name + collection: "enxcol_.encryptedCollection.ecoc" + - name: assertCollectionExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection" + - name: assertIndexExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection" + index: __safeContent___1 + + expectations: + # events from dropCollection ... begin + - command_started_event: + command: + drop: "enxcol_.encryptedCollection.esc" + command_name: drop + database_name: *database_name + - command_started_event: + command: + drop: "enxcol_.encryptedCollection.ecc" + command_name: drop + database_name: *database_name + - command_started_event: + command: + drop: "enxcol_.encryptedCollection.ecoc" + command_name: drop + database_name: *database_name + - command_started_event: + command: + drop: "encryptedCollection" + command_name: drop + database_name: *database_name + # events from dropCollection ... end + # events from createCollection ... begin + # State collections are created first. + - command_started_event: + command: + create: "enxcol_.encryptedCollection.esc" + clusteredIndex: {key: {_id: 1}, unique: true} + command_name: create + database_name: *database_name + - command_started_event: + command: + create: "enxcol_.encryptedCollection.ecc" + clusteredIndex: {key: {_id: 1}, unique: true} + command_name: create + database_name: *database_name + - command_started_event: + command: + create: "enxcol_.encryptedCollection.ecoc" + clusteredIndex: {key: {_id: 1}, unique: true} + command_name: create + database_name: *database_name + # Data collection is created after. + - command_started_event: + command: + create: "encryptedCollection" + encryptedFields: *encrypted_fields1 + command_name: create + database_name: *database_name + # Index on __safeContents__ is then created. + - command_started_event: + command: + createIndexes: "encryptedCollection" + indexes: + - name: __safeContent___1 + key: { __safeContent__: 1 } + command_name: createIndexes + database_name: *database_name + # events from createCollection ... end + - description: "drop removes all state collections" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + encryptedFieldsMap: + default.encryptedCollection: &encrypted_fields2 { + "fields": [ + { + "path": "firstName", + "bsonType": "string", + "keyId": { "$binary": { "subType": "04", "base64": "AAAAAAAAAAAAAAAAAAAAAA==" }}, + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + } + ] + } + + operations: + # Do an initial drop to remove collections that may exist from previous test runs. + - name: dropCollection + object: database + arguments: + collection: "encryptedCollection" + - name: createCollection + object: database + arguments: + collection: "encryptedCollection" + - name: assertCollectionExists + object: testRunner + arguments: + database: *database_name + collection: "enxcol_.encryptedCollection.esc" + - name: assertCollectionExists + object: testRunner + arguments: + database: *database_name + collection: "enxcol_.encryptedCollection.ecc" + - name: assertCollectionExists + object: testRunner + arguments: + database: *database_name + collection: "enxcol_.encryptedCollection.ecoc" + - name: assertCollectionExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection" + - name: assertIndexExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection" + index: __safeContent___1 + - name: dropCollection + object: database + arguments: + collection: "encryptedCollection" + - name: assertCollectionNotExists + object: testRunner + arguments: + database: *database_name + collection: "enxcol_.encryptedCollection.ecc" + - name: assertCollectionNotExists + object: testRunner + arguments: + database: *database_name + collection: "enxcol_.encryptedCollection.ecoc" + - name: assertCollectionNotExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection" + - name: assertIndexNotExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection" + index: __safeContent___1 + + expectations: + # events from dropCollection ... begin + - command_started_event: + command: + drop: "enxcol_.encryptedCollection.esc" + command_name: drop + database_name: *database_name + - command_started_event: + command: + drop: "enxcol_.encryptedCollection.ecc" + command_name: drop + database_name: *database_name + - command_started_event: + command: + drop: "enxcol_.encryptedCollection.ecoc" + command_name: drop + database_name: *database_name + - command_started_event: + command: + drop: "encryptedCollection" + command_name: drop + database_name: *database_name + # events from dropCollection ... end + # events from createCollection ... begin + # State collections are created first. + - command_started_event: + command: + create: "enxcol_.encryptedCollection.esc" + clusteredIndex: {key: {_id: 1}, unique: true} + command_name: create + database_name: *database_name + - command_started_event: + command: + create: "enxcol_.encryptedCollection.ecc" + clusteredIndex: {key: {_id: 1}, unique: true} + command_name: create + database_name: *database_name + - command_started_event: + command: + create: "enxcol_.encryptedCollection.ecoc" + clusteredIndex: {key: {_id: 1}, unique: true} + command_name: create + database_name: *database_name + # Data collection is created after. + - command_started_event: + command: + create: "encryptedCollection" + encryptedFields: *encrypted_fields2 + command_name: create + database_name: *database_name + # Index on __safeContents__ is then created. + - command_started_event: + command: + createIndexes: "encryptedCollection" + indexes: + - name: __safeContent___1 + key: { __safeContent__: 1 } + command_name: createIndexes + database_name: *database_name + # events from createCollection ... end + # events from dropCollection ... begin + - command_started_event: + command: + drop: "enxcol_.encryptedCollection.esc" + command_name: drop + database_name: *database_name + - command_started_event: + command: + drop: "enxcol_.encryptedCollection.ecc" + command_name: drop + database_name: *database_name + - command_started_event: + command: + drop: "enxcol_.encryptedCollection.ecoc" + command_name: drop + database_name: *database_name + - command_started_event: + command: + drop: "encryptedCollection" + command_name: drop + database_name: *database_name + # events from dropCollection ... end + - description: "encryptedFieldsMap with cyclic entries does not loop" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + encryptedFieldsMap: + # encryptedCollection has encryptedCollection.esc as the escCollection. + # encryptedCollection.esc has encryptedCollection as the escCollection. + default.encryptedCollection: &encrypted_fields3 { + "escCollection": "encryptedCollection.esc", + "eccCollection": "encryptedCollection.ecc", + "ecocCollection": "encryptedCollection.ecoc", + "fields": [ + { + "path": "firstName", + "bsonType": "string", + "keyId": { "$binary": { "subType": "04", "base64": "AAAAAAAAAAAAAAAAAAAAAA==" }} + } + ] + } + default.encryptedCollection.esc: { + "escCollection": "encryptedCollection", + "eccCollection": "encryptedCollection.ecc", + "ecocCollection": "encryptedCollection.ecoc", + "fields": [ + { + "path": "firstName", + "bsonType": "string", + "keyId": { "$binary": { "subType": "04", "base64": "AAAAAAAAAAAAAAAAAAAAAA==" }} + } + ] + } + operations: + # Do an initial drop to remove collections that may exist from previous test runs. + - name: dropCollection + object: database + arguments: + collection: "encryptedCollection" + - name: createCollection + object: database + arguments: + collection: "encryptedCollection" + - name: assertCollectionExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection.esc" + - name: assertCollectionExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection.ecc" + - name: assertCollectionExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection.ecoc" + - name: assertCollectionExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection" + - name: assertIndexExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection" + index: __safeContent___1 + expectations: + # events from dropCollection ... begin + - command_started_event: + command: + drop: "encryptedCollection.esc" + command_name: drop + database_name: *database_name + - command_started_event: + command: + drop: "encryptedCollection.ecc" + command_name: drop + database_name: *database_name + - command_started_event: + command: + drop: "encryptedCollection.ecoc" + command_name: drop + database_name: *database_name + - command_started_event: + command: + drop: "encryptedCollection" + command_name: drop + database_name: *database_name + # events from dropCollection ... end + # events from createCollection ... begin + # State collections are created first. + - command_started_event: + command: + create: "encryptedCollection.esc" + clusteredIndex: {key: {_id: 1}, unique: true} + command_name: create + database_name: *database_name + - command_started_event: + command: + create: "encryptedCollection.ecc" + clusteredIndex: {key: {_id: 1}, unique: true} + command_name: create + database_name: *database_name + - command_started_event: + command: + create: "encryptedCollection.ecoc" + clusteredIndex: {key: {_id: 1}, unique: true} + command_name: create + database_name: *database_name + # Data collection is created after. + - command_started_event: + command: + create: "encryptedCollection" + encryptedFields: *encrypted_fields3 + command_name: create + database_name: *database_name + # Index on __safeContents__ is then created. + - command_started_event: + command: + createIndexes: "encryptedCollection" + indexes: + - name: __safeContent___1 + key: { __safeContent__: 1 } + command_name: createIndexes + database_name: *database_name + # events from createCollection ... end + - description: "CreateCollection without encryptedFields." + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + encryptedFieldsMap: + default.encryptedCollection: { + "escCollection": "encryptedCollection.esc", + "eccCollection": "encryptedCollection.ecc", + "ecocCollection": "encryptedCollection.ecoc", + "fields": [ + { + "path": "firstName", + "bsonType": "string", + "keyId": { "$binary": { "subType": "04", "base64": "AAAAAAAAAAAAAAAAAAAAAA==" }} + } + ] + } + operations: + # Do an initial drop to remove collections that may exist from previous test runs. + - name: dropCollection + object: database + arguments: + collection: "plaintextCollection" + - name: createCollection + object: database + arguments: + collection: "plaintextCollection" + - name: assertCollectionExists + object: testRunner + arguments: + database: *database_name + collection: "plaintextCollection" + + expectations: + # events from dropCollection ... begin + # expect listCollections to be sent on drop to check for remote encryptedFields. + - command_started_event: + command: + listCollections: 1 + filter: { name: "plaintextCollection" } + command_name: listCollections + database_name: *database_name + - command_started_event: + command: + drop: "plaintextCollection" + command_name: drop + database_name: *database_name + # events from dropCollection ... end + - command_started_event: + command: + create: "plaintextCollection" + command_name: create + database_name: *database_name + - description: "CreateCollection from encryptedFieldsMap." + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + encryptedFieldsMap: + default.encryptedCollection: &encrypted_fields4 { + "escCollection": "encryptedCollection.esc", + "eccCollection": "encryptedCollection.ecc", + "ecocCollection": "encryptedCollection.ecoc", + "fields": [ + { + "path": "firstName", + "bsonType": "string", + "keyId": { "$binary": { "subType": "04", "base64": "AAAAAAAAAAAAAAAAAAAAAA==" }} + } + ] + } + operations: + # Do an initial drop to remove collections that may exist from previous test runs. + - name: dropCollection + object: database + arguments: + collection: "encryptedCollection" + - name: createCollection + object: database + arguments: + collection: "encryptedCollection" + - name: assertCollectionExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection.esc" + - name: assertCollectionExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection.ecc" + - name: assertCollectionExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection.ecoc" + - name: assertCollectionExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection" + - name: assertIndexExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection" + index: __safeContent___1 + + expectations: + # events from dropCollection ... begin + - command_started_event: + command: + drop: "encryptedCollection.esc" + command_name: drop + database_name: *database_name + - command_started_event: + command: + drop: "encryptedCollection.ecc" + command_name: drop + database_name: *database_name + - command_started_event: + command: + drop: "encryptedCollection.ecoc" + command_name: drop + database_name: *database_name + - command_started_event: + command: + drop: "encryptedCollection" + command_name: drop + database_name: *database_name + # events from dropCollection ... end + # events from createCollection ... begin + # State collections are created first. + - command_started_event: + command: + create: "encryptedCollection.esc" + clusteredIndex: {key: {_id: 1}, unique: true} + command_name: create + database_name: *database_name + - command_started_event: + command: + create: "encryptedCollection.ecc" + clusteredIndex: {key: {_id: 1}, unique: true} + command_name: create + database_name: *database_name + - command_started_event: + command: + create: "encryptedCollection.ecoc" + clusteredIndex: {key: {_id: 1}, unique: true} + command_name: create + database_name: *database_name + # Data collection is created after. + - command_started_event: + command: + create: "encryptedCollection" + encryptedFields: *encrypted_fields4 + command_name: create + database_name: *database_name + # Index on __safeContents__ is then created. + - command_started_event: + command: + createIndexes: "encryptedCollection" + indexes: + - name: __safeContent___1 + key: { __safeContent__: 1 } + command_name: createIndexes + database_name: *database_name + # events from createCollection ... end + - description: "CreateCollection from encryptedFields." + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + # Do initial drops to remove collections that may exist from previous test runs. + - name: dropCollection + object: database + arguments: + collection: "encryptedCollection" + encryptedFields: { + "escCollection": "encryptedCollection.esc", + "eccCollection": "encryptedCollection.ecc", + "ecocCollection": "encryptedCollection.ecoc", + "fields": [ + { + "path": "firstName", + "bsonType": "string", + "keyId": { "$binary": { "subType": "04", "base64": "AAAAAAAAAAAAAAAAAAAAAA==" }} + } + ] + } + - name: createCollection + object: database + arguments: + collection: "encryptedCollection" + encryptedFields: &encrypted_fields5 { + "escCollection": "encryptedCollection.esc", + "eccCollection": "encryptedCollection.ecc", + "ecocCollection": "encryptedCollection.ecoc", + "fields": [ + { + "path": "firstName", + "bsonType": "string", + "keyId": { "$binary": { "subType": "04", "base64": "AAAAAAAAAAAAAAAAAAAAAA==" }} + } + ] + } + - name: assertCollectionExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection.esc" + - name: assertCollectionExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection.ecc" + - name: assertCollectionExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection.ecoc" + - name: assertCollectionExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection" + - name: assertIndexExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection" + index: __safeContent___1 + + expectations: + # events from dropCollection ... begin + - command_started_event: + command: + drop: "encryptedCollection.esc" + command_name: drop + database_name: *database_name + - command_started_event: + command: + drop: "encryptedCollection.ecc" + command_name: drop + database_name: *database_name + - command_started_event: + command: + drop: "encryptedCollection.ecoc" + command_name: drop + database_name: *database_name + - command_started_event: + command: + drop: "encryptedCollection" + command_name: drop + database_name: *database_name + # events from dropCollection ... end + # events from createCollection ... begin + # State collections are created first. + - command_started_event: + command: + create: "encryptedCollection.esc" + clusteredIndex: {key: {_id: 1}, unique: true} + command_name: create + database_name: *database_name + - command_started_event: + command: + create: "encryptedCollection.ecc" + clusteredIndex: {key: {_id: 1}, unique: true} + command_name: create + database_name: *database_name + - command_started_event: + command: + create: "encryptedCollection.ecoc" + clusteredIndex: {key: {_id: 1}, unique: true} + command_name: create + database_name: *database_name + # Data collection is created after. + - command_started_event: + command: + create: "encryptedCollection" + encryptedFields: *encrypted_fields5 + command_name: create + database_name: *database_name + # libmongocrypt requests listCollections to get a schema for the "createIndexes" command. + - command_started_event: + command: + listCollections: 1 + filter: { name: "encryptedCollection" } + command_name: listCollections + database_name: *database_name + # Index on __safeContents__ is then created. + - command_started_event: + command: + createIndexes: "encryptedCollection" + indexes: + - name: __safeContent___1 + key: { __safeContent__: 1 } + command_name: createIndexes + database_name: *database_name + # events from createCollection ... end + + - description: "DropCollection from encryptedFieldsMap" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + encryptedFieldsMap: + default.encryptedCollection: { + "escCollection": "encryptedCollection.esc", + "eccCollection": "encryptedCollection.ecc", + "ecocCollection": "encryptedCollection.ecoc", + "fields": [ + { + "path": "firstName", + "bsonType": "string", + "keyId": { "$binary": { "subType": "04", "base64": "AAAAAAAAAAAAAAAAAAAAAA==" }} + } + ] + } + operations: + - name: dropCollection + object: database + arguments: + collection: "encryptedCollection" + expectations: + # events from dropCollection ... begin + - command_started_event: + command: + drop: "encryptedCollection.esc" + command_name: drop + database_name: *database_name + - command_started_event: + command: + drop: "encryptedCollection.ecc" + command_name: drop + database_name: *database_name + - command_started_event: + command: + drop: "encryptedCollection.ecoc" + command_name: drop + database_name: *database_name + - command_started_event: + command: + drop: "encryptedCollection" + command_name: drop + database_name: *database_name + # events from dropCollection ... end + - description: "DropCollection from encryptedFields" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + encryptedFieldsMap: {} + operations: + # Do initial drops to remove collections that may exist from previous test runs. + - name: dropCollection + object: database + arguments: + collection: "encryptedCollection" + encryptedFields: { + "escCollection": "encryptedCollection.esc", + "eccCollection": "encryptedCollection.ecc", + "ecocCollection": "encryptedCollection.ecoc", + "fields": [ + { + "path": "firstName", + "bsonType": "string", + "keyId": { "$binary": { "subType": "04", "base64": "AAAAAAAAAAAAAAAAAAAAAA==" }} + } + ] + } + - name: createCollection + object: database + arguments: + collection: "encryptedCollection" + encryptedFields: { + "escCollection": "encryptedCollection.esc", + "eccCollection": "encryptedCollection.ecc", + "ecocCollection": "encryptedCollection.ecoc", + "fields": [ + { + "path": "firstName", + "bsonType": "string", + "keyId": { "$binary": { "subType": "04", "base64": "AAAAAAAAAAAAAAAAAAAAAA==" }} + } + ] + } + - name: assertCollectionExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection.esc" + - name: assertCollectionExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection.ecc" + - name: assertCollectionExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection.ecoc" + - name: assertCollectionExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection" + - name: assertIndexExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection" + index: __safeContent___1 + - name: dropCollection + object: database + arguments: + collection: "encryptedCollection" + encryptedFields: &encrypted_fields6 { + "escCollection": "encryptedCollection.esc", + "eccCollection": "encryptedCollection.ecc", + "ecocCollection": "encryptedCollection.ecoc", + "fields": [ + { + "path": "firstName", + "bsonType": "string", + "keyId": { "$binary": { "subType": "04", "base64": "AAAAAAAAAAAAAAAAAAAAAA==" }} + } + ] + } + - name: assertCollectionNotExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection.esc" + - name: assertCollectionNotExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection.ecc" + - name: assertCollectionNotExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection.ecoc" + - name: assertCollectionNotExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection" + expectations: + # events from dropCollection ... begin + - command_started_event: + command: + drop: "encryptedCollection.esc" + command_name: drop + database_name: *database_name + - command_started_event: + command: + drop: "encryptedCollection.ecc" + command_name: drop + database_name: *database_name + - command_started_event: + command: + drop: "encryptedCollection.ecoc" + command_name: drop + database_name: *database_name + - command_started_event: + command: + drop: "encryptedCollection" + command_name: drop + database_name: *database_name + # events from dropCollection ... end + # events from createCollection ... begin + - command_started_event: + command: + create: "encryptedCollection.esc" + clusteredIndex: {key: {_id: 1}, unique: true} + command_name: create + database_name: *database_name + - command_started_event: + command: + create: "encryptedCollection.ecc" + clusteredIndex: {key: {_id: 1}, unique: true} + command_name: create + database_name: *database_name + - command_started_event: + command: + create: "encryptedCollection.ecoc" + clusteredIndex: {key: {_id: 1}, unique: true} + command_name: create + database_name: *database_name + - command_started_event: + command: + create: "encryptedCollection" + encryptedFields: *encrypted_fields6 + command_name: create + database_name: *database_name + # libmongocrypt requests listCollections to get a schema for the "createIndexes" command. + - command_started_event: + command: + listCollections: 1 + filter: { name: "encryptedCollection" } + command_name: listCollections + database_name: *database_name + # Index on __safeContents__ is then created. + - command_started_event: + command: + createIndexes: "encryptedCollection" + indexes: + - name: __safeContent___1 + key: { __safeContent__: 1 } + command_name: createIndexes + database_name: *database_name + # events from createCollection ... end + # events from dropCollection ... begin + - command_started_event: + command: + drop: "encryptedCollection.esc" + command_name: drop + database_name: *database_name + - command_started_event: + command: + drop: "encryptedCollection.ecc" + command_name: drop + database_name: *database_name + - command_started_event: + command: + drop: "encryptedCollection.ecoc" + command_name: drop + database_name: *database_name + - command_started_event: + command: + drop: "encryptedCollection" + command_name: drop + database_name: *database_name + # events from dropCollection ... end + + - description: "DropCollection from remote encryptedFields" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + encryptedFieldsMap: {} + + operations: + # Do initial drops to remove collections that may exist from previous test runs. + - name: dropCollection + object: database + arguments: + collection: "encryptedCollection" + encryptedFields: { + "escCollection": "encryptedCollection.esc", + "eccCollection": "encryptedCollection.ecc", + "ecocCollection": "encryptedCollection.ecoc", + "fields": [ + { + "path": "firstName", + "bsonType": "string", + "keyId": { "$binary": { "subType": "04", "base64": "AAAAAAAAAAAAAAAAAAAAAA==" }} + } + ] + } + - name: createCollection + object: database + arguments: + collection: "encryptedCollection" + encryptedFields: &encrypted_fields7 { + "escCollection": "encryptedCollection.esc", + "eccCollection": "encryptedCollection.ecc", + "ecocCollection": "encryptedCollection.ecoc", + "fields": [ + { + "path": "firstName", + "bsonType": "string", + "keyId": { "$binary": { "subType": "04", "base64": "AAAAAAAAAAAAAAAAAAAAAA==" }} + } + ] + } + - name: assertCollectionExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection.esc" + - name: assertCollectionExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection.ecc" + - name: assertCollectionExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection.ecoc" + - name: assertCollectionExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection" + - name: assertIndexExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection" + index: __safeContent___1 + - name: dropCollection + object: database + arguments: + collection: "encryptedCollection" + - name: assertCollectionNotExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection.esc" + - name: assertCollectionNotExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection.ecc" + - name: assertCollectionNotExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection.ecoc" + - name: assertCollectionNotExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection" + + expectations: + # events from dropCollection ... begin + - command_started_event: + command: + drop: "encryptedCollection.esc" + command_name: drop + database_name: *database_name + - command_started_event: + command: + drop: "encryptedCollection.ecc" + command_name: drop + database_name: *database_name + - command_started_event: + command: + drop: "encryptedCollection.ecoc" + command_name: drop + database_name: *database_name + - command_started_event: + command: + drop: "encryptedCollection" + command_name: drop + database_name: *database_name + # events from dropCollection ... end + # events from createCollection ... begin + - command_started_event: + command: + create: "encryptedCollection.esc" + clusteredIndex: {key: {_id: 1}, unique: true} + command_name: create + database_name: *database_name + - command_started_event: + command: + create: "encryptedCollection.ecc" + clusteredIndex: {key: {_id: 1}, unique: true} + command_name: create + database_name: *database_name + - command_started_event: + command: + create: "encryptedCollection.ecoc" + clusteredIndex: {key: {_id: 1}, unique: true} + command_name: create + database_name: *database_name + - command_started_event: + command: + create: "encryptedCollection" + encryptedFields: *encrypted_fields7 + command_name: create + database_name: *database_name + # libmongocrypt requests listCollections to get a schema for the "createIndexes" command. + - command_started_event: + command: + listCollections: 1 + filter: { name: "encryptedCollection" } + command_name: listCollections + database_name: *database_name + # Index on __safeContents__ is then created. + - command_started_event: + command: + createIndexes: "encryptedCollection" + indexes: + - name: __safeContent___1 + key: { __safeContent__: 1 } + command_name: createIndexes + database_name: *database_name + # events from createCollection ... end + # events from dropCollection ... begin + - command_started_event: + command: + listCollections: 1 + filter: { name: "encryptedCollection" } + command_name: listCollections + database_name: *database_name + - command_started_event: + command: + drop: "encryptedCollection.esc" + command_name: drop + database_name: *database_name + - command_started_event: + command: + drop: "encryptedCollection.ecc" + command_name: drop + database_name: *database_name + - command_started_event: + command: + drop: "encryptedCollection.ecoc" + command_name: drop + database_name: *database_name + - command_started_event: + command: + drop: "encryptedCollection" + command_name: drop + database_name: *database_name + # events from dropCollection ... end diff --git a/src/test/spec/json/client-side-encryption/legacy/fle2-DecryptExistingData.json b/src/test/spec/json/client-side-encryption/legacy/fle2-DecryptExistingData.json new file mode 100644 index 000000000..e622d3334 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/fle2-DecryptExistingData.json @@ -0,0 +1,149 @@ +{ + "runOn": [ + { + "minServerVersion": "6.0.0", + "topology": [ + "replicaset", + "sharded", + "load-balanced" + ] + } + ], + "database_name": "default", + "collection_name": "default", + "data": [ + { + "_id": 1, + "encryptedUnindexed": { + "$binary": { + "base64": "BqvN76sSNJh2EjQSNFZ4kBICTQaVZPWgXp41I7mPV1rLFTtw1tXzjcdSEyxpKKqujlko5TeizkB9hHQ009dVY1+fgIiDcefh+eQrm3CkhQ==", + "subType": "06" + } + } + } + ], + "key_vault_data": [ + { + "_id": { + "$binary": { + "base64": "q83vqxI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "keyMaterial": { + "$binary": { + "base64": "HBk9BWihXExNDvTp1lUxOuxuZK2Pe2ZdVdlsxPEBkiO1bS4mG5NNDsQ7zVxJAH8BtdOYp72Ku4Y3nwc0BUpIKsvAKX4eYXtlhv5zUQxWdeNFhg9qK7qb8nqhnnLeT0f25jFSqzWJoT379hfwDeu0bebJHr35QrJ8myZdPMTEDYF08QYQ48ShRBli0S+QzBHHAQiM2iJNr4svg2WR8JSeWQ==", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1648914851981" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1648914851981" + } + }, + "status": { + "$numberInt": "0" + }, + "masterKey": { + "provider": "local" + } + } + ], + "tests": [ + { + "description": "FLE2 decrypt of existing data succeeds", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "local": { + "key": { + "$binary": { + "base64": "Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk", + "subType": "00" + } + } + } + } + } + }, + "operations": [ + { + "name": "find", + "arguments": { + "filter": { + "_id": 1 + } + }, + "result": [ + { + "_id": 1, + "encryptedUnindexed": "value123" + } + ] + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "default" + } + }, + "command_name": "listCollections" + } + }, + { + "command_started_event": { + "command": { + "find": "default", + "filter": { + "_id": 1 + } + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "q83vqxI0mHYSNBI0VniQEg==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + } + ] + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/fle2-DecryptExistingData.yml b/src/test/spec/json/client-side-encryption/legacy/fle2-DecryptExistingData.yml new file mode 100644 index 000000000..d1d0e2384 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/fle2-DecryptExistingData.yml @@ -0,0 +1,64 @@ +runOn: + - minServerVersion: "6.0.0" + # FLE 2 Encrypted collections are not supported on standalone. + topology: [ "replicaset", "sharded", "load-balanced" ] +database_name: &database_name "default" +collection_name: &collection_name "default" +data: [ + &doc0 { + "_id": 1, + "encryptedUnindexed": { + "$binary": { + "base64": "BqvN76sSNJh2EjQSNFZ4kBICTQaVZPWgXp41I7mPV1rLFTtw1tXzjcdSEyxpKKqujlko5TeizkB9hHQ009dVY1+fgIiDcefh+eQrm3CkhQ==", + "subType": "06" + } + } + } +] +key_vault_data: [ {'_id': {'$binary': {'base64': 'q83vqxI0mHYSNBI0VniQEg==', 'subType': '04'}}, 'keyMaterial': {'$binary': {'base64': 'HBk9BWihXExNDvTp1lUxOuxuZK2Pe2ZdVdlsxPEBkiO1bS4mG5NNDsQ7zVxJAH8BtdOYp72Ku4Y3nwc0BUpIKsvAKX4eYXtlhv5zUQxWdeNFhg9qK7qb8nqhnnLeT0f25jFSqzWJoT379hfwDeu0bebJHr35QrJ8myZdPMTEDYF08QYQ48ShRBli0S+QzBHHAQiM2iJNr4svg2WR8JSeWQ==', 'subType': '00'}}, 'creationDate': {'$date': {'$numberLong': '1648914851981'}}, 'updateDate': {'$date': {'$numberLong': '1648914851981'}}, 'status': {'$numberInt': '0'}, 'masterKey': {'provider': 'local'}}] +tests: + - description: "FLE2 decrypt of existing data succeeds" + clientOptions: + autoEncryptOpts: + kmsProviders: + local: {'key': {'$binary': {'base64': 'Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk', 'subType': '00'}}} + operations: + - name: find + arguments: + filter: { _id: 1 } + result: + [{ "_id": 1, "encryptedUnindexed": "value123" }] + expectations: + - command_started_event: + command: + listCollections: 1 + filter: + name: *collection_name + command_name: listCollections + - command_started_event: + command: + find: *collection_name + filter: { "_id": 1 } + command_name: find + - command_started_event: + command: + find: datakeys + filter: { + "$or": [ + { + "_id": { + "$in": [ + {'$binary': {'base64': 'q83vqxI0mHYSNBI0VniQEg==', 'subType': '04'}} + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + } + $db: keyvault + readConcern: { level: "majority" } + command_name: find \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/fle2-Delete.json b/src/test/spec/json/client-side-encryption/legacy/fle2-Delete.json new file mode 100644 index 000000000..868712774 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/fle2-Delete.json @@ -0,0 +1,306 @@ +{ + "runOn": [ + { + "minServerVersion": "6.0.0", + "topology": [ + "replicaset", + "sharded", + "load-balanced" + ] + } + ], + "database_name": "default", + "collection_name": "default", + "data": [], + "encrypted_fields": { + "escCollection": "enxcol_.default.esc", + "eccCollection": "enxcol_.default.ecc", + "ecocCollection": "enxcol_.default.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedIndexed", + "bsonType": "string", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + }, + { + "keyId": { + "$binary": { + "base64": "q83vqxI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedUnindexed", + "bsonType": "string" + } + ] + }, + "key_vault_data": [ + { + "_id": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "keyMaterial": { + "$binary": { + "base64": "sHe0kz57YW7v8g9VP9sf/+K1ex4JqKc5rf/URX3n3p8XdZ6+15uXPaSayC6adWbNxkFskuMCOifDoTT+rkqMtFkDclOy884RuGGtUysq3X7zkAWYTKi8QAfKkajvVbZl2y23UqgVasdQu3OVBQCrH/xY00nNAs/52e958nVjBuzQkSb1T8pKJAyjZsHJ60+FtnfafDZSTAIBJYn7UWBCwQ==", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1648914851981" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1648914851981" + } + }, + "status": { + "$numberInt": "0" + }, + "masterKey": { + "provider": "local" + } + } + ], + "tests": [ + { + "description": "Delete can query an FLE2 indexed field", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "local": { + "key": { + "$binary": { + "base64": "Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk", + "subType": "00" + } + } + } + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encryptedIndexed": "value123" + } + } + }, + { + "name": "deleteOne", + "arguments": { + "filter": { + "encryptedIndexed": "value123" + } + }, + "result": { + "deletedCount": 1 + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "default" + } + }, + "command_name": "listCollections" + } + }, + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "insert": "default", + "documents": [ + { + "_id": 1, + "encryptedIndexed": { + "$$type": "binData" + } + } + ], + "ordered": true, + "encryptionInformation": { + "type": 1, + "schema": { + "default.default": { + "escCollection": "enxcol_.default.esc", + "eccCollection": "enxcol_.default.ecc", + "ecocCollection": "enxcol_.default.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedIndexed", + "bsonType": "string", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + }, + { + "keyId": { + "$binary": { + "base64": "q83vqxI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedUnindexed", + "bsonType": "string" + } + ] + } + } + } + }, + "command_name": "insert" + } + }, + { + "command_started_event": { + "command": { + "delete": "default", + "deletes": [ + { + "q": { + "encryptedIndexed": { + "$eq": { + "$binary": { + "base64": "BbEAAAAFZAAgAAAAAPtVteJQAlgb2YMa/+7YWH00sbQPyt7L6Rb8OwBdMmL2BXMAIAAAAAAd44hgVKnEnTFlwNVC14oyc9OZOTspeymusqkRQj57nAVjACAAAAAA19X9v9NlWidu/wR5/C/7WUV54DfL5CkNmT5WYrhxdDcFZQAgAAAAAOuac/eRLYakKX6B0vZ1r3QodOQFfjqJD+xlGiPu4/PsEmNtAAAAAAAAAAAAAA==", + "subType": "06" + } + } + } + }, + "limit": 1 + } + ], + "encryptionInformation": { + "type": 1, + "schema": { + "default.default": { + "escCollection": "enxcol_.default.esc", + "eccCollection": "enxcol_.default.ecc", + "ecocCollection": "enxcol_.default.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedIndexed", + "bsonType": "string", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + }, + { + "keyId": { + "$binary": { + "base64": "q83vqxI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedUnindexed", + "bsonType": "string" + } + ] + } + }, + "deleteTokens": { + "default.default": { + "encryptedIndexed": { + "e": { + "$binary": { + "base64": "65pz95EthqQpfoHS9nWvdCh05AV+OokP7GUaI+7j8+w=", + "subType": "00" + } + }, + "o": { + "$binary": { + "base64": "noN+05JsuO1oDg59yypIGj45i+eFH6HOTXOPpeZ//Mk=", + "subType": "00" + } + } + } + } + } + } + }, + "command_name": "delete" + } + } + ], + "outcome": { + "collection": { + "data": [] + } + } + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/fle2-Delete.yml b/src/test/spec/json/client-side-encryption/legacy/fle2-Delete.yml new file mode 100644 index 000000000..7dfe11768 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/fle2-Delete.yml @@ -0,0 +1,107 @@ +runOn: + - minServerVersion: "6.0.0" + # FLE 2 Encrypted collections are not supported on standalone. + topology: [ "replicaset", "sharded", "load-balanced" ] +database_name: &database_name "default" +collection_name: &collection_name "default" +data: [] +encrypted_fields: &encrypted_fields {'escCollection': 'enxcol_.default.esc', 'eccCollection': 'enxcol_.default.ecc', 'ecocCollection': 'enxcol_.default.ecoc', 'fields': [{'keyId': {'$binary': {'base64': 'EjRWeBI0mHYSNBI0VniQEg==', 'subType': '04'}}, 'path': 'encryptedIndexed', 'bsonType': 'string', 'queries': {'queryType': 'equality', 'contention': {'$numberLong': '0'}}}, {'keyId': {'$binary': {'base64': 'q83vqxI0mHYSNBI0VniQEg==', 'subType': '04'}}, 'path': 'encryptedUnindexed', 'bsonType': 'string'}]} +key_vault_data: [ {'_id': {'$binary': {'base64': 'EjRWeBI0mHYSNBI0VniQEg==', 'subType': '04'}}, 'keyMaterial': {'$binary': {'base64': 'sHe0kz57YW7v8g9VP9sf/+K1ex4JqKc5rf/URX3n3p8XdZ6+15uXPaSayC6adWbNxkFskuMCOifDoTT+rkqMtFkDclOy884RuGGtUysq3X7zkAWYTKi8QAfKkajvVbZl2y23UqgVasdQu3OVBQCrH/xY00nNAs/52e958nVjBuzQkSb1T8pKJAyjZsHJ60+FtnfafDZSTAIBJYn7UWBCwQ==', 'subType': '00'}}, 'creationDate': {'$date': {'$numberLong': '1648914851981'}}, 'updateDate': {'$date': {'$numberLong': '1648914851981'}}, 'status': {'$numberInt': '0'}, 'masterKey': {'provider': 'local'}} ] +tests: + - description: "Delete can query an FLE2 indexed field" + clientOptions: + autoEncryptOpts: + kmsProviders: + local: {'key': {'$binary': {'base64': 'Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk', 'subType': '00'}}} + operations: + - name: insertOne + arguments: + document: &doc0 {"_id": 1, "encryptedIndexed": "value123" } + - name: deleteOne + arguments: + filter: { "encryptedIndexed": "value123" } + result: + deletedCount: 1 + expectations: + - command_started_event: + command: + listCollections: 1 + filter: + name: *collection_name + command_name: listCollections + - command_started_event: + command: + find: datakeys + filter: { + "$or": [ + { + "_id": { + "$in": [ + {'$binary': {'base64': 'EjRWeBI0mHYSNBI0VniQEg==', 'subType': '04'}} + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + } + $db: keyvault + readConcern: { level: "majority" } + command_name: find + - command_started_event: + command: + insert: *collection_name + documents: + - { "_id": 1, "encryptedIndexed": { $$type: "binData" } } + ordered: true + encryptionInformation: + type: 1 + schema: + "default.default": *encrypted_fields + command_name: insert + - command_started_event: + command: + delete: *collection_name + deletes: + - { + "q": { + "encryptedIndexed": { + "$eq": { + "$binary": { + "base64": "BbEAAAAFZAAgAAAAAPtVteJQAlgb2YMa/+7YWH00sbQPyt7L6Rb8OwBdMmL2BXMAIAAAAAAd44hgVKnEnTFlwNVC14oyc9OZOTspeymusqkRQj57nAVjACAAAAAA19X9v9NlWidu/wR5/C/7WUV54DfL5CkNmT5WYrhxdDcFZQAgAAAAAOuac/eRLYakKX6B0vZ1r3QodOQFfjqJD+xlGiPu4/PsEmNtAAAAAAAAAAAAAA==", + "subType": "06" + } + } + } + }, + "limit": 1 + } + encryptionInformation: + type: 1 + schema: + "default.default": *encrypted_fields + deleteTokens: { + "default.default": { + "encryptedIndexed": { + "e": { + "$binary": { + "base64": "65pz95EthqQpfoHS9nWvdCh05AV+OokP7GUaI+7j8+w=", + "subType": "00" + } + }, + "o": { + "$binary": { + "base64": "noN+05JsuO1oDg59yypIGj45i+eFH6HOTXOPpeZ//Mk=", + "subType": "00" + } + } + } + } + } + command_name: delete + outcome: + collection: + data: [] \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/fle2-EncryptedFields-vs-EncryptedFieldsMap.json b/src/test/spec/json/client-side-encryption/legacy/fle2-EncryptedFields-vs-EncryptedFieldsMap.json new file mode 100644 index 000000000..911b42863 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/fle2-EncryptedFields-vs-EncryptedFieldsMap.json @@ -0,0 +1,218 @@ +{ + "runOn": [ + { + "minServerVersion": "6.0.0", + "topology": [ + "replicaset", + "sharded", + "load-balanced" + ] + } + ], + "database_name": "default", + "collection_name": "default", + "data": [], + "encrypted_fields": { + "escCollection": "enxcol_.default.esc", + "eccCollection": "enxcol_.default.ecc", + "ecocCollection": "enxcol_.default.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedIndexed", + "bsonType": "string", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + }, + { + "keyId": { + "$binary": { + "base64": "q83vqxI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedUnindexed", + "bsonType": "string" + } + ] + }, + "key_vault_data": [ + { + "_id": { + "$binary": { + "base64": "q83vqxI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "keyMaterial": { + "$binary": { + "base64": "HBk9BWihXExNDvTp1lUxOuxuZK2Pe2ZdVdlsxPEBkiO1bS4mG5NNDsQ7zVxJAH8BtdOYp72Ku4Y3nwc0BUpIKsvAKX4eYXtlhv5zUQxWdeNFhg9qK7qb8nqhnnLeT0f25jFSqzWJoT379hfwDeu0bebJHr35QrJ8myZdPMTEDYF08QYQ48ShRBli0S+QzBHHAQiM2iJNr4svg2WR8JSeWQ==", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1648914851981" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1648914851981" + } + }, + "status": { + "$numberInt": "0" + }, + "masterKey": { + "provider": "local" + } + } + ], + "tests": [ + { + "description": "encryptedFieldsMap is preferred over remote encryptedFields", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "local": { + "key": { + "$binary": { + "base64": "Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk", + "subType": "00" + } + } + } + }, + "encryptedFieldsMap": { + "default.default": { + "escCollection": "esc", + "eccCollection": "ecc", + "ecocCollection": "ecoc", + "fields": [] + } + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encryptedUnindexed": { + "$binary": { + "base64": "BqvN76sSNJh2EjQSNFZ4kBICTQaVZPWgXp41I7mPV1rLFTtw1tXzjcdSEyxpKKqujlko5TeizkB9hHQ009dVY1+fgIiDcefh+eQrm3CkhQ==", + "subType": "06" + } + } + } + } + }, + { + "name": "find", + "arguments": { + "filter": { + "_id": 1 + } + }, + "result": [ + { + "_id": 1, + "encryptedUnindexed": "value123" + } + ] + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "insert": "default", + "documents": [ + { + "_id": 1, + "encryptedUnindexed": { + "$binary": { + "base64": "BqvN76sSNJh2EjQSNFZ4kBICTQaVZPWgXp41I7mPV1rLFTtw1tXzjcdSEyxpKKqujlko5TeizkB9hHQ009dVY1+fgIiDcefh+eQrm3CkhQ==", + "subType": "06" + } + } + } + ], + "ordered": true + }, + "command_name": "insert" + } + }, + { + "command_started_event": { + "command": { + "find": "default", + "filter": { + "_id": 1 + } + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "q83vqxI0mHYSNBI0VniQEg==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "encryptedUnindexed": { + "$binary": { + "base64": "BqvN76sSNJh2EjQSNFZ4kBICTQaVZPWgXp41I7mPV1rLFTtw1tXzjcdSEyxpKKqujlko5TeizkB9hHQ009dVY1+fgIiDcefh+eQrm3CkhQ==", + "subType": "06" + } + } + } + ] + } + } + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/fle2-EncryptedFields-vs-EncryptedFieldsMap.yml b/src/test/spec/json/client-side-encryption/legacy/fle2-EncryptedFields-vs-EncryptedFieldsMap.yml new file mode 100644 index 000000000..ba4e7a736 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/fle2-EncryptedFields-vs-EncryptedFieldsMap.yml @@ -0,0 +1,80 @@ +runOn: + - minServerVersion: "6.0.0" + # FLE 2 Encrypted collections are not supported on standalone. + topology: [ "replicaset", "sharded", "load-balanced" ] +database_name: &database_name "default" +collection_name: &collection_name "default" +data: [] +encrypted_fields: {'escCollection': 'enxcol_.default.esc', 'eccCollection': 'enxcol_.default.ecc', 'ecocCollection': 'enxcol_.default.ecoc', 'fields': [{'keyId': {'$binary': {'base64': 'EjRWeBI0mHYSNBI0VniQEg==', 'subType': '04'}}, 'path': 'encryptedIndexed', 'bsonType': 'string', 'queries': {'queryType': 'equality', 'contention': {'$numberLong': '0'}}}, {'keyId': {'$binary': {'base64': 'q83vqxI0mHYSNBI0VniQEg==', 'subType': '04'}}, 'path': 'encryptedUnindexed', 'bsonType': 'string'}]} +key_vault_data: [ {'_id': {'$binary': {'base64': 'q83vqxI0mHYSNBI0VniQEg==', 'subType': '04'}}, 'keyMaterial': {'$binary': {'base64': 'HBk9BWihXExNDvTp1lUxOuxuZK2Pe2ZdVdlsxPEBkiO1bS4mG5NNDsQ7zVxJAH8BtdOYp72Ku4Y3nwc0BUpIKsvAKX4eYXtlhv5zUQxWdeNFhg9qK7qb8nqhnnLeT0f25jFSqzWJoT379hfwDeu0bebJHr35QrJ8myZdPMTEDYF08QYQ48ShRBli0S+QzBHHAQiM2iJNr4svg2WR8JSeWQ==', 'subType': '00'}}, 'creationDate': {'$date': {'$numberLong': '1648914851981'}}, 'updateDate': {'$date': {'$numberLong': '1648914851981'}}, 'status': {'$numberInt': '0'}, 'masterKey': {'provider': 'local'}}] +tests: + - description: "encryptedFieldsMap is preferred over remote encryptedFields" + clientOptions: + autoEncryptOpts: + kmsProviders: + local: {'key': {'$binary': {'base64': 'Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk', 'subType': '00'}}} + encryptedFieldsMap: { + "default.default": { + "escCollection": "esc", + "eccCollection": "ecc", + "ecocCollection": "ecoc", + "fields": [] + } + } + operations: + # EncryptedFieldsMap overrides remote encryptedFields. + # Automatic encryption does not occur on encryptedUnindexed. The value is validated on the server. + - name: insertOne + arguments: + document: &doc0 { + _id: 1, + encryptedUnindexed: { + "$binary": { + "base64": "BqvN76sSNJh2EjQSNFZ4kBICTQaVZPWgXp41I7mPV1rLFTtw1tXzjcdSEyxpKKqujlko5TeizkB9hHQ009dVY1+fgIiDcefh+eQrm3CkhQ==", + "subType": "06" + } + } + } + - name: find + arguments: + filter: { "_id": 1 } + result: [{"_id": 1, "encryptedUnindexed": "value123" }] + expectations: + - command_started_event: + command: + insert: *collection_name + documents: + - *doc0 + ordered: true + command_name: insert + - command_started_event: + command: + find: *collection_name + filter: { "_id": 1} + command_name: find + - command_started_event: + command: + find: datakeys + filter: { + "$or": [ + { + "_id": { + "$in": [ + {'$binary': {'base64': 'q83vqxI0mHYSNBI0VniQEg==', 'subType': '04'}} + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + } + $db: keyvault + readConcern: { level: "majority" } + command_name: find + outcome: + collection: + data: + - *doc0 \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/fle2-EncryptedFields-vs-jsonSchema.json b/src/test/spec/json/client-side-encryption/legacy/fle2-EncryptedFields-vs-jsonSchema.json new file mode 100644 index 000000000..f4386483d --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/fle2-EncryptedFields-vs-jsonSchema.json @@ -0,0 +1,305 @@ +{ + "runOn": [ + { + "minServerVersion": "6.0.0", + "topology": [ + "replicaset", + "sharded", + "load-balanced" + ] + } + ], + "database_name": "default", + "collection_name": "default", + "data": [], + "json_schema": { + "properties": {}, + "bsonType": "object" + }, + "encrypted_fields": { + "escCollection": "enxcol_.default.esc", + "eccCollection": "enxcol_.default.ecc", + "ecocCollection": "enxcol_.default.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedIndexed", + "bsonType": "string", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + }, + { + "keyId": { + "$binary": { + "base64": "q83vqxI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedUnindexed", + "bsonType": "string" + } + ] + }, + "key_vault_data": [ + { + "_id": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "keyMaterial": { + "$binary": { + "base64": "sHe0kz57YW7v8g9VP9sf/+K1ex4JqKc5rf/URX3n3p8XdZ6+15uXPaSayC6adWbNxkFskuMCOifDoTT+rkqMtFkDclOy884RuGGtUysq3X7zkAWYTKi8QAfKkajvVbZl2y23UqgVasdQu3OVBQCrH/xY00nNAs/52e958nVjBuzQkSb1T8pKJAyjZsHJ60+FtnfafDZSTAIBJYn7UWBCwQ==", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1648914851981" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1648914851981" + } + }, + "status": { + "$numberInt": "0" + }, + "masterKey": { + "provider": "local" + } + } + ], + "tests": [ + { + "description": "encryptedFields is preferred over jsonSchema", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "local": { + "key": { + "$binary": { + "base64": "Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk", + "subType": "00" + } + } + } + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encryptedIndexed": "123" + } + } + }, + { + "name": "find", + "arguments": { + "filter": { + "encryptedIndexed": "123" + } + }, + "result": [ + { + "_id": 1, + "encryptedIndexed": "123" + } + ] + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "default" + } + }, + "command_name": "listCollections" + } + }, + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "insert": "default", + "documents": [ + { + "_id": 1, + "encryptedIndexed": { + "$$type": "binData" + } + } + ], + "ordered": true, + "encryptionInformation": { + "type": 1, + "schema": { + "default.default": { + "escCollection": "enxcol_.default.esc", + "eccCollection": "enxcol_.default.ecc", + "ecocCollection": "enxcol_.default.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedIndexed", + "bsonType": "string", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + }, + { + "keyId": { + "$binary": { + "base64": "q83vqxI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedUnindexed", + "bsonType": "string" + } + ] + } + } + } + }, + "command_name": "insert" + } + }, + { + "command_started_event": { + "command": { + "find": "default", + "filter": { + "encryptedIndexed": { + "$eq": { + "$binary": { + "base64": "BbEAAAAFZAAgAAAAAPGmZcUzdE/FPILvRSyAScGvZparGI2y9rJ/vSBxgCujBXMAIAAAAACi1RjmndKqgnXy7xb22RzUbnZl1sOZRXPOC0KcJkAxmQVjACAAAAAAWuidNu47c9A4Clic3DvFhn1AQJVC+FJtoE5bGZuz6PsFZQAgAAAAAOuac/eRLYakKX6B0vZ1r3QodOQFfjqJD+xlGiPu4/PsEmNtAAAAAAAAAAAAAA==", + "subType": "06" + } + } + } + }, + "encryptionInformation": { + "type": 1, + "schema": { + "default.default": { + "escCollection": "enxcol_.default.esc", + "eccCollection": "enxcol_.default.ecc", + "ecocCollection": "enxcol_.default.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedIndexed", + "bsonType": "string", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + }, + { + "keyId": { + "$binary": { + "base64": "q83vqxI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedUnindexed", + "bsonType": "string" + } + ] + } + } + } + }, + "command_name": "find" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "encryptedIndexed": { + "$$type": "binData" + }, + "__safeContent__": [ + { + "$binary": { + "base64": "31eCYlbQoVboc5zwC8IoyJVSkag9PxREka8dkmbXJeY=", + "subType": "00" + } + } + ] + } + ] + } + } + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/fle2-EncryptedFields-vs-jsonSchema.yml b/src/test/spec/json/client-side-encryption/legacy/fle2-EncryptedFields-vs-jsonSchema.yml new file mode 100644 index 000000000..2ff2e4da1 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/fle2-EncryptedFields-vs-jsonSchema.yml @@ -0,0 +1,90 @@ +runOn: + - minServerVersion: "6.0.0" + # FLE 2 Encrypted collections are not supported on standalone. + topology: [ "replicaset", "sharded", "load-balanced" ] +database_name: &database_name "default" +collection_name: &collection_name "default" +data: [] +json_schema: { + "properties": {}, + "bsonType": "object" +} +encrypted_fields: &encrypted_fields {'escCollection': 'enxcol_.default.esc', 'eccCollection': 'enxcol_.default.ecc', 'ecocCollection': 'enxcol_.default.ecoc', 'fields': [{'keyId': {'$binary': {'base64': 'EjRWeBI0mHYSNBI0VniQEg==', 'subType': '04'}}, 'path': 'encryptedIndexed', 'bsonType': 'string', 'queries': {'queryType': 'equality', 'contention': {'$numberLong': '0'}}}, {'keyId': {'$binary': {'base64': 'q83vqxI0mHYSNBI0VniQEg==', 'subType': '04'}}, 'path': 'encryptedUnindexed', 'bsonType': 'string'}]} +key_vault_data: [ {'_id': {'$binary': {'base64': 'EjRWeBI0mHYSNBI0VniQEg==', 'subType': '04'}}, 'keyMaterial': {'$binary': {'base64': 'sHe0kz57YW7v8g9VP9sf/+K1ex4JqKc5rf/URX3n3p8XdZ6+15uXPaSayC6adWbNxkFskuMCOifDoTT+rkqMtFkDclOy884RuGGtUysq3X7zkAWYTKi8QAfKkajvVbZl2y23UqgVasdQu3OVBQCrH/xY00nNAs/52e958nVjBuzQkSb1T8pKJAyjZsHJ60+FtnfafDZSTAIBJYn7UWBCwQ==', 'subType': '00'}}, 'creationDate': {'$date': {'$numberLong': '1648914851981'}}, 'updateDate': {'$date': {'$numberLong': '1648914851981'}}, 'status': {'$numberInt': '0'}, 'masterKey': {'provider': 'local'}} ] +tests: + - description: "encryptedFields is preferred over jsonSchema" + clientOptions: + autoEncryptOpts: + kmsProviders: + local: {'key': {'$binary': {'base64': 'Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk', 'subType': '00'}}} + operations: + - name: insertOne + arguments: + document: &doc0 { _id: 1, encryptedIndexed: "123" } + - name: find + arguments: + filter: { encryptedIndexed: "123" } + result: [*doc0] + expectations: + - command_started_event: + command: + listCollections: 1 + filter: + name: *collection_name + command_name: listCollections + - command_started_event: + command: + find: datakeys + filter: { + "$or": [ + { + "_id": { + "$in": [ + {'$binary': {'base64': 'EjRWeBI0mHYSNBI0VniQEg==', 'subType': '04'}} + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + } + $db: keyvault + readConcern: { level: "majority" } + command_name: find + - command_started_event: + command: + insert: *collection_name + documents: + - &doc0_encrypted { "_id": 1, "encryptedIndexed": { $$type: "binData" } } + ordered: true + encryptionInformation: + type: 1 + schema: + "default.default": *encrypted_fields + command_name: insert + - command_started_event: + command: + find: *collection_name + filter: { + "encryptedIndexed": { + "$eq": { + "$binary": { + "base64": "BbEAAAAFZAAgAAAAAPGmZcUzdE/FPILvRSyAScGvZparGI2y9rJ/vSBxgCujBXMAIAAAAACi1RjmndKqgnXy7xb22RzUbnZl1sOZRXPOC0KcJkAxmQVjACAAAAAAWuidNu47c9A4Clic3DvFhn1AQJVC+FJtoE5bGZuz6PsFZQAgAAAAAOuac/eRLYakKX6B0vZ1r3QodOQFfjqJD+xlGiPu4/PsEmNtAAAAAAAAAAAAAA==", + "subType": "06" + } + } + } + } + encryptionInformation: + type: 1 + schema: + "default.default": *encrypted_fields + command_name: find + outcome: + collection: + # Outcome is checked using a separate MongoClient without auto encryption. + data: + - { "_id": 1, "encryptedIndexed": { $$type: "binData" }, "__safeContent__": [{ "$binary" : { "base64" : "31eCYlbQoVboc5zwC8IoyJVSkag9PxREka8dkmbXJeY=", "subType" : "00" } }] } \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/fle2-EncryptedFieldsMap-defaults.json b/src/test/spec/json/client-side-encryption/legacy/fle2-EncryptedFieldsMap-defaults.json new file mode 100644 index 000000000..60820aae9 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/fle2-EncryptedFieldsMap-defaults.json @@ -0,0 +1,106 @@ +{ + "runOn": [ + { + "minServerVersion": "6.0.0", + "topology": [ + "replicaset", + "sharded", + "load-balanced" + ] + } + ], + "database_name": "default", + "collection_name": "default", + "data": [], + "key_vault_data": [], + "tests": [ + { + "description": "default state collections are applied to encryptionInformation", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "local": { + "key": { + "$binary": { + "base64": "Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk", + "subType": "00" + } + } + } + }, + "encryptedFieldsMap": { + "default.default": { + "fields": [] + } + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "foo": { + "$binary": { + "base64": "BYkAAAAFZAAgAAAAAE8KGPgq7h3n9nH5lfHcia8wtOTLwGkZNLBesb6PULqbBXMAIAAAAACq0558QyD3c3jkR5k0Zc9UpQK8ByhXhtn2d1xVQnuJ3AVjACAAAAAA1003zUWGwD4zVZ0KeihnZOthS3V6CEHUfnJZcIYHefISY20AAAAAAAAAAAAA", + "subType": "06" + } + } + } + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "insert": "default", + "documents": [ + { + "_id": 1, + "foo": { + "$binary": { + "base64": "BYkAAAAFZAAgAAAAAE8KGPgq7h3n9nH5lfHcia8wtOTLwGkZNLBesb6PULqbBXMAIAAAAACq0558QyD3c3jkR5k0Zc9UpQK8ByhXhtn2d1xVQnuJ3AVjACAAAAAA1003zUWGwD4zVZ0KeihnZOthS3V6CEHUfnJZcIYHefISY20AAAAAAAAAAAAA", + "subType": "06" + } + } + } + ], + "encryptionInformation": { + "type": { + "$numberInt": "1" + }, + "schema": { + "default.default": { + "fields": [], + "escCollection": "enxcol_.default.esc", + "eccCollection": "enxcol_.default.ecc", + "ecocCollection": "enxcol_.default.ecoc" + } + } + }, + "ordered": true + }, + "command_name": "insert" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "foo": { + "$binary": { + "base64": "BYkAAAAFZAAgAAAAAE8KGPgq7h3n9nH5lfHcia8wtOTLwGkZNLBesb6PULqbBXMAIAAAAACq0558QyD3c3jkR5k0Zc9UpQK8ByhXhtn2d1xVQnuJ3AVjACAAAAAA1003zUWGwD4zVZ0KeihnZOthS3V6CEHUfnJZcIYHefISY20AAAAAAAAAAAAA", + "subType": "06" + } + } + } + ] + } + } + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/fle2-EncryptedFieldsMap-defaults.yml b/src/test/spec/json/client-side-encryption/legacy/fle2-EncryptedFieldsMap-defaults.yml new file mode 100644 index 000000000..0ee418db0 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/fle2-EncryptedFieldsMap-defaults.yml @@ -0,0 +1,57 @@ +runOn: + - minServerVersion: "6.0.0" + # FLE 2 Encrypted collections are not supported on standalone. + topology: [ "replicaset", "sharded", "load-balanced" ] +database_name: &database_name "default" +collection_name: &collection_name "default" +data: [] +key_vault_data: [] +tests: + - description: "default state collections are applied to encryptionInformation" + clientOptions: + autoEncryptOpts: + kmsProviders: + local: {'key': {'$binary': {'base64': 'Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk', 'subType': '00'}}} + encryptedFieldsMap: &efm { + "default.default": { + "fields": [] + } + } + operations: + - name: insertOne + arguments: + document: &doc0 { + _id: 1, + # Include a FLE2FindEncryptedPayload for 'encryptionInformation' to be appended. + foo: { + "$binary": { + "base64": "BYkAAAAFZAAgAAAAAE8KGPgq7h3n9nH5lfHcia8wtOTLwGkZNLBesb6PULqbBXMAIAAAAACq0558QyD3c3jkR5k0Zc9UpQK8ByhXhtn2d1xVQnuJ3AVjACAAAAAA1003zUWGwD4zVZ0KeihnZOthS3V6CEHUfnJZcIYHefISY20AAAAAAAAAAAAA", + "subType": "06" + } + } + } + expectations: + - command_started_event: + command: + insert: *collection_name + documents: + - *doc0 + encryptionInformation: { + "type": { + "$numberInt": "1" + }, + "schema": { + "default.default": { + "fields": [], + "escCollection": "enxcol_.default.esc", + "eccCollection": "enxcol_.default.ecc", + "ecocCollection": "enxcol_.default.ecoc" + } + } + } + ordered: true + command_name: insert + outcome: + collection: + data: + - *doc0 \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/fle2-FindOneAndUpdate.json b/src/test/spec/json/client-side-encryption/legacy/fle2-FindOneAndUpdate.json new file mode 100644 index 000000000..de1b5c5aa --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/fle2-FindOneAndUpdate.json @@ -0,0 +1,603 @@ +{ + "runOn": [ + { + "minServerVersion": "6.0.0", + "topology": [ + "replicaset", + "sharded", + "load-balanced" + ] + } + ], + "database_name": "default", + "collection_name": "default", + "data": [], + "encrypted_fields": { + "escCollection": "enxcol_.default.esc", + "eccCollection": "enxcol_.default.ecc", + "ecocCollection": "enxcol_.default.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedIndexed", + "bsonType": "string", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + }, + { + "keyId": { + "$binary": { + "base64": "q83vqxI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedUnindexed", + "bsonType": "string" + } + ] + }, + "key_vault_data": [ + { + "_id": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "keyMaterial": { + "$binary": { + "base64": "sHe0kz57YW7v8g9VP9sf/+K1ex4JqKc5rf/URX3n3p8XdZ6+15uXPaSayC6adWbNxkFskuMCOifDoTT+rkqMtFkDclOy884RuGGtUysq3X7zkAWYTKi8QAfKkajvVbZl2y23UqgVasdQu3OVBQCrH/xY00nNAs/52e958nVjBuzQkSb1T8pKJAyjZsHJ60+FtnfafDZSTAIBJYn7UWBCwQ==", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1648914851981" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1648914851981" + } + }, + "status": { + "$numberInt": "0" + }, + "masterKey": { + "provider": "local" + } + } + ], + "tests": [ + { + "description": "findOneAndUpdate can query an FLE2 indexed field", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "local": { + "key": { + "$binary": { + "base64": "Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk", + "subType": "00" + } + } + } + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encryptedIndexed": "value123" + } + } + }, + { + "name": "findOneAndUpdate", + "arguments": { + "filter": { + "encryptedIndexed": "value123" + }, + "update": { + "$set": { + "foo": "bar" + } + }, + "returnDocument": "Before" + }, + "result": { + "_id": 1, + "encryptedIndexed": "value123" + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "default" + } + }, + "command_name": "listCollections" + } + }, + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "insert": "default", + "documents": [ + { + "_id": 1, + "encryptedIndexed": { + "$$type": "binData" + } + } + ], + "ordered": true, + "encryptionInformation": { + "type": 1, + "schema": { + "default.default": { + "escCollection": "enxcol_.default.esc", + "eccCollection": "enxcol_.default.ecc", + "ecocCollection": "enxcol_.default.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedIndexed", + "bsonType": "string", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + }, + { + "keyId": { + "$binary": { + "base64": "q83vqxI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedUnindexed", + "bsonType": "string" + } + ] + } + } + } + }, + "command_name": "insert" + } + }, + { + "command_started_event": { + "command": { + "findAndModify": "default", + "query": { + "encryptedIndexed": { + "$eq": { + "$binary": { + "base64": "BbEAAAAFZAAgAAAAAPtVteJQAlgb2YMa/+7YWH00sbQPyt7L6Rb8OwBdMmL2BXMAIAAAAAAd44hgVKnEnTFlwNVC14oyc9OZOTspeymusqkRQj57nAVjACAAAAAA19X9v9NlWidu/wR5/C/7WUV54DfL5CkNmT5WYrhxdDcFZQAgAAAAAOuac/eRLYakKX6B0vZ1r3QodOQFfjqJD+xlGiPu4/PsEmNtAAAAAAAAAAAAAA==", + "subType": "06" + } + } + } + }, + "update": { + "$set": { + "foo": "bar" + } + }, + "encryptionInformation": { + "type": 1, + "schema": { + "default.default": { + "escCollection": "enxcol_.default.esc", + "eccCollection": "enxcol_.default.ecc", + "ecocCollection": "enxcol_.default.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedIndexed", + "bsonType": "string", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + }, + { + "keyId": { + "$binary": { + "base64": "q83vqxI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedUnindexed", + "bsonType": "string" + } + ] + } + }, + "deleteTokens": { + "default.default": { + "encryptedIndexed": { + "e": { + "$binary": { + "base64": "65pz95EthqQpfoHS9nWvdCh05AV+OokP7GUaI+7j8+w=", + "subType": "00" + } + }, + "o": { + "$binary": { + "base64": "noN+05JsuO1oDg59yypIGj45i+eFH6HOTXOPpeZ//Mk=", + "subType": "00" + } + } + } + } + } + } + }, + "command_name": "findAndModify" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "encryptedIndexed": { + "$$type": "binData" + }, + "foo": "bar", + "__safeContent__": [ + { + "$binary": { + "base64": "ThpoKfQ8AkOzkFfNC1+9PF0pY2nIzfXvRdxQgjkNbBw=", + "subType": "00" + } + } + ] + } + ] + } + } + }, + { + "description": "findOneAndUpdate can modify an FLE2 indexed field", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "local": { + "key": { + "$binary": { + "base64": "Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk", + "subType": "00" + } + } + } + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encryptedIndexed": "value123" + } + } + }, + { + "name": "findOneAndUpdate", + "arguments": { + "filter": { + "encryptedIndexed": "value123" + }, + "update": { + "$set": { + "encryptedIndexed": "value456" + } + }, + "returnDocument": "Before" + }, + "result": { + "_id": 1, + "encryptedIndexed": "value123" + } + }, + { + "name": "find", + "arguments": { + "filter": { + "_id": 1 + } + }, + "result": [ + { + "encryptedIndexed": "value456" + } + ] + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "default" + } + }, + "command_name": "listCollections" + } + }, + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "insert": "default", + "documents": [ + { + "_id": 1, + "encryptedIndexed": { + "$$type": "binData" + } + } + ], + "ordered": true, + "encryptionInformation": { + "type": 1, + "schema": { + "default.default": { + "escCollection": "enxcol_.default.esc", + "eccCollection": "enxcol_.default.ecc", + "ecocCollection": "enxcol_.default.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedIndexed", + "bsonType": "string", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + }, + { + "keyId": { + "$binary": { + "base64": "q83vqxI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedUnindexed", + "bsonType": "string" + } + ] + } + } + } + }, + "command_name": "insert" + } + }, + { + "command_started_event": { + "command": { + "findAndModify": "default", + "query": { + "encryptedIndexed": { + "$eq": { + "$binary": { + "base64": "BbEAAAAFZAAgAAAAAPtVteJQAlgb2YMa/+7YWH00sbQPyt7L6Rb8OwBdMmL2BXMAIAAAAAAd44hgVKnEnTFlwNVC14oyc9OZOTspeymusqkRQj57nAVjACAAAAAA19X9v9NlWidu/wR5/C/7WUV54DfL5CkNmT5WYrhxdDcFZQAgAAAAAOuac/eRLYakKX6B0vZ1r3QodOQFfjqJD+xlGiPu4/PsEmNtAAAAAAAAAAAAAA==", + "subType": "06" + } + } + } + }, + "update": { + "$set": { + "encryptedIndexed": { + "$$type": "binData" + } + } + }, + "encryptionInformation": { + "type": 1, + "schema": { + "default.default": { + "escCollection": "enxcol_.default.esc", + "eccCollection": "enxcol_.default.ecc", + "ecocCollection": "enxcol_.default.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedIndexed", + "bsonType": "string", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + }, + { + "keyId": { + "$binary": { + "base64": "q83vqxI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedUnindexed", + "bsonType": "string" + } + ] + } + }, + "deleteTokens": { + "default.default": { + "encryptedIndexed": { + "e": { + "$binary": { + "base64": "65pz95EthqQpfoHS9nWvdCh05AV+OokP7GUaI+7j8+w=", + "subType": "00" + } + }, + "o": { + "$binary": { + "base64": "noN+05JsuO1oDg59yypIGj45i+eFH6HOTXOPpeZ//Mk=", + "subType": "00" + } + } + } + } + } + } + }, + "command_name": "findAndModify" + } + }, + { + "command_started_event": { + "command": { + "find": "default", + "filter": { + "_id": { + "$eq": 1 + } + } + }, + "command_name": "find" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "encryptedIndexed": { + "$$type": "binData" + }, + "__safeContent__": [ + { + "$binary": { + "base64": "rhe7/w8Ob8Unl44rGr/moScx6m5VODQnscDhF4Nkn6g=", + "subType": "00" + } + } + ] + } + ] + } + } + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/fle2-FindOneAndUpdate.yml b/src/test/spec/json/client-side-encryption/legacy/fle2-FindOneAndUpdate.yml new file mode 100644 index 000000000..a5596c2c2 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/fle2-FindOneAndUpdate.yml @@ -0,0 +1,213 @@ +runOn: + - minServerVersion: "6.0.0" + # FLE 2 Encrypted collections are not supported on standalone. + topology: [ "replicaset", "sharded", "load-balanced" ] +database_name: &database_name "default" +collection_name: &collection_name "default" +data: [] +encrypted_fields: &encrypted_fields {'escCollection': 'enxcol_.default.esc', 'eccCollection': 'enxcol_.default.ecc', 'ecocCollection': 'enxcol_.default.ecoc', 'fields': [{'keyId': {'$binary': {'base64': 'EjRWeBI0mHYSNBI0VniQEg==', 'subType': '04'}}, 'path': 'encryptedIndexed', 'bsonType': 'string', 'queries': {'queryType': 'equality', 'contention': {'$numberLong': '0'}}}, {'keyId': {'$binary': {'base64': 'q83vqxI0mHYSNBI0VniQEg==', 'subType': '04'}}, 'path': 'encryptedUnindexed', 'bsonType': 'string'}]} +key_vault_data: [ {'_id': {'$binary': {'base64': 'EjRWeBI0mHYSNBI0VniQEg==', 'subType': '04'}}, 'keyMaterial': {'$binary': {'base64': 'sHe0kz57YW7v8g9VP9sf/+K1ex4JqKc5rf/URX3n3p8XdZ6+15uXPaSayC6adWbNxkFskuMCOifDoTT+rkqMtFkDclOy884RuGGtUysq3X7zkAWYTKi8QAfKkajvVbZl2y23UqgVasdQu3OVBQCrH/xY00nNAs/52e958nVjBuzQkSb1T8pKJAyjZsHJ60+FtnfafDZSTAIBJYn7UWBCwQ==', 'subType': '00'}}, 'creationDate': {'$date': {'$numberLong': '1648914851981'}}, 'updateDate': {'$date': {'$numberLong': '1648914851981'}}, 'status': {'$numberInt': '0'}, 'masterKey': {'provider': 'local'}} ] +tests: + - description: "findOneAndUpdate can query an FLE2 indexed field" + clientOptions: + autoEncryptOpts: + kmsProviders: + local: {'key': {'$binary': {'base64': 'Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk', 'subType': '00'}}} + operations: + - name: insertOne + arguments: + document: {"_id": 1, "encryptedIndexed": "value123" } + - name: findOneAndUpdate + arguments: + filter: { "encryptedIndexed": "value123" } + update: { "$set": { "foo": "bar"}} + returnDocument: Before + result: { "_id": 1, "encryptedIndexed": "value123" } + expectations: + - command_started_event: + command: + listCollections: 1 + filter: + name: *collection_name + command_name: listCollections + - command_started_event: + command: + find: datakeys + filter: { + "$or": [ + { + "_id": { + "$in": [ + {'$binary': {'base64': 'EjRWeBI0mHYSNBI0VniQEg==', 'subType': '04'}} + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + } + $db: keyvault + readConcern: { level: "majority" } + command_name: find + - command_started_event: + command: + insert: *collection_name + documents: + - { "_id": 1, "encryptedIndexed": { $$type: "binData" } } + ordered: true + encryptionInformation: + type: 1 + schema: + "default.default": *encrypted_fields + command_name: insert + - command_started_event: + command: + findAndModify: *collection_name + query: { + "encryptedIndexed": { + "$eq": { + "$binary": { + "base64": "BbEAAAAFZAAgAAAAAPtVteJQAlgb2YMa/+7YWH00sbQPyt7L6Rb8OwBdMmL2BXMAIAAAAAAd44hgVKnEnTFlwNVC14oyc9OZOTspeymusqkRQj57nAVjACAAAAAA19X9v9NlWidu/wR5/C/7WUV54DfL5CkNmT5WYrhxdDcFZQAgAAAAAOuac/eRLYakKX6B0vZ1r3QodOQFfjqJD+xlGiPu4/PsEmNtAAAAAAAAAAAAAA==", + "subType": "06" + } + } + } + } + update: { "$set": { "foo": "bar"} } + encryptionInformation: + type: 1 + schema: + "default.default": *encrypted_fields + deleteTokens: + "default.default": { + "encryptedIndexed": { + "e": { + "$binary": { + "base64": "65pz95EthqQpfoHS9nWvdCh05AV+OokP7GUaI+7j8+w=", + "subType": "00" + } + }, + "o": { + "$binary": { + "base64": "noN+05JsuO1oDg59yypIGj45i+eFH6HOTXOPpeZ//Mk=", + "subType": "00" + } + } + } + } + command_name: findAndModify + outcome: + collection: + data: + - { "_id": 1, "encryptedIndexed": { "$$type": "binData" }, "foo": "bar", "__safeContent__": [{ "$binary" : { "base64" : "ThpoKfQ8AkOzkFfNC1+9PF0pY2nIzfXvRdxQgjkNbBw=", "subType" : "00" } }] } + + - description: "findOneAndUpdate can modify an FLE2 indexed field" + clientOptions: + autoEncryptOpts: + kmsProviders: + local: {'key': {'$binary': {'base64': 'Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk', 'subType': '00'}}} + operations: + - name: insertOne + arguments: + document: {"_id": 1, "encryptedIndexed": "value123" } + - name: findOneAndUpdate + arguments: + filter: { "encryptedIndexed": "value123" } + update: { "$set": { "encryptedIndexed": "value456"}} + returnDocument: Before + result: { "_id": 1, "encryptedIndexed": "value123" } + - name: find + arguments: + filter: { "_id": 1} + result: + [ "encryptedIndexed": "value456" ] + expectations: + - command_started_event: + command: + listCollections: 1 + filter: + name: *collection_name + command_name: listCollections + - command_started_event: + command: + find: datakeys + filter: { + "$or": [ + { + "_id": { + "$in": [ + {'$binary': {'base64': 'EjRWeBI0mHYSNBI0VniQEg==', 'subType': '04'}} + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + } + $db: keyvault + readConcern: { level: "majority" } + command_name: find + - command_started_event: + command: + insert: *collection_name + documents: + - { "_id": 1, "encryptedIndexed": { $$type: "binData" } } + ordered: true + encryptionInformation: + type: 1 + schema: + "default.default": *encrypted_fields + command_name: insert + + - command_started_event: + command: + findAndModify: *collection_name + query: { + "encryptedIndexed": { + "$eq": { + "$binary": { + "base64": "BbEAAAAFZAAgAAAAAPtVteJQAlgb2YMa/+7YWH00sbQPyt7L6Rb8OwBdMmL2BXMAIAAAAAAd44hgVKnEnTFlwNVC14oyc9OZOTspeymusqkRQj57nAVjACAAAAAA19X9v9NlWidu/wR5/C/7WUV54DfL5CkNmT5WYrhxdDcFZQAgAAAAAOuac/eRLYakKX6B0vZ1r3QodOQFfjqJD+xlGiPu4/PsEmNtAAAAAAAAAAAAAA==", + "subType": "06" + } + } + } + } + update: { "$set": { "encryptedIndexed": { "$$type": "binData" }} } + encryptionInformation: + type: 1 + schema: + "default.default": *encrypted_fields + deleteTokens: { + "default.default": { + "encryptedIndexed": { + "e": { + "$binary": { + "base64": "65pz95EthqQpfoHS9nWvdCh05AV+OokP7GUaI+7j8+w=", + "subType": "00" + } + }, + "o": { + "$binary": { + "base64": "noN+05JsuO1oDg59yypIGj45i+eFH6HOTXOPpeZ//Mk=", + "subType": "00" + } + } + } + } + } + command_name: findAndModify + - command_started_event: + command: + find: *collection_name + filter: { "_id": { "$eq": 1 }} + command_name: find + outcome: + collection: + data: + - { "_id": 1, "encryptedIndexed": { "$$type": "binData" }, "__safeContent__": [{ "$binary" : { "base64" : "rhe7/w8Ob8Unl44rGr/moScx6m5VODQnscDhF4Nkn6g=", "subType" : "00" } }] } \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/fle2-InsertFind-Indexed.json b/src/test/spec/json/client-side-encryption/legacy/fle2-InsertFind-Indexed.json new file mode 100644 index 000000000..84b69d7de --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/fle2-InsertFind-Indexed.json @@ -0,0 +1,301 @@ +{ + "runOn": [ + { + "minServerVersion": "6.0.0", + "topology": [ + "replicaset", + "sharded", + "load-balanced" + ] + } + ], + "database_name": "default", + "collection_name": "default", + "data": [], + "encrypted_fields": { + "escCollection": "enxcol_.default.esc", + "eccCollection": "enxcol_.default.ecc", + "ecocCollection": "enxcol_.default.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedIndexed", + "bsonType": "string", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + }, + { + "keyId": { + "$binary": { + "base64": "q83vqxI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedUnindexed", + "bsonType": "string" + } + ] + }, + "key_vault_data": [ + { + "_id": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "keyMaterial": { + "$binary": { + "base64": "sHe0kz57YW7v8g9VP9sf/+K1ex4JqKc5rf/URX3n3p8XdZ6+15uXPaSayC6adWbNxkFskuMCOifDoTT+rkqMtFkDclOy884RuGGtUysq3X7zkAWYTKi8QAfKkajvVbZl2y23UqgVasdQu3OVBQCrH/xY00nNAs/52e958nVjBuzQkSb1T8pKJAyjZsHJ60+FtnfafDZSTAIBJYn7UWBCwQ==", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1648914851981" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1648914851981" + } + }, + "status": { + "$numberInt": "0" + }, + "masterKey": { + "provider": "local" + } + } + ], + "tests": [ + { + "description": "Insert and find FLE2 indexed field", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "local": { + "key": { + "$binary": { + "base64": "Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk", + "subType": "00" + } + } + } + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encryptedIndexed": "123" + } + } + }, + { + "name": "find", + "arguments": { + "filter": { + "encryptedIndexed": "123" + } + }, + "result": [ + { + "_id": 1, + "encryptedIndexed": "123" + } + ] + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "default" + } + }, + "command_name": "listCollections" + } + }, + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "insert": "default", + "documents": [ + { + "_id": 1, + "encryptedIndexed": { + "$$type": "binData" + } + } + ], + "ordered": true, + "encryptionInformation": { + "type": 1, + "schema": { + "default.default": { + "escCollection": "enxcol_.default.esc", + "eccCollection": "enxcol_.default.ecc", + "ecocCollection": "enxcol_.default.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedIndexed", + "bsonType": "string", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + }, + { + "keyId": { + "$binary": { + "base64": "q83vqxI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedUnindexed", + "bsonType": "string" + } + ] + } + } + } + }, + "command_name": "insert" + } + }, + { + "command_started_event": { + "command": { + "find": "default", + "filter": { + "encryptedIndexed": { + "$eq": { + "$binary": { + "base64": "BbEAAAAFZAAgAAAAAPGmZcUzdE/FPILvRSyAScGvZparGI2y9rJ/vSBxgCujBXMAIAAAAACi1RjmndKqgnXy7xb22RzUbnZl1sOZRXPOC0KcJkAxmQVjACAAAAAAWuidNu47c9A4Clic3DvFhn1AQJVC+FJtoE5bGZuz6PsFZQAgAAAAAOuac/eRLYakKX6B0vZ1r3QodOQFfjqJD+xlGiPu4/PsEmNtAAAAAAAAAAAAAA==", + "subType": "06" + } + } + } + }, + "encryptionInformation": { + "type": 1, + "schema": { + "default.default": { + "escCollection": "enxcol_.default.esc", + "eccCollection": "enxcol_.default.ecc", + "ecocCollection": "enxcol_.default.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedIndexed", + "bsonType": "string", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + }, + { + "keyId": { + "$binary": { + "base64": "q83vqxI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedUnindexed", + "bsonType": "string" + } + ] + } + } + } + }, + "command_name": "find" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "encryptedIndexed": { + "$$type": "binData" + }, + "__safeContent__": [ + { + "$binary": { + "base64": "31eCYlbQoVboc5zwC8IoyJVSkag9PxREka8dkmbXJeY=", + "subType": "00" + } + } + ] + } + ] + } + } + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/fle2-InsertFind-Indexed.yml b/src/test/spec/json/client-side-encryption/legacy/fle2-InsertFind-Indexed.yml new file mode 100644 index 000000000..5c5efbcc5 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/fle2-InsertFind-Indexed.yml @@ -0,0 +1,86 @@ +runOn: + - minServerVersion: "6.0.0" + # FLE 2 Encrypted collections are not supported on standalone. + topology: [ "replicaset", "sharded", "load-balanced" ] +database_name: &database_name "default" +collection_name: &collection_name "default" +data: [] +encrypted_fields: &encrypted_fields {'escCollection': 'enxcol_.default.esc', 'eccCollection': 'enxcol_.default.ecc', 'ecocCollection': 'enxcol_.default.ecoc', 'fields': [{'keyId': {'$binary': {'base64': 'EjRWeBI0mHYSNBI0VniQEg==', 'subType': '04'}}, 'path': 'encryptedIndexed', 'bsonType': 'string', 'queries': {'queryType': 'equality', 'contention': {'$numberLong': '0'}}}, {'keyId': {'$binary': {'base64': 'q83vqxI0mHYSNBI0VniQEg==', 'subType': '04'}}, 'path': 'encryptedUnindexed', 'bsonType': 'string'}]} +key_vault_data: [ {'_id': {'$binary': {'base64': 'EjRWeBI0mHYSNBI0VniQEg==', 'subType': '04'}}, 'keyMaterial': {'$binary': {'base64': 'sHe0kz57YW7v8g9VP9sf/+K1ex4JqKc5rf/URX3n3p8XdZ6+15uXPaSayC6adWbNxkFskuMCOifDoTT+rkqMtFkDclOy884RuGGtUysq3X7zkAWYTKi8QAfKkajvVbZl2y23UqgVasdQu3OVBQCrH/xY00nNAs/52e958nVjBuzQkSb1T8pKJAyjZsHJ60+FtnfafDZSTAIBJYn7UWBCwQ==', 'subType': '00'}}, 'creationDate': {'$date': {'$numberLong': '1648914851981'}}, 'updateDate': {'$date': {'$numberLong': '1648914851981'}}, 'status': {'$numberInt': '0'}, 'masterKey': {'provider': 'local'}} ] +tests: + - description: "Insert and find FLE2 indexed field" + clientOptions: + autoEncryptOpts: + kmsProviders: + local: {'key': {'$binary': {'base64': 'Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk', 'subType': '00'}}} + operations: + - name: insertOne + arguments: + document: &doc0 { _id: 1, encryptedIndexed: "123" } + - name: find + arguments: + filter: { encryptedIndexed: "123" } + result: [*doc0] + expectations: + - command_started_event: + command: + listCollections: 1 + filter: + name: *collection_name + command_name: listCollections + - command_started_event: + command: + find: datakeys + filter: { + "$or": [ + { + "_id": { + "$in": [ + {'$binary': {'base64': 'EjRWeBI0mHYSNBI0VniQEg==', 'subType': '04'}} + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + } + $db: keyvault + readConcern: { level: "majority" } + command_name: find + - command_started_event: + command: + insert: *collection_name + documents: + - &doc0_encrypted { "_id": 1, "encryptedIndexed": { $$type: "binData" } } + ordered: true + encryptionInformation: + type: 1 + schema: + default.default: *encrypted_fields + command_name: insert + - command_started_event: + command: + find: *collection_name + filter: { + "encryptedIndexed": { + "$eq": { + "$binary": { + "base64": "BbEAAAAFZAAgAAAAAPGmZcUzdE/FPILvRSyAScGvZparGI2y9rJ/vSBxgCujBXMAIAAAAACi1RjmndKqgnXy7xb22RzUbnZl1sOZRXPOC0KcJkAxmQVjACAAAAAAWuidNu47c9A4Clic3DvFhn1AQJVC+FJtoE5bGZuz6PsFZQAgAAAAAOuac/eRLYakKX6B0vZ1r3QodOQFfjqJD+xlGiPu4/PsEmNtAAAAAAAAAAAAAA==", + "subType": "06" + } + } + } + } + encryptionInformation: + type: 1 + schema: + default.default: *encrypted_fields + command_name: find + outcome: + collection: + # Outcome is checked using a separate MongoClient without auto encryption. + data: + - { "_id": 1, "encryptedIndexed": { $$type: "binData" }, "__safeContent__": [{ "$binary" : { "base64" : "31eCYlbQoVboc5zwC8IoyJVSkag9PxREka8dkmbXJeY=", "subType" : "00" } }] } \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/fle2-InsertFind-Unindexed.json b/src/test/spec/json/client-side-encryption/legacy/fle2-InsertFind-Unindexed.json new file mode 100644 index 000000000..9b3143852 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/fle2-InsertFind-Unindexed.json @@ -0,0 +1,251 @@ +{ + "runOn": [ + { + "minServerVersion": "6.0.0", + "topology": [ + "replicaset", + "sharded", + "load-balanced" + ] + } + ], + "database_name": "default", + "collection_name": "default", + "data": [], + "encrypted_fields": { + "escCollection": "enxcol_.default.esc", + "eccCollection": "enxcol_.default.ecc", + "ecocCollection": "enxcol_.default.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedIndexed", + "bsonType": "string", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + }, + { + "keyId": { + "$binary": { + "base64": "q83vqxI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedUnindexed", + "bsonType": "string" + } + ] + }, + "key_vault_data": [ + { + "_id": { + "$binary": { + "base64": "q83vqxI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "keyMaterial": { + "$binary": { + "base64": "HBk9BWihXExNDvTp1lUxOuxuZK2Pe2ZdVdlsxPEBkiO1bS4mG5NNDsQ7zVxJAH8BtdOYp72Ku4Y3nwc0BUpIKsvAKX4eYXtlhv5zUQxWdeNFhg9qK7qb8nqhnnLeT0f25jFSqzWJoT379hfwDeu0bebJHr35QrJ8myZdPMTEDYF08QYQ48ShRBli0S+QzBHHAQiM2iJNr4svg2WR8JSeWQ==", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1648914851981" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1648914851981" + } + }, + "status": { + "$numberInt": "0" + }, + "masterKey": { + "provider": "local" + } + } + ], + "tests": [ + { + "description": "Insert and find FLE2 unindexed field", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "local": { + "key": { + "$binary": { + "base64": "Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk", + "subType": "00" + } + } + } + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encryptedUnindexed": "value123" + } + } + }, + { + "name": "find", + "arguments": { + "filter": { + "_id": 1 + } + }, + "result": [ + { + "_id": 1, + "encryptedUnindexed": "value123" + } + ] + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "default" + } + }, + "command_name": "listCollections" + } + }, + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "q83vqxI0mHYSNBI0VniQEg==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "insert": "default", + "documents": [ + { + "_id": 1, + "encryptedUnindexed": { + "$$type": "binData" + } + } + ], + "ordered": true + }, + "command_name": "insert" + } + }, + { + "command_started_event": { + "command": { + "find": "default", + "filter": { + "_id": { + "$eq": 1 + } + } + }, + "command_name": "find" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "encryptedUnindexed": { + "$$type": "binData" + } + } + ] + } + } + }, + { + "description": "Query with an unindexed field fails", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "local": { + "key": { + "$binary": { + "base64": "Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk", + "subType": "00" + } + } + } + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encryptedUnindexed": "value123" + } + } + }, + { + "name": "find", + "arguments": { + "filter": { + "encryptedUnindexed": "value123" + } + }, + "result": { + "errorContains": "encrypt" + } + } + ] + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/fle2-InsertFind-Unindexed.yml b/src/test/spec/json/client-side-encryption/legacy/fle2-InsertFind-Unindexed.yml new file mode 100644 index 000000000..71f1993e5 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/fle2-InsertFind-Unindexed.yml @@ -0,0 +1,87 @@ +runOn: + - minServerVersion: "6.0.0" + # FLE 2 Encrypted collections are not supported on standalone. + topology: [ "replicaset", "sharded", "load-balanced" ] +database_name: &database_name "default" +collection_name: &collection_name "default" +data: [] +encrypted_fields: {'escCollection': 'enxcol_.default.esc', 'eccCollection': 'enxcol_.default.ecc', 'ecocCollection': 'enxcol_.default.ecoc', 'fields': [{'keyId': {'$binary': {'base64': 'EjRWeBI0mHYSNBI0VniQEg==', 'subType': '04'}}, 'path': 'encryptedIndexed', 'bsonType': 'string', 'queries': {'queryType': 'equality', 'contention': {'$numberLong': '0'}}}, {'keyId': {'$binary': {'base64': 'q83vqxI0mHYSNBI0VniQEg==', 'subType': '04'}}, 'path': 'encryptedUnindexed', 'bsonType': 'string'}]} +key_vault_data: [ {'_id': {'$binary': {'base64': 'q83vqxI0mHYSNBI0VniQEg==', 'subType': '04'}}, 'keyMaterial': {'$binary': {'base64': 'HBk9BWihXExNDvTp1lUxOuxuZK2Pe2ZdVdlsxPEBkiO1bS4mG5NNDsQ7zVxJAH8BtdOYp72Ku4Y3nwc0BUpIKsvAKX4eYXtlhv5zUQxWdeNFhg9qK7qb8nqhnnLeT0f25jFSqzWJoT379hfwDeu0bebJHr35QrJ8myZdPMTEDYF08QYQ48ShRBli0S+QzBHHAQiM2iJNr4svg2WR8JSeWQ==', 'subType': '00'}}, 'creationDate': {'$date': {'$numberLong': '1648914851981'}}, 'updateDate': {'$date': {'$numberLong': '1648914851981'}}, 'status': {'$numberInt': '0'}, 'masterKey': {'provider': 'local'}} ] +tests: + - description: "Insert and find FLE2 unindexed field" + clientOptions: + autoEncryptOpts: + kmsProviders: + local: {'key': {'$binary': {'base64': 'Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk', 'subType': '00'}}} + operations: + - name: insertOne + arguments: + document: &doc0 { _id: 1, encryptedUnindexed: "value123" } + - name: find + arguments: + filter: { _id: 1 } + result: [*doc0] + expectations: + - command_started_event: + command: + listCollections: 1 + filter: + name: *collection_name + command_name: listCollections + - command_started_event: + command: + find: datakeys + filter: { + "$or": [ + { + "_id": { + "$in": [ + {'$binary': {'base64': 'q83vqxI0mHYSNBI0VniQEg==', 'subType': '04'}} + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + } + $db: keyvault + readConcern: { level: "majority" } + command_name: find + - command_started_event: + command: + insert: *collection_name + documents: + - &doc0_encrypted { "_id": 1, "encryptedUnindexed": { $$type: "binData" } } + ordered: true + command_name: insert + - command_started_event: + command: + find: *collection_name + filter: { "_id": { "$eq": 1 }} + command_name: find + outcome: + collection: + data: + - { "_id": 1, "encryptedUnindexed": { $$type: "binData" } } + + - description: "Query with an unindexed field fails" + clientOptions: + autoEncryptOpts: + kmsProviders: + local: {'key': {'$binary': {'base64': 'Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk', 'subType': '00'}}} + operations: + - name: insertOne + arguments: + document: { _id: 1, encryptedUnindexed: "value123" } + - name: find + arguments: + filter: { encryptedUnindexed: "value123" } + result: + # Expected error message changed in https://github.com/10gen/mongo-enterprise-modules/commit/212b584d4f7a44bed41c826a180a4aff00923d7a#diff-5f12b55e8d5c52c2f62853ec595dc2c1e2e5cb4fdbf7a32739a8e3acb3c6f818 + # Before the message was "cannot query non-indexed fields with the randomized encryption algorithm" + # After: "can only execute encrypted equality queries with an encrypted equality index" + # Use a small common substring. + errorContains: "encrypt" \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/fle2-MissingKey.json b/src/test/spec/json/client-side-encryption/legacy/fle2-MissingKey.json new file mode 100644 index 000000000..4210da09e --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/fle2-MissingKey.json @@ -0,0 +1,119 @@ +{ + "runOn": [ + { + "minServerVersion": "6.0.0", + "topology": [ + "replicaset", + "sharded", + "load-balanced" + ] + } + ], + "database_name": "default", + "collection_name": "default", + "data": [ + { + "encryptedUnindexed": { + "$binary": { + "base64": "BqvN76sSNJh2EjQSNFZ4kBICTQaVZPWgXp41I7mPV1rLFTtw1tXzjcdSEyxpKKqujlko5TeizkB9hHQ009dVY1+fgIiDcefh+eQrm3CkhQ==", + "subType": "06" + } + } + } + ], + "encrypted_fields": { + "escCollection": "enxcol_.default.esc", + "eccCollection": "enxcol_.default.ecc", + "ecocCollection": "enxcol_.default.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedIndexed", + "bsonType": "string", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + }, + { + "keyId": { + "$binary": { + "base64": "q83vqxI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedUnindexed", + "bsonType": "string" + } + ] + }, + "key_vault_data": [], + "tests": [ + { + "description": "FLE2 encrypt fails with mising key", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "local": { + "key": { + "$binary": { + "base64": "Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk", + "subType": "00" + } + } + } + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encryptedIndexed": "123" + } + }, + "result": { + "errorContains": "not all keys requested were satisfied" + } + } + ] + }, + { + "description": "FLE2 decrypt fails with mising key", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "local": { + "key": { + "$binary": { + "base64": "Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk", + "subType": "00" + } + } + } + } + } + }, + "operations": [ + { + "name": "find", + "arguments": { + "filter": {} + }, + "result": { + "errorContains": "not all keys requested were satisfied" + } + } + ] + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/fle2-MissingKey.yml b/src/test/spec/json/client-side-encryption/legacy/fle2-MissingKey.yml new file mode 100644 index 000000000..937c82ee9 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/fle2-MissingKey.yml @@ -0,0 +1,41 @@ +runOn: + - minServerVersion: "6.0.0" + # FLE 2 Encrypted collections are not supported on standalone. + topology: [ "replicaset", "sharded", "load-balanced" ] +database_name: &database_name "default" +collection_name: &collection_name "default" +data: [ + &doc0 { + "encryptedUnindexed": { + "$binary": { + "base64": "BqvN76sSNJh2EjQSNFZ4kBICTQaVZPWgXp41I7mPV1rLFTtw1tXzjcdSEyxpKKqujlko5TeizkB9hHQ009dVY1+fgIiDcefh+eQrm3CkhQ==", + "subType": "06" + } + } + } +] +encrypted_fields: {'escCollection': 'enxcol_.default.esc', 'eccCollection': 'enxcol_.default.ecc', 'ecocCollection': 'enxcol_.default.ecoc', 'fields': [{'keyId': {'$binary': {'base64': 'EjRWeBI0mHYSNBI0VniQEg==', 'subType': '04'}}, 'path': 'encryptedIndexed', 'bsonType': 'string', 'queries': {'queryType': 'equality', 'contention': {'$numberLong': '0'}}}, {'keyId': {'$binary': {'base64': 'q83vqxI0mHYSNBI0VniQEg==', 'subType': '04'}}, 'path': 'encryptedUnindexed', 'bsonType': 'string'}]} +key_vault_data: [] +tests: + - description: "FLE2 encrypt fails with mising key" + clientOptions: + autoEncryptOpts: + kmsProviders: + local: {'key': {'$binary': {'base64': 'Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk', 'subType': '00'}}} + operations: + - name: insertOne + arguments: + document: { _id: 1, encryptedIndexed: "123" } + result: + errorContains: "not all keys requested were satisfied" + - description: "FLE2 decrypt fails with mising key" + clientOptions: + autoEncryptOpts: + kmsProviders: + local: {'key': {'$binary': {'base64': 'Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk', 'subType': '00'}}} + operations: + - name: find + arguments: + filter: { } + result: + errorContains: "not all keys requested were satisfied" \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/fle2-NoEncryption.json b/src/test/spec/json/client-side-encryption/legacy/fle2-NoEncryption.json new file mode 100644 index 000000000..9d255bd49 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/fle2-NoEncryption.json @@ -0,0 +1,87 @@ +{ + "runOn": [ + { + "minServerVersion": "6.0.0", + "topology": [ + "replicaset", + "sharded", + "load-balanced" + ] + } + ], + "database_name": "default", + "collection_name": "default", + "data": [], + "key_vault_data": [], + "encrypted_fields": { + "fields": [] + }, + "tests": [ + { + "description": "insert with no encryption succeeds", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "local": { + "key": { + "$binary": { + "base64": "Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk", + "subType": "00" + } + } + } + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "foo": "bar" + } + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "default" + } + }, + "command_name": "listCollections" + } + }, + { + "command_started_event": { + "command": { + "insert": "default", + "documents": [ + { + "_id": 1, + "foo": "bar" + } + ], + "ordered": true + }, + "command_name": "insert" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "foo": "bar" + } + ] + } + } + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/fle2-NoEncryption.yml b/src/test/spec/json/client-side-encryption/legacy/fle2-NoEncryption.yml new file mode 100644 index 000000000..8725ac1ef --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/fle2-NoEncryption.yml @@ -0,0 +1,42 @@ +runOn: + - minServerVersion: "6.0.0" + # FLE 2 Encrypted collections are not supported on standalone. + topology: [ "replicaset", "sharded", "load-balanced" ] +database_name: &database_name "default" +collection_name: &collection_name "default" +data: [] +key_vault_data: [] +encrypted_fields: { + "fields": [] +} +tests: + - description: "insert with no encryption succeeds" + clientOptions: + autoEncryptOpts: + kmsProviders: + local: {'key': {'$binary': {'base64': 'Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk', 'subType': '00'}}} + operations: + - name: insertOne + arguments: + document: &doc0 { + _id: 1, + foo: "bar" + } + expectations: + - command_started_event: + command: + listCollections: 1 + filter: + name: *collection_name + command_name: listCollections + - command_started_event: + command: + insert: *collection_name + documents: + - *doc0 + ordered: true + command_name: insert + outcome: + collection: + data: + - *doc0 \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/fle2-Update.json b/src/test/spec/json/client-side-encryption/legacy/fle2-Update.json new file mode 100644 index 000000000..090f44f9a --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/fle2-Update.json @@ -0,0 +1,611 @@ +{ + "runOn": [ + { + "minServerVersion": "6.0.0", + "topology": [ + "replicaset", + "sharded", + "load-balanced" + ] + } + ], + "database_name": "default", + "collection_name": "default", + "data": [], + "encrypted_fields": { + "escCollection": "enxcol_.default.esc", + "eccCollection": "enxcol_.default.ecc", + "ecocCollection": "enxcol_.default.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedIndexed", + "bsonType": "string", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + }, + { + "keyId": { + "$binary": { + "base64": "q83vqxI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedUnindexed", + "bsonType": "string" + } + ] + }, + "key_vault_data": [ + { + "_id": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "keyMaterial": { + "$binary": { + "base64": "sHe0kz57YW7v8g9VP9sf/+K1ex4JqKc5rf/URX3n3p8XdZ6+15uXPaSayC6adWbNxkFskuMCOifDoTT+rkqMtFkDclOy884RuGGtUysq3X7zkAWYTKi8QAfKkajvVbZl2y23UqgVasdQu3OVBQCrH/xY00nNAs/52e958nVjBuzQkSb1T8pKJAyjZsHJ60+FtnfafDZSTAIBJYn7UWBCwQ==", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1648914851981" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1648914851981" + } + }, + "status": { + "$numberInt": "0" + }, + "masterKey": { + "provider": "local" + } + } + ], + "tests": [ + { + "description": "Update can query an FLE2 indexed field", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "local": { + "key": { + "$binary": { + "base64": "Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk", + "subType": "00" + } + } + } + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encryptedIndexed": "value123" + } + } + }, + { + "name": "updateOne", + "arguments": { + "filter": { + "encryptedIndexed": "value123" + }, + "update": { + "$set": { + "foo": "bar" + } + } + }, + "result": { + "matchedCount": 1, + "modifiedCount": 1, + "upsertedCount": 0 + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "default" + } + }, + "command_name": "listCollections" + } + }, + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "insert": "default", + "documents": [ + { + "_id": 1, + "encryptedIndexed": { + "$$type": "binData" + } + } + ], + "ordered": true, + "encryptionInformation": { + "type": 1, + "schema": { + "default.default": { + "escCollection": "enxcol_.default.esc", + "eccCollection": "enxcol_.default.ecc", + "ecocCollection": "enxcol_.default.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedIndexed", + "bsonType": "string", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + }, + { + "keyId": { + "$binary": { + "base64": "q83vqxI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedUnindexed", + "bsonType": "string" + } + ] + } + } + } + }, + "command_name": "insert" + } + }, + { + "command_started_event": { + "command": { + "update": "default", + "updates": [ + { + "q": { + "encryptedIndexed": { + "$eq": { + "$binary": { + "base64": "BbEAAAAFZAAgAAAAAPtVteJQAlgb2YMa/+7YWH00sbQPyt7L6Rb8OwBdMmL2BXMAIAAAAAAd44hgVKnEnTFlwNVC14oyc9OZOTspeymusqkRQj57nAVjACAAAAAA19X9v9NlWidu/wR5/C/7WUV54DfL5CkNmT5WYrhxdDcFZQAgAAAAAOuac/eRLYakKX6B0vZ1r3QodOQFfjqJD+xlGiPu4/PsEmNtAAAAAAAAAAAAAA==", + "subType": "06" + } + } + } + }, + "u": { + "$set": { + "foo": "bar" + } + } + } + ], + "encryptionInformation": { + "type": 1, + "schema": { + "default.default": { + "escCollection": "enxcol_.default.esc", + "eccCollection": "enxcol_.default.ecc", + "ecocCollection": "enxcol_.default.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedIndexed", + "bsonType": "string", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + }, + { + "keyId": { + "$binary": { + "base64": "q83vqxI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedUnindexed", + "bsonType": "string" + } + ] + } + }, + "deleteTokens": { + "default.default": { + "encryptedIndexed": { + "e": { + "$binary": { + "base64": "65pz95EthqQpfoHS9nWvdCh05AV+OokP7GUaI+7j8+w=", + "subType": "00" + } + }, + "o": { + "$binary": { + "base64": "noN+05JsuO1oDg59yypIGj45i+eFH6HOTXOPpeZ//Mk=", + "subType": "00" + } + } + } + } + } + } + }, + "command_name": "update" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "encryptedIndexed": { + "$$type": "binData" + }, + "foo": "bar", + "__safeContent__": [ + { + "$binary": { + "base64": "ThpoKfQ8AkOzkFfNC1+9PF0pY2nIzfXvRdxQgjkNbBw=", + "subType": "00" + } + } + ] + } + ] + } + } + }, + { + "description": "Update can modify an FLE2 indexed field", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "local": { + "key": { + "$binary": { + "base64": "Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk", + "subType": "00" + } + } + } + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encryptedIndexed": "value123" + } + } + }, + { + "name": "updateOne", + "arguments": { + "filter": { + "encryptedIndexed": "value123" + }, + "update": { + "$set": { + "encryptedIndexed": "value456" + } + } + }, + "result": { + "matchedCount": 1, + "modifiedCount": 1, + "upsertedCount": 0 + } + }, + { + "name": "find", + "arguments": { + "filter": { + "_id": 1 + } + }, + "result": [ + { + "encryptedIndexed": "value456" + } + ] + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "default" + } + }, + "command_name": "listCollections" + } + }, + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "insert": "default", + "documents": [ + { + "_id": 1, + "encryptedIndexed": { + "$$type": "binData" + } + } + ], + "ordered": true, + "encryptionInformation": { + "type": 1, + "schema": { + "default.default": { + "escCollection": "enxcol_.default.esc", + "eccCollection": "enxcol_.default.ecc", + "ecocCollection": "enxcol_.default.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedIndexed", + "bsonType": "string", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + }, + { + "keyId": { + "$binary": { + "base64": "q83vqxI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedUnindexed", + "bsonType": "string" + } + ] + } + } + } + }, + "command_name": "insert" + } + }, + { + "command_started_event": { + "command": { + "update": "default", + "updates": [ + { + "q": { + "encryptedIndexed": { + "$eq": { + "$binary": { + "base64": "BbEAAAAFZAAgAAAAAPtVteJQAlgb2YMa/+7YWH00sbQPyt7L6Rb8OwBdMmL2BXMAIAAAAAAd44hgVKnEnTFlwNVC14oyc9OZOTspeymusqkRQj57nAVjACAAAAAA19X9v9NlWidu/wR5/C/7WUV54DfL5CkNmT5WYrhxdDcFZQAgAAAAAOuac/eRLYakKX6B0vZ1r3QodOQFfjqJD+xlGiPu4/PsEmNtAAAAAAAAAAAAAA==", + "subType": "06" + } + } + } + }, + "u": { + "$set": { + "encryptedIndexed": { + "$$type": "binData" + } + } + } + } + ], + "encryptionInformation": { + "type": 1, + "schema": { + "default.default": { + "escCollection": "enxcol_.default.esc", + "eccCollection": "enxcol_.default.ecc", + "ecocCollection": "enxcol_.default.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedIndexed", + "bsonType": "string", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + }, + { + "keyId": { + "$binary": { + "base64": "q83vqxI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedUnindexed", + "bsonType": "string" + } + ] + } + }, + "deleteTokens": { + "default.default": { + "encryptedIndexed": { + "e": { + "$binary": { + "base64": "65pz95EthqQpfoHS9nWvdCh05AV+OokP7GUaI+7j8+w=", + "subType": "00" + } + }, + "o": { + "$binary": { + "base64": "noN+05JsuO1oDg59yypIGj45i+eFH6HOTXOPpeZ//Mk=", + "subType": "00" + } + } + } + } + } + } + }, + "command_name": "update" + } + }, + { + "command_started_event": { + "command": { + "find": "default", + "filter": { + "_id": { + "$eq": 1 + } + } + }, + "command_name": "find" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "encryptedIndexed": { + "$$type": "binData" + }, + "__safeContent__": [ + { + "$binary": { + "base64": "rhe7/w8Ob8Unl44rGr/moScx6m5VODQnscDhF4Nkn6g=", + "subType": "00" + } + } + ] + } + ] + } + } + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/fle2-Update.yml b/src/test/spec/json/client-side-encryption/legacy/fle2-Update.yml new file mode 100644 index 000000000..929f4a3a3 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/fle2-Update.yml @@ -0,0 +1,221 @@ +runOn: + - minServerVersion: "6.0.0" + # FLE 2 Encrypted collections are not supported on standalone. + topology: [ "replicaset", "sharded", "load-balanced" ] +database_name: &database_name "default" +collection_name: &collection_name "default" +data: [] +encrypted_fields: &encrypted_fields {'escCollection': 'enxcol_.default.esc', 'eccCollection': 'enxcol_.default.ecc', 'ecocCollection': 'enxcol_.default.ecoc', 'fields': [{'keyId': {'$binary': {'base64': 'EjRWeBI0mHYSNBI0VniQEg==', 'subType': '04'}}, 'path': 'encryptedIndexed', 'bsonType': 'string', 'queries': {'queryType': 'equality', 'contention': {'$numberLong': '0'}}}, {'keyId': {'$binary': {'base64': 'q83vqxI0mHYSNBI0VniQEg==', 'subType': '04'}}, 'path': 'encryptedUnindexed', 'bsonType': 'string'}]} +key_vault_data: [ {'_id': {'$binary': {'base64': 'EjRWeBI0mHYSNBI0VniQEg==', 'subType': '04'}}, 'keyMaterial': {'$binary': {'base64': 'sHe0kz57YW7v8g9VP9sf/+K1ex4JqKc5rf/URX3n3p8XdZ6+15uXPaSayC6adWbNxkFskuMCOifDoTT+rkqMtFkDclOy884RuGGtUysq3X7zkAWYTKi8QAfKkajvVbZl2y23UqgVasdQu3OVBQCrH/xY00nNAs/52e958nVjBuzQkSb1T8pKJAyjZsHJ60+FtnfafDZSTAIBJYn7UWBCwQ==', 'subType': '00'}}, 'creationDate': {'$date': {'$numberLong': '1648914851981'}}, 'updateDate': {'$date': {'$numberLong': '1648914851981'}}, 'status': {'$numberInt': '0'}, 'masterKey': {'provider': 'local'}} ] +tests: + - description: "Update can query an FLE2 indexed field" + clientOptions: + autoEncryptOpts: + kmsProviders: + local: {'key': {'$binary': {'base64': 'Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk', 'subType': '00'}}} + operations: + - name: insertOne + arguments: + document: {"_id": 1, "encryptedIndexed": "value123" } + - name: updateOne + arguments: + filter: { "encryptedIndexed": "value123" } + update: { "$set": { "foo": "bar"}} + result: + matchedCount: 1 + modifiedCount: 1 + upsertedCount: 0 + expectations: + - command_started_event: + command: + listCollections: 1 + filter: + name: *collection_name + command_name: listCollections + - command_started_event: + command: + find: datakeys + filter: { + "$or": [ + { + "_id": { + "$in": [ + {'$binary': {'base64': 'EjRWeBI0mHYSNBI0VniQEg==', 'subType': '04'}} + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + } + $db: keyvault + readConcern: { level: "majority" } + command_name: find + - command_started_event: + command: + insert: *collection_name + documents: + - { "_id": 1, "encryptedIndexed": { $$type: "binData" } } + ordered: true + encryptionInformation: + type: 1 + schema: + "default.default": *encrypted_fields + command_name: insert + - command_started_event: + command: + update: *collection_name + updates: + - { + "q": { + "encryptedIndexed": { + "$eq": { + "$binary": { + "base64": "BbEAAAAFZAAgAAAAAPtVteJQAlgb2YMa/+7YWH00sbQPyt7L6Rb8OwBdMmL2BXMAIAAAAAAd44hgVKnEnTFlwNVC14oyc9OZOTspeymusqkRQj57nAVjACAAAAAA19X9v9NlWidu/wR5/C/7WUV54DfL5CkNmT5WYrhxdDcFZQAgAAAAAOuac/eRLYakKX6B0vZ1r3QodOQFfjqJD+xlGiPu4/PsEmNtAAAAAAAAAAAAAA==", + "subType": "06" + } + } + } + }, + "u": { "$set": { "foo": "bar"} } + } + encryptionInformation: + type: 1 + schema: + "default.default": *encrypted_fields + deleteTokens: + "default.default": { + "encryptedIndexed": { + "e": { + "$binary": { + "base64": "65pz95EthqQpfoHS9nWvdCh05AV+OokP7GUaI+7j8+w=", + "subType": "00" + } + }, + "o": { + "$binary": { + "base64": "noN+05JsuO1oDg59yypIGj45i+eFH6HOTXOPpeZ//Mk=", + "subType": "00" + } + } + } + } + command_name: update + outcome: + collection: + data: + - { "_id": 1, "encryptedIndexed": { "$$type": "binData" }, "foo": "bar", "__safeContent__": [{ "$binary" : { "base64" : "ThpoKfQ8AkOzkFfNC1+9PF0pY2nIzfXvRdxQgjkNbBw=", "subType" : "00" } }] } + - description: "Update can modify an FLE2 indexed field" + clientOptions: + autoEncryptOpts: + kmsProviders: + local: {'key': {'$binary': {'base64': 'Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk', 'subType': '00'}}} + operations: + - name: insertOne + arguments: + document: {"_id": 1, "encryptedIndexed": "value123" } + - name: updateOne + arguments: + filter: { "encryptedIndexed": "value123" } + update: { "$set": { "encryptedIndexed": "value456"}} + result: + matchedCount: 1 + modifiedCount: 1 + upsertedCount: 0 + - name: find + arguments: + filter: { "_id": 1} + result: + [ "encryptedIndexed": "value456" ] + expectations: + - command_started_event: + command: + listCollections: 1 + filter: + name: *collection_name + command_name: listCollections + - command_started_event: + command: + find: datakeys + filter: { + "$or": [ + { + "_id": { + "$in": [ + {'$binary': {'base64': 'EjRWeBI0mHYSNBI0VniQEg==', 'subType': '04'}} + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + } + $db: keyvault + readConcern: { level: "majority" } + command_name: find + - command_started_event: + command: + insert: *collection_name + documents: + - { "_id": 1, "encryptedIndexed": { $$type: "binData" } } + ordered: true + encryptionInformation: + type: 1 + schema: + "default.default": *encrypted_fields + command_name: insert + - command_started_event: + command: + update: *collection_name + updates: + - { + "q": { + "encryptedIndexed": { + "$eq": { + "$binary": { + "base64": "BbEAAAAFZAAgAAAAAPtVteJQAlgb2YMa/+7YWH00sbQPyt7L6Rb8OwBdMmL2BXMAIAAAAAAd44hgVKnEnTFlwNVC14oyc9OZOTspeymusqkRQj57nAVjACAAAAAA19X9v9NlWidu/wR5/C/7WUV54DfL5CkNmT5WYrhxdDcFZQAgAAAAAOuac/eRLYakKX6B0vZ1r3QodOQFfjqJD+xlGiPu4/PsEmNtAAAAAAAAAAAAAA==", + "subType": "06" + } + } + } + }, + "u": { "$set": { "encryptedIndexed": { "$$type": "binData" }} } + } + encryptionInformation: + type: 1 + schema: + "default.default": *encrypted_fields + deleteTokens: { + "default.default": { + "encryptedIndexed": { + "e": { + "$binary": { + "base64": "65pz95EthqQpfoHS9nWvdCh05AV+OokP7GUaI+7j8+w=", + "subType": "00" + } + }, + "o": { + "$binary": { + "base64": "noN+05JsuO1oDg59yypIGj45i+eFH6HOTXOPpeZ//Mk=", + "subType": "00" + } + } + } + } + } + command_name: update + - command_started_event: + command: + find: *collection_name + filter: { "_id": { "$eq": 1 }} + command_name: find + outcome: + collection: + data: + - { "_id": 1, "encryptedIndexed": { "$$type": "binData" }, "__safeContent__": [{ "$binary" : { "base64" : "rhe7/w8Ob8Unl44rGr/moScx6m5VODQnscDhF4Nkn6g=", "subType" : "00" } }] } \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/fle2-validatorAndPartialFieldExpression.json b/src/test/spec/json/client-side-encryption/legacy/fle2-validatorAndPartialFieldExpression.json new file mode 100644 index 000000000..e70ca7c72 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/fle2-validatorAndPartialFieldExpression.json @@ -0,0 +1,521 @@ +{ + "runOn": [ + { + "minServerVersion": "6.0.0", + "topology": [ + "replicaset", + "sharded", + "load-balanced" + ] + } + ], + "database_name": "default", + "collection_name": "default", + "data": [], + "tests": [ + { + "description": "create with a validator on an unencrypted field is OK", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "local": { + "key": { + "$binary": { + "base64": "Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk", + "subType": "00" + } + } + } + }, + "encryptedFieldsMap": { + "default.encryptedCollection": { + "escCollection": "enxcol_.default.esc", + "eccCollection": "enxcol_.default.ecc", + "ecocCollection": "enxcol_.default.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedIndexed", + "bsonType": "string", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + }, + { + "keyId": { + "$binary": { + "base64": "q83vqxI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedUnindexed", + "bsonType": "string" + } + ] + } + } + } + }, + "operations": [ + { + "name": "dropCollection", + "object": "database", + "arguments": { + "collection": "encryptedCollection" + } + }, + { + "name": "createCollection", + "object": "database", + "arguments": { + "collection": "encryptedCollection", + "validator": { + "unencrypted_string": "foo" + } + } + }, + { + "name": "assertCollectionExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection" + } + } + ] + }, + { + "description": "create with a validator on an encrypted field is an error", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "local": { + "key": { + "$binary": { + "base64": "Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk", + "subType": "00" + } + } + } + }, + "encryptedFieldsMap": { + "default.encryptedCollection": { + "escCollection": "enxcol_.default.esc", + "eccCollection": "enxcol_.default.ecc", + "ecocCollection": "enxcol_.default.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedIndexed", + "bsonType": "string", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + }, + { + "keyId": { + "$binary": { + "base64": "q83vqxI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedUnindexed", + "bsonType": "string" + } + ] + } + } + } + }, + "operations": [ + { + "name": "dropCollection", + "object": "database", + "arguments": { + "collection": "encryptedCollection" + } + }, + { + "name": "createCollection", + "object": "database", + "arguments": { + "collection": "encryptedCollection", + "validator": { + "encryptedIndexed": "foo" + } + }, + "result": { + "errorContains": "Comparison to encrypted fields not supported" + } + } + ] + }, + { + "description": "collMod with a validator on an unencrypted field is OK", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "local": { + "key": { + "$binary": { + "base64": "Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk", + "subType": "00" + } + } + } + }, + "encryptedFieldsMap": { + "default.encryptedCollection": { + "escCollection": "enxcol_.default.esc", + "eccCollection": "enxcol_.default.ecc", + "ecocCollection": "enxcol_.default.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedIndexed", + "bsonType": "string", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + }, + { + "keyId": { + "$binary": { + "base64": "q83vqxI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedUnindexed", + "bsonType": "string" + } + ] + } + } + } + }, + "operations": [ + { + "name": "dropCollection", + "object": "database", + "arguments": { + "collection": "encryptedCollection" + } + }, + { + "name": "createCollection", + "object": "database", + "arguments": { + "collection": "encryptedCollection" + } + }, + { + "name": "runCommand", + "object": "database", + "arguments": { + "command": { + "collMod": "encryptedCollection", + "validator": { + "unencrypted_string": "foo" + } + } + } + } + ] + }, + { + "description": "collMod with a validator on an encrypted field is an error", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "local": { + "key": { + "$binary": { + "base64": "Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk", + "subType": "00" + } + } + } + }, + "encryptedFieldsMap": { + "default.encryptedCollection": { + "escCollection": "enxcol_.default.esc", + "eccCollection": "enxcol_.default.ecc", + "ecocCollection": "enxcol_.default.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedIndexed", + "bsonType": "string", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + }, + { + "keyId": { + "$binary": { + "base64": "q83vqxI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedUnindexed", + "bsonType": "string" + } + ] + } + } + } + }, + "operations": [ + { + "name": "dropCollection", + "object": "database", + "arguments": { + "collection": "encryptedCollection" + } + }, + { + "name": "createCollection", + "object": "database", + "arguments": { + "collection": "encryptedCollection" + } + }, + { + "name": "runCommand", + "object": "database", + "arguments": { + "command": { + "collMod": "encryptedCollection", + "validator": { + "encryptedIndexed": "foo" + } + } + }, + "result": { + "errorContains": "Comparison to encrypted fields not supported" + } + } + ] + }, + { + "description": "createIndexes with a partialFilterExpression on an unencrypted field is OK", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "local": { + "key": { + "$binary": { + "base64": "Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk", + "subType": "00" + } + } + } + }, + "encryptedFieldsMap": { + "default.encryptedCollection": { + "escCollection": "enxcol_.default.esc", + "eccCollection": "enxcol_.default.ecc", + "ecocCollection": "enxcol_.default.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedIndexed", + "bsonType": "string", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + }, + { + "keyId": { + "$binary": { + "base64": "q83vqxI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedUnindexed", + "bsonType": "string" + } + ] + } + } + } + }, + "operations": [ + { + "name": "dropCollection", + "object": "database", + "arguments": { + "collection": "encryptedCollection" + } + }, + { + "name": "createCollection", + "object": "database", + "arguments": { + "collection": "encryptedCollection" + } + }, + { + "name": "runCommand", + "object": "database", + "arguments": { + "command": { + "createIndexes": "encryptedCollection", + "indexes": [ + { + "name": "name", + "key": { + "name": 1 + }, + "partialFilterExpression": { + "unencrypted_string": "foo" + } + } + ] + } + } + }, + { + "name": "assertIndexExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection", + "index": "name" + } + } + ] + }, + { + "description": "createIndexes with a partialFilterExpression on an encrypted field is an error", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "local": { + "key": { + "$binary": { + "base64": "Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk", + "subType": "00" + } + } + } + }, + "encryptedFieldsMap": { + "default.encryptedCollection": { + "escCollection": "enxcol_.default.esc", + "eccCollection": "enxcol_.default.ecc", + "ecocCollection": "enxcol_.default.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedIndexed", + "bsonType": "string", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + }, + { + "keyId": { + "$binary": { + "base64": "q83vqxI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encryptedUnindexed", + "bsonType": "string" + } + ] + } + } + } + }, + "operations": [ + { + "name": "dropCollection", + "object": "database", + "arguments": { + "collection": "encryptedCollection" + } + }, + { + "name": "createCollection", + "object": "database", + "arguments": { + "collection": "encryptedCollection" + } + }, + { + "name": "runCommand", + "object": "database", + "arguments": { + "command": { + "createIndexes": "encryptedCollection", + "indexes": [ + { + "name": "name", + "key": { + "name": 1 + }, + "partialFilterExpression": { + "encryptedIndexed": "foo" + } + } + ] + } + }, + "result": { + "errorContains": "Comparison to encrypted fields not supported" + } + } + ] + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/fle2-validatorAndPartialFieldExpression.yml b/src/test/spec/json/client-side-encryption/legacy/fle2-validatorAndPartialFieldExpression.yml new file mode 100644 index 000000000..9463ddeca --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/fle2-validatorAndPartialFieldExpression.yml @@ -0,0 +1,168 @@ +# This test requires libmongocrypt 1.5.0-alpha2. +runOn: + # Require server version 6.0.0 to get behavior added in SERVER-64911. + - minServerVersion: "6.0.0" + # FLE 2 Encrypted collections are not supported on standalone. + topology: [ "replicaset", "sharded", "load-balanced" ] + +database_name: &database_name "default" +collection_name: &collection_name "default" +data: [] +tests: + - description: "create with a validator on an unencrypted field is OK" + clientOptions: + autoEncryptOpts: + kmsProviders: + local: {'key': {'$binary': {'base64': 'Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk', 'subType': '00'}}} + encryptedFieldsMap: + "default.encryptedCollection": {'escCollection': 'enxcol_.default.esc', 'eccCollection': 'enxcol_.default.ecc', 'ecocCollection': 'enxcol_.default.ecoc', 'fields': [{'keyId': {'$binary': {'base64': 'EjRWeBI0mHYSNBI0VniQEg==', 'subType': '04'}}, 'path': 'encryptedIndexed', 'bsonType': 'string', 'queries': {'queryType': 'equality', 'contention': {'$numberLong': '0'}}}, {'keyId': {'$binary': {'base64': 'q83vqxI0mHYSNBI0VniQEg==', 'subType': '04'}}, 'path': 'encryptedUnindexed', 'bsonType': 'string'}]} + operations: + # Drop to remove a collection that may exist from previous test runs. + - name: dropCollection + object: database + arguments: + collection: "encryptedCollection" + - name: createCollection + object: database + arguments: + collection: "encryptedCollection" + validator: + unencrypted_string: "foo" + - name: assertCollectionExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection" + - description: "create with a validator on an encrypted field is an error" + clientOptions: + autoEncryptOpts: + kmsProviders: + local: {'key': {'$binary': {'base64': 'Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk', 'subType': '00'}}} + encryptedFieldsMap: + "default.encryptedCollection": {'escCollection': 'enxcol_.default.esc', 'eccCollection': 'enxcol_.default.ecc', 'ecocCollection': 'enxcol_.default.ecoc', 'fields': [{'keyId': {'$binary': {'base64': 'EjRWeBI0mHYSNBI0VniQEg==', 'subType': '04'}}, 'path': 'encryptedIndexed', 'bsonType': 'string', 'queries': {'queryType': 'equality', 'contention': {'$numberLong': '0'}}}, {'keyId': {'$binary': {'base64': 'q83vqxI0mHYSNBI0VniQEg==', 'subType': '04'}}, 'path': 'encryptedUnindexed', 'bsonType': 'string'}]} + operations: + # Drop to remove a collection that may exist from previous test runs. + - name: dropCollection + object: database + arguments: + collection: "encryptedCollection" + - name: createCollection + object: database + arguments: + collection: "encryptedCollection" + validator: + encryptedIndexed: "foo" + result: + errorContains: "Comparison to encrypted fields not supported" + - description: "collMod with a validator on an unencrypted field is OK" + clientOptions: + autoEncryptOpts: + kmsProviders: + local: {'key': {'$binary': {'base64': 'Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk', 'subType': '00'}}} + encryptedFieldsMap: + "default.encryptedCollection": {'escCollection': 'enxcol_.default.esc', 'eccCollection': 'enxcol_.default.ecc', 'ecocCollection': 'enxcol_.default.ecoc', 'fields': [{'keyId': {'$binary': {'base64': 'EjRWeBI0mHYSNBI0VniQEg==', 'subType': '04'}}, 'path': 'encryptedIndexed', 'bsonType': 'string', 'queries': {'queryType': 'equality', 'contention': {'$numberLong': '0'}}}, {'keyId': {'$binary': {'base64': 'q83vqxI0mHYSNBI0VniQEg==', 'subType': '04'}}, 'path': 'encryptedUnindexed', 'bsonType': 'string'}]} + operations: + # Drop to remove a collection that may exist from previous test runs. + - name: dropCollection + object: database + arguments: + collection: "encryptedCollection" + - name: createCollection + object: database + arguments: + collection: "encryptedCollection" + - name: runCommand + object: database + arguments: + command: + collMod: "encryptedCollection" + validator: + unencrypted_string: "foo" + - description: "collMod with a validator on an encrypted field is an error" + clientOptions: + autoEncryptOpts: + kmsProviders: + local: {'key': {'$binary': {'base64': 'Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk', 'subType': '00'}}} + encryptedFieldsMap: + "default.encryptedCollection": {'escCollection': 'enxcol_.default.esc', 'eccCollection': 'enxcol_.default.ecc', 'ecocCollection': 'enxcol_.default.ecoc', 'fields': [{'keyId': {'$binary': {'base64': 'EjRWeBI0mHYSNBI0VniQEg==', 'subType': '04'}}, 'path': 'encryptedIndexed', 'bsonType': 'string', 'queries': {'queryType': 'equality', 'contention': {'$numberLong': '0'}}}, {'keyId': {'$binary': {'base64': 'q83vqxI0mHYSNBI0VniQEg==', 'subType': '04'}}, 'path': 'encryptedUnindexed', 'bsonType': 'string'}]} + operations: + # Drop to remove a collection that may exist from previous test runs. + - name: dropCollection + object: database + arguments: + collection: "encryptedCollection" + - name: createCollection + object: database + arguments: + collection: "encryptedCollection" + - name: runCommand + object: database + arguments: + command: + collMod: "encryptedCollection" + validator: + encryptedIndexed: "foo" + result: + errorContains: "Comparison to encrypted fields not supported" + - description: "createIndexes with a partialFilterExpression on an unencrypted field is OK" + clientOptions: + autoEncryptOpts: + kmsProviders: + local: {'key': {'$binary': {'base64': 'Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk', 'subType': '00'}}} + encryptedFieldsMap: + "default.encryptedCollection": {'escCollection': 'enxcol_.default.esc', 'eccCollection': 'enxcol_.default.ecc', 'ecocCollection': 'enxcol_.default.ecoc', 'fields': [{'keyId': {'$binary': {'base64': 'EjRWeBI0mHYSNBI0VniQEg==', 'subType': '04'}}, 'path': 'encryptedIndexed', 'bsonType': 'string', 'queries': {'queryType': 'equality', 'contention': {'$numberLong': '0'}}}, {'keyId': {'$binary': {'base64': 'q83vqxI0mHYSNBI0VniQEg==', 'subType': '04'}}, 'path': 'encryptedUnindexed', 'bsonType': 'string'}]} + operations: + # Drop to remove a collection that may exist from previous test runs. + - name: dropCollection + object: database + arguments: + collection: "encryptedCollection" + - name: createCollection + object: database + arguments: + collection: "encryptedCollection" + - name: runCommand + object: database + arguments: + command: + createIndexes: "encryptedCollection" + indexes: + - name: "name" + key: { name: 1 } + partialFilterExpression: + unencrypted_string: "foo" + - name: assertIndexExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection" + index: name + - description: "createIndexes with a partialFilterExpression on an encrypted field is an error" + clientOptions: + autoEncryptOpts: + kmsProviders: + local: {'key': {'$binary': {'base64': 'Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk', 'subType': '00'}}} + encryptedFieldsMap: + "default.encryptedCollection": {'escCollection': 'enxcol_.default.esc', 'eccCollection': 'enxcol_.default.ecc', 'ecocCollection': 'enxcol_.default.ecoc', 'fields': [{'keyId': {'$binary': {'base64': 'EjRWeBI0mHYSNBI0VniQEg==', 'subType': '04'}}, 'path': 'encryptedIndexed', 'bsonType': 'string', 'queries': {'queryType': 'equality', 'contention': {'$numberLong': '0'}}}, {'keyId': {'$binary': {'base64': 'q83vqxI0mHYSNBI0VniQEg==', 'subType': '04'}}, 'path': 'encryptedUnindexed', 'bsonType': 'string'}]} + operations: + # Drop to remove a collection that may exist from previous test runs. + - name: dropCollection + object: database + arguments: + collection: "encryptedCollection" + - name: createCollection + object: database + arguments: + collection: "encryptedCollection" + - name: runCommand + object: database + arguments: + command: + createIndexes: "encryptedCollection" + indexes: + - name: "name" + key: { name: 1 } + partialFilterExpression: + encryptedIndexed: "foo" + result: + errorContains: "Comparison to encrypted fields not supported" \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/gcpKMS.json b/src/test/spec/json/client-side-encryption/legacy/gcpKMS.json new file mode 100644 index 000000000..c2c08b8a2 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/gcpKMS.json @@ -0,0 +1,226 @@ +{ + "runOn": [ + { + "minServerVersion": "4.1.10" + } + ], + "database_name": "default", + "collection_name": "default", + "data": [], + "json_schema": { + "properties": { + "encrypted_string_aws": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "encrypted_string_azure": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AZURE+AAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "encrypted_string_gcp": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "GCP+AAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "encrypted_string_local": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "encrypted_string_kmip": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "dBHpr8aITfeBQ15grpbLpQ==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + }, + "key_vault_data": [ + { + "_id": { + "$binary": { + "base64": "GCP+AAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + }, + "keyMaterial": { + "$binary": { + "base64": "CiQAIgLj0WyktnB4dfYHo5SLZ41K4ASQrjJUaSzl5vvVH0G12G0SiQEAjlV8XPlbnHDEDFbdTO4QIe8ER2/172U1ouLazG0ysDtFFIlSvWX5ZnZUrRMmp/R2aJkzLXEt/zf8Mn4Lfm+itnjgo5R9K4pmPNvvPKNZX5C16lrPT+aA+rd+zXFSmlMg3i5jnxvTdLHhg3G7Q/Uv1ZIJskKt95bzLoe0tUVzRWMYXLIEcohnQg==", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1601574333107" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1601574333107" + } + }, + "status": { + "$numberInt": "0" + }, + "masterKey": { + "provider": "gcp", + "projectId": "devprod-drivers", + "location": "global", + "keyRing": "key-ring-csfle", + "keyName": "key-name-csfle" + }, + "keyAltNames": [ + "altname", + "gcp_altname" + ] + } + ], + "tests": [ + { + "description": "Insert a document with auto encryption using GCP KMS provider", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "gcp": {} + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encrypted_string_gcp": "string0" + } + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "default" + } + }, + "command_name": "listCollections" + } + }, + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "GCP+AAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault" + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "insert": "default", + "documents": [ + { + "_id": 1, + "encrypted_string_gcp": { + "$binary": { + "base64": "ARgj/gAAAAAAAAAAAAAAAAACwFd+Y5Ojw45GUXNvbcIpN9YkRdoHDHkR4kssdn0tIMKlDQOLFkWFY9X07IRlXsxPD8DcTiKnl6XINK28vhcGlg==", + "subType": "06" + } + } + } + ], + "ordered": true + }, + "command_name": "insert" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "encrypted_string_gcp": { + "$binary": { + "base64": "ARgj/gAAAAAAAAAAAAAAAAACwFd+Y5Ojw45GUXNvbcIpN9YkRdoHDHkR4kssdn0tIMKlDQOLFkWFY9X07IRlXsxPD8DcTiKnl6XINK28vhcGlg==", + "subType": "06" + } + } + } + ] + } + } + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/gcpKMS.yml b/src/test/spec/json/client-side-encryption/legacy/gcpKMS.yml new file mode 100644 index 000000000..50b6a40be --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/gcpKMS.yml @@ -0,0 +1,46 @@ +runOn: + - minServerVersion: "4.1.10" +database_name: &database_name "default" +collection_name: &collection_name "default" + +data: [] +json_schema: {'properties': {'encrypted_string_aws': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'encrypted_string_azure': {'encrypt': {'keyId': [{'$binary': {'base64': 'AZURE+AAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'encrypted_string_gcp': {'encrypt': {'keyId': [{'$binary': {'base64': 'GCP+AAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'encrypted_string_local': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'encrypted_string_kmip': {'encrypt': {'keyId': [{'$binary': {'base64': 'dBHpr8aITfeBQ15grpbLpQ==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} +key_vault_data: [{'_id': {'$binary': {'base64': 'GCP+AAAAAAAAAAAAAAAAAA==', 'subType': '04'}}, 'keyMaterial': {'$binary': {'base64': 'CiQAIgLj0WyktnB4dfYHo5SLZ41K4ASQrjJUaSzl5vvVH0G12G0SiQEAjlV8XPlbnHDEDFbdTO4QIe8ER2/172U1ouLazG0ysDtFFIlSvWX5ZnZUrRMmp/R2aJkzLXEt/zf8Mn4Lfm+itnjgo5R9K4pmPNvvPKNZX5C16lrPT+aA+rd+zXFSmlMg3i5jnxvTdLHhg3G7Q/Uv1ZIJskKt95bzLoe0tUVzRWMYXLIEcohnQg==', 'subType': '00'}}, 'creationDate': {'$date': {'$numberLong': '1601574333107'}}, 'updateDate': {'$date': {'$numberLong': '1601574333107'}}, 'status': {'$numberInt': '0'}, 'masterKey': {'provider': 'gcp', 'projectId': 'devprod-drivers', 'location': 'global', 'keyRing': 'key-ring-csfle', 'keyName': 'key-name-csfle'}, 'keyAltNames': ['altname', 'gcp_altname']}] + +tests: + - description: "Insert a document with auto encryption using GCP KMS provider" + clientOptions: + autoEncryptOpts: + kmsProviders: + gcp: {} + operations: + - name: insertOne + arguments: + document: &doc0 { _id: 1, encrypted_string_gcp: "string0" } + expectations: + # Auto encryption will request the collection info. + - command_started_event: + command: + listCollections: 1 + filter: + name: *collection_name + command_name: listCollections + # Then key is fetched from the key vault. + - command_started_event: + command: + find: datakeys + filter: { $or: [ { _id: { $in: [ {'$binary': {'base64': 'GCP+AAAAAAAAAAAAAAAAAA==', 'subType': '04'}} ] } }, { keyAltNames: { $in: [] } } ] } + $db: keyvault + command_name: find + - command_started_event: + command: + insert: *collection_name + documents: + - &doc0_encrypted { _id: 1, encrypted_string_gcp: {'$binary': {'base64': 'ARgj/gAAAAAAAAAAAAAAAAACwFd+Y5Ojw45GUXNvbcIpN9YkRdoHDHkR4kssdn0tIMKlDQOLFkWFY9X07IRlXsxPD8DcTiKnl6XINK28vhcGlg==', 'subType': '06'}} } + ordered: true + command_name: insert + outcome: + collection: + # Outcome is checked using a separate MongoClient without auto encryption. + data: + - *doc0_encrypted \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/getMore.json b/src/test/spec/json/client-side-encryption/legacy/getMore.json new file mode 100644 index 000000000..ee99bf753 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/getMore.json @@ -0,0 +1,263 @@ +{ + "runOn": [ + { + "minServerVersion": "4.1.10" + } + ], + "database_name": "default", + "collection_name": "default", + "data": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + }, + { + "_id": 2, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", + "subType": "06" + } + } + }, + { + "_id": 3, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACQ76HWOut3DZtQuV90hp1aaCpZn95vZIaWmn+wrBehcEtcFwyJlBdlyzDzZTWPZCPgiFq72Wvh6Y7VbpU9NAp3A==", + "subType": "06" + } + } + } + ], + "json_schema": { + "properties": { + "encrypted_w_altname": { + "encrypt": { + "keyId": "/altname", + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "random": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string_equivalent": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + }, + "key_vault_data": [ + { + "status": 1, + "_id": { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + }, + "masterKey": { + "provider": "aws", + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "region": "us-east-1" + }, + "updateDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyMaterial": { + "$binary": { + "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyAltNames": [ + "altname", + "another_altname" + ] + } + ], + "tests": [ + { + "description": "getMore with encryption", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "find", + "arguments": { + "batchSize": 2, + "filter": {} + }, + "result": [ + { + "_id": 1, + "encrypted_string": "string0" + }, + { + "_id": 2, + "encrypted_string": "string1" + }, + { + "_id": 3, + "encrypted_string": "string2" + } + ] + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "default" + } + }, + "command_name": "listCollections" + } + }, + { + "command_started_event": { + "command": { + "find": "default", + "batchSize": 2 + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "getMore": { + "$$type": "long" + }, + "collection": "default", + "batchSize": 2 + }, + "command_name": "getMore" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + }, + { + "_id": 2, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", + "subType": "06" + } + } + }, + { + "_id": 3, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACQ76HWOut3DZtQuV90hp1aaCpZn95vZIaWmn+wrBehcEtcFwyJlBdlyzDzZTWPZCPgiFq72Wvh6Y7VbpU9NAp3A==", + "subType": "06" + } + } + } + ] + } + } + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/getMore.yml b/src/test/spec/json/client-side-encryption/legacy/getMore.yml new file mode 100644 index 000000000..4359ee891 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/getMore.yml @@ -0,0 +1,61 @@ +runOn: + - minServerVersion: "4.1.10" +database_name: &database_name "default" +collection_name: &collection_name "default" + +data: + - &doc0_encrypted { _id: 1, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==', 'subType': '06'}} } + - &doc1_encrypted { _id: 2, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==', 'subType': '06'}} } + - &doc2_encrypted { _id: 3, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACQ76HWOut3DZtQuV90hp1aaCpZn95vZIaWmn+wrBehcEtcFwyJlBdlyzDzZTWPZCPgiFq72Wvh6Y7VbpU9NAp3A==', 'subType': '06'}} } +json_schema: {'properties': {'encrypted_w_altname': {'encrypt': {'keyId': '/altname', 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'random': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string_equivalent': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} +key_vault_data: [{'status': 1, '_id': {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}, 'masterKey': {'provider': 'aws', 'key': 'arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0', 'region': 'us-east-1'}, 'updateDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyMaterial': {'$binary': {'base64': 'AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO', 'subType': '00'}}, 'creationDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyAltNames': ['altname', 'another_altname']}] + +tests: + - description: "getMore with encryption" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: find + arguments: + batchSize: 2 + filter: {} + result: + - { _id: 1, encrypted_string: "string0" } + - { _id: 2, encrypted_string: "string1" } + - { _id: 3, encrypted_string: "string2" } + expectations: + # Auto encryption will request the collection info. + - command_started_event: + command: + listCollections: 1 + filter: + name: *collection_name + command_name: listCollections + - command_started_event: + command: + find: *collection_name + batchSize: 2 + command_name: find + # Then key is fetched from the key vault. + - command_started_event: + command: + find: datakeys + filter: {"$or": [{"_id": {"$in": [ {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}} ] }}, {"keyAltNames": {"$in": []}}]} + $db: keyvault + readConcern: { level: "majority" } + command_name: find + - command_started_event: + command: + getMore: { $$type: "long" } + collection: *collection_name + batchSize: 2 + command_name: getMore + outcome: + collection: + # Outcome is checked using a separate MongoClient without auto encryption. + data: + - *doc0_encrypted + - *doc1_encrypted + - *doc2_encrypted \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/insert.json b/src/test/spec/json/client-side-encryption/legacy/insert.json new file mode 100644 index 000000000..cf2910fd7 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/insert.json @@ -0,0 +1,344 @@ +{ + "runOn": [ + { + "minServerVersion": "4.1.10" + } + ], + "database_name": "default", + "collection_name": "default", + "data": [], + "json_schema": { + "properties": { + "encrypted_w_altname": { + "encrypt": { + "keyId": "/altname", + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "random": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string_equivalent": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + }, + "key_vault_data": [ + { + "status": 1, + "_id": { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + }, + "masterKey": { + "provider": "aws", + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "region": "us-east-1" + }, + "updateDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyMaterial": { + "$binary": { + "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyAltNames": [ + "altname", + "another_altname" + ] + } + ], + "tests": [ + { + "description": "insertOne with encryption", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encrypted_string": "string0", + "random": "abc" + } + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "default" + } + }, + "command_name": "listCollections" + } + }, + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "insert": "default", + "documents": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + }, + "random": { + "$$type": "binData" + } + } + ], + "ordered": true + }, + "command_name": "insert" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + }, + "random": { + "$$type": "binData" + } + } + ] + } + } + }, + { + "description": "insertMany with encryption", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "insertMany", + "arguments": { + "documents": [ + { + "_id": 1, + "encrypted_string": "string0", + "random": "abc" + }, + { + "_id": 2, + "encrypted_string": "string1" + } + ] + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "default" + } + }, + "command_name": "listCollections" + } + }, + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "insert": "default", + "documents": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + }, + "random": { + "$$type": "binData" + } + }, + { + "_id": 2, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", + "subType": "06" + } + } + } + ], + "ordered": true + }, + "command_name": "insert" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + }, + "random": { + "$$type": "binData" + } + }, + { + "_id": 2, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", + "subType": "06" + } + } + } + ] + } + } + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/insert.yml b/src/test/spec/json/client-side-encryption/legacy/insert.yml new file mode 100644 index 000000000..99521f035 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/insert.yml @@ -0,0 +1,88 @@ +runOn: + - minServerVersion: "4.1.10" +database_name: &database_name "default" +collection_name: &collection_name "default" + +data: [] +json_schema: {'properties': {'encrypted_w_altname': {'encrypt': {'keyId': '/altname', 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'random': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string_equivalent': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} +key_vault_data: [{'status': 1, '_id': {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}, 'masterKey': {'provider': 'aws', 'key': 'arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0', 'region': 'us-east-1'}, 'updateDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyMaterial': {'$binary': {'base64': 'AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO', 'subType': '00'}}, 'creationDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyAltNames': ['altname', 'another_altname']}] + +tests: + - description: "insertOne with encryption" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: insertOne + arguments: + document: &doc0 { _id: 1, encrypted_string: "string0", random: "abc" } + expectations: + # Auto encryption will request the collection info. + - command_started_event: + command: + listCollections: 1 + filter: + name: *collection_name + command_name: listCollections + # Then key is fetched from the key vault. + - command_started_event: + command: + find: datakeys + filter: {"$or": [{"_id": {"$in": [ {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}} ] }}, {"keyAltNames": {"$in": []}}]} + $db: keyvault + readConcern: { level: "majority" } + command_name: find + - command_started_event: + command: + insert: *collection_name + documents: + - &doc0_encrypted { _id: 1, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==', 'subType': '06'}}, random: { $$type: "binData" } } + ordered: true + command_name: insert + outcome: + collection: + # Outcome is checked using a separate MongoClient without auto encryption. + data: + - *doc0_encrypted + - description: "insertMany with encryption" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: insertMany + arguments: + documents: + - *doc0 + - &doc1 { _id: 2, encrypted_string: "string1" } + expectations: + # Auto encryption will request the collection info. + - command_started_event: + command: + listCollections: 1 + filter: + name: *collection_name + command_name: listCollections + # Then key is fetched from the key vault. + - command_started_event: + command: + find: datakeys + filter: {"$or": [{"_id": {"$in": [ {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}} ] }}, {"keyAltNames": {"$in": []}}]} + $db: keyvault + readConcern: { level: "majority" } + command_name: find + - command_started_event: + command: + insert: *collection_name + documents: + - *doc0_encrypted + - &doc1_encrypted { _id: 2, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==', 'subType': '06'}} } + ordered: true + command_name: insert + outcome: + collection: + # Outcome is checked using a separate MongoClient without auto encryption. + data: + - *doc0_encrypted + - *doc1_encrypted \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/keyAltName.json b/src/test/spec/json/client-side-encryption/legacy/keyAltName.json new file mode 100644 index 000000000..7f71b9dbe --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/keyAltName.json @@ -0,0 +1,228 @@ +{ + "runOn": [ + { + "minServerVersion": "4.1.10" + } + ], + "database_name": "default", + "collection_name": "default", + "data": [], + "json_schema": { + "properties": { + "encrypted_w_altname": { + "encrypt": { + "keyId": "/altname", + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "random": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string_equivalent": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + }, + "key_vault_data": [ + { + "status": 1, + "_id": { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + }, + "masterKey": { + "provider": "aws", + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "region": "us-east-1" + }, + "updateDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyMaterial": { + "$binary": { + "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyAltNames": [ + "altname", + "another_altname" + ] + } + ], + "tests": [ + { + "description": "Insert with encryption using key alt name", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encrypted_w_altname": "string0", + "altname": "altname" + } + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "default" + } + }, + "command_name": "listCollections" + } + }, + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [] + } + }, + { + "keyAltNames": { + "$in": [ + "altname" + ] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "insert": "default", + "documents": [ + { + "_id": 1, + "encrypted_w_altname": { + "$$type": "binData" + }, + "altname": "altname" + } + ], + "ordered": true + }, + "command_name": "insert" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "encrypted_w_altname": { + "$$type": "binData" + }, + "altname": "altname" + } + ] + } + } + }, + { + "description": "Replace with key alt name fails", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "updateOne", + "arguments": { + "filter": {}, + "update": { + "$set": { + "encrypted_w_altname": "string0" + } + }, + "upsert": true + }, + "result": { + "errorContains": "A non-static (JSONPointer) keyId is not supported" + } + } + ], + "outcome": { + "collection": { + "data": [] + } + } + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/keyAltName.yml b/src/test/spec/json/client-side-encryption/legacy/keyAltName.yml new file mode 100644 index 000000000..a7660ba38 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/keyAltName.yml @@ -0,0 +1,64 @@ +runOn: + - minServerVersion: "4.1.10" +database_name: &database_name "default" +collection_name: &collection_name "default" + +data: [] +json_schema: {'properties': {'encrypted_w_altname': {'encrypt': {'keyId': '/altname', 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'random': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string_equivalent': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} +key_vault_data: [{'status': 1, '_id': {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}, 'masterKey': {'provider': 'aws', 'key': 'arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0', 'region': 'us-east-1'}, 'updateDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyMaterial': {'$binary': {'base64': 'AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO', 'subType': '00'}}, 'creationDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyAltNames': ['altname', 'another_altname']}] + +tests: + - description: "Insert with encryption using key alt name" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: insertOne + arguments: + document: &doc0 { _id: 1, encrypted_w_altname: "string0", altname: "altname" } + expectations: + # Auto encryption will request the collection info. + - command_started_event: + command: + listCollections: 1 + filter: + name: *collection_name + command_name: listCollections + # Then key is fetched from the key vault. + - command_started_event: + command: + find: datakeys + filter: {$or: [ { _id: { $in: [] } }, { keyAltNames: { $in: [ "altname" ] } } ] } + $db: keyvault + readConcern: { level: "majority" } + command_name: find + - command_started_event: + command: + insert: *collection_name + documents: + - &doc0_encrypted { _id: 1, encrypted_w_altname: { $$type: "binData" }, altname: "altname" } + ordered: true + command_name: insert + outcome: + collection: + # Outcome is checked using a separate MongoClient without auto encryption. + data: + - *doc0_encrypted + - description: "Replace with key alt name fails" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: updateOne + arguments: + filter: {} + update: { $set: { encrypted_w_altname: "string0" } } + upsert: true + result: + errorContains: "A non-static (JSONPointer) keyId is not supported" + outcome: + collection: + # Outcome is checked using a separate MongoClient without auto encryption. + data: [] \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/kmipKMS.json b/src/test/spec/json/client-side-encryption/legacy/kmipKMS.json new file mode 100644 index 000000000..5749d21ab --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/kmipKMS.json @@ -0,0 +1,223 @@ +{ + "runOn": [ + { + "minServerVersion": "4.1.10" + } + ], + "database_name": "default", + "collection_name": "default", + "data": [], + "json_schema": { + "properties": { + "encrypted_string_aws": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "encrypted_string_azure": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AZURE+AAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "encrypted_string_gcp": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "GCP+AAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "encrypted_string_local": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "encrypted_string_kmip": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "dBHpr8aITfeBQ15grpbLpQ==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + }, + "key_vault_data": [ + { + "_id": { + "$binary": { + "base64": "dBHpr8aITfeBQ15grpbLpQ==", + "subType": "04" + } + }, + "keyMaterial": { + "$binary": { + "base64": "eUYDyB0HuWb+lQgUwO+6qJQyTTDTY2gp9FbemL7ZFo0pvr0x6rm6Ff9OVUTGH6HyMKipaeHdiIJU1dzsLwvqKvi7Beh+U4iaIWX/K0oEg1GOsJc0+Z/in8gNHbGUYLmycHViM3LES3kdt7FdFSUl5rEBHrM71yoNEXImz17QJWMGOuT4x6yoi2pvnaRJwfrI4DjpmnnTrDMac92jgZehbg==", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1634220190041" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1634220190041" + } + }, + "status": { + "$numberInt": "0" + }, + "masterKey": { + "provider": "kmip", + "keyId": "1" + }, + "keyAltNames": [ + "altname", + "kmip_altname" + ] + } + ], + "tests": [ + { + "description": "Insert a document with auto encryption using KMIP KMS provider", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "kmip": {} + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encrypted_string_kmip": "string0" + } + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "default" + } + }, + "command_name": "listCollections" + } + }, + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "dBHpr8aITfeBQ15grpbLpQ==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault" + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "insert": "default", + "documents": [ + { + "_id": 1, + "encrypted_string_kmip": { + "$binary": { + "base64": "AXQR6a/GiE33gUNeYK6Wy6UCKCwtKFIsL8eKObDVxvqGupJNUk7kXswHhB7G5j/C1D+6no+Asra0KgSU43bTL3ooIBLVyIzbV5CDJYqzAsa4WQ==", + "subType": "06" + } + } + } + ], + "ordered": true + }, + "command_name": "insert" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "encrypted_string_kmip": { + "$binary": { + "base64": "AXQR6a/GiE33gUNeYK6Wy6UCKCwtKFIsL8eKObDVxvqGupJNUk7kXswHhB7G5j/C1D+6no+Asra0KgSU43bTL3ooIBLVyIzbV5CDJYqzAsa4WQ==", + "subType": "06" + } + } + } + ] + } + } + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/kmipKMS.yml b/src/test/spec/json/client-side-encryption/legacy/kmipKMS.yml new file mode 100644 index 000000000..874a92bf3 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/kmipKMS.yml @@ -0,0 +1,46 @@ +runOn: + - minServerVersion: "4.1.10" +database_name: &database_name "default" +collection_name: &collection_name "default" + +data: [] +json_schema: {'properties': {'encrypted_string_aws': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'encrypted_string_azure': {'encrypt': {'keyId': [{'$binary': {'base64': 'AZURE+AAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'encrypted_string_gcp': {'encrypt': {'keyId': [{'$binary': {'base64': 'GCP+AAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'encrypted_string_local': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'encrypted_string_kmip': {'encrypt': {'keyId': [{'$binary': {'base64': 'dBHpr8aITfeBQ15grpbLpQ==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} +key_vault_data: [{'_id': {'$binary': {'base64': 'dBHpr8aITfeBQ15grpbLpQ==', 'subType': '04'}}, 'keyMaterial': {'$binary': {'base64': 'eUYDyB0HuWb+lQgUwO+6qJQyTTDTY2gp9FbemL7ZFo0pvr0x6rm6Ff9OVUTGH6HyMKipaeHdiIJU1dzsLwvqKvi7Beh+U4iaIWX/K0oEg1GOsJc0+Z/in8gNHbGUYLmycHViM3LES3kdt7FdFSUl5rEBHrM71yoNEXImz17QJWMGOuT4x6yoi2pvnaRJwfrI4DjpmnnTrDMac92jgZehbg==', 'subType': '00'}}, 'creationDate': {'$date': {'$numberLong': '1634220190041'}}, 'updateDate': {'$date': {'$numberLong': '1634220190041'}}, 'status': {'$numberInt': '0'}, 'masterKey': {'provider': 'kmip', 'keyId': '1'}, 'keyAltNames': ['altname', 'kmip_altname']}] + +tests: + - description: "Insert a document with auto encryption using KMIP KMS provider" + clientOptions: + autoEncryptOpts: + kmsProviders: + kmip: {} + operations: + - name: insertOne + arguments: + document: &doc0 { _id: 1, encrypted_string_kmip: "string0" } + expectations: + # Auto encryption will request the collection info. + - command_started_event: + command: + listCollections: 1 + filter: + name: *collection_name + command_name: listCollections + # Then key is fetched from the key vault. + - command_started_event: + command: + find: datakeys + filter: { $or: [ { _id: { $in: [ {'$binary': {'base64': 'dBHpr8aITfeBQ15grpbLpQ==', 'subType': '04'}} ] } }, { keyAltNames: { $in: [] } } ] } + $db: keyvault + command_name: find + - command_started_event: + command: + insert: *collection_name + documents: + - &doc0_encrypted { _id: 1, encrypted_string_kmip: {'$binary': {'base64': 'AXQR6a/GiE33gUNeYK6Wy6UCKCwtKFIsL8eKObDVxvqGupJNUk7kXswHhB7G5j/C1D+6no+Asra0KgSU43bTL3ooIBLVyIzbV5CDJYqzAsa4WQ==', 'subType': '06'}} } + ordered: true + command_name: insert + outcome: + collection: + # Outcome is checked using a separate MongoClient without auto encryption. + data: + - *doc0_encrypted \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/localKMS.json b/src/test/spec/json/client-side-encryption/legacy/localKMS.json new file mode 100644 index 000000000..67c4ba130 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/localKMS.json @@ -0,0 +1,191 @@ +{ + "runOn": [ + { + "minServerVersion": "4.1.10" + } + ], + "database_name": "default", + "collection_name": "default", + "data": [], + "json_schema": { + "properties": { + "encrypted_string": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "random": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + } + }, + "bsonType": "object" + }, + "key_vault_data": [ + { + "_id": { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + }, + "keyMaterial": { + "$binary": { + "base64": "Ce9HSz/HKKGkIt4uyy+jDuKGA+rLC2cycykMo6vc8jXxqa1UVDYHWq1r+vZKbnnSRBfB981akzRKZCFpC05CTyFqDhXv6OnMjpG97OZEREGIsHEYiJkBW0jJJvfLLgeLsEpBzsro9FztGGXASxyxFRZFhXvHxyiLOKrdWfs7X1O/iK3pEoHMx6uSNSfUOgbebLfIqW7TO++iQS5g1xovXA==", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "status": { + "$numberInt": "0" + }, + "masterKey": { + "provider": "local" + } + } + ], + "tests": [ + { + "description": "Insert a document with auto encryption using local KMS provider", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {}, + "local": { + "key": { + "$binary": { + "base64": "Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk", + "subType": "00" + } + } + } + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encrypted_string": "string0", + "random": "abc" + } + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "default" + } + }, + "command_name": "listCollections" + } + }, + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault" + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "insert": "default", + "documents": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACV/+zJmpqMU47yxS/xIVAviGi7wHDuFwaULAixEAoIh0xHz73UYOM3D8D44gcJn67EROjbz4ITpYzzlCJovDL0Q==", + "subType": "06" + } + }, + "random": { + "$$type": "binData" + } + } + ], + "ordered": true + }, + "command_name": "insert" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACV/+zJmpqMU47yxS/xIVAviGi7wHDuFwaULAixEAoIh0xHz73UYOM3D8D44gcJn67EROjbz4ITpYzzlCJovDL0Q==", + "subType": "06" + } + }, + "random": { + "$$type": "binData" + } + } + ] + } + } + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/localKMS.yml b/src/test/spec/json/client-side-encryption/legacy/localKMS.yml new file mode 100644 index 000000000..4c0d962f3 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/localKMS.yml @@ -0,0 +1,47 @@ +runOn: + - minServerVersion: "4.1.10" +database_name: &database_name "default" +collection_name: &collection_name "default" + +data: [] +json_schema: {'properties': {'encrypted_string': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'random': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}}, 'bsonType': 'object'} +key_vault_data: [{'_id': {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}, 'keyMaterial': {'$binary': {'base64': 'Ce9HSz/HKKGkIt4uyy+jDuKGA+rLC2cycykMo6vc8jXxqa1UVDYHWq1r+vZKbnnSRBfB981akzRKZCFpC05CTyFqDhXv6OnMjpG97OZEREGIsHEYiJkBW0jJJvfLLgeLsEpBzsro9FztGGXASxyxFRZFhXvHxyiLOKrdWfs7X1O/iK3pEoHMx6uSNSfUOgbebLfIqW7TO++iQS5g1xovXA==', 'subType': '00'}}, 'creationDate': {'$date': {'$numberLong': '1552949630483'}}, 'updateDate': {'$date': {'$numberLong': '1552949630483'}}, 'status': {'$numberInt': '0'}, 'masterKey': {'provider': 'local'}}] + +tests: + - description: "Insert a document with auto encryption using local KMS provider" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + local: {'key': {'$binary': {'base64': 'Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk', 'subType': '00'}}} + operations: + - name: insertOne + arguments: + document: &doc0 { _id: 1, encrypted_string: "string0", random: "abc" } + expectations: + # Auto encryption will request the collection info. + - command_started_event: + command: + listCollections: 1 + filter: + name: *collection_name + command_name: listCollections + # Then key is fetched from the key vault. + - command_started_event: + command: + find: datakeys + filter: { $or: [ { _id: { $in: [ {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}} ] } }, { keyAltNames: { $in: [] } } ] } + $db: keyvault + command_name: find + - command_started_event: + command: + insert: *collection_name + documents: + - &doc0_encrypted { _id: 1, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACV/+zJmpqMU47yxS/xIVAviGi7wHDuFwaULAixEAoIh0xHz73UYOM3D8D44gcJn67EROjbz4ITpYzzlCJovDL0Q==', 'subType': '06'}}, random: { $$type: "binData" } } + ordered: true + command_name: insert + outcome: + collection: + # Outcome is checked using a separate MongoClient without auto encryption. + data: + - *doc0_encrypted \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/localSchema.json b/src/test/spec/json/client-side-encryption/legacy/localSchema.json new file mode 100644 index 000000000..4698520f6 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/localSchema.json @@ -0,0 +1,258 @@ +{ + "runOn": [ + { + "minServerVersion": "4.1.10" + } + ], + "database_name": "default", + "collection_name": "default", + "data": [], + "json_schema": {}, + "key_vault_data": [ + { + "status": 1, + "_id": { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + }, + "masterKey": { + "provider": "aws", + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "region": "us-east-1" + }, + "updateDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyMaterial": { + "$binary": { + "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyAltNames": [ + "altname", + "another_altname" + ] + } + ], + "tests": [ + { + "description": "A local schema should override", + "clientOptions": { + "autoEncryptOpts": { + "schemaMap": { + "default.default": { + "properties": { + "encrypted_w_altname": { + "encrypt": { + "keyId": "/altname", + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "random": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string_equivalent": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + } + }, + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encrypted_string": "string0" + } + } + }, + { + "name": "find", + "arguments": { + "filter": { + "_id": 1 + } + }, + "result": [ + { + "_id": 1, + "encrypted_string": "string0" + } + ] + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "insert": "default", + "documents": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + } + ], + "ordered": true + }, + "command_name": "insert" + } + }, + { + "command_started_event": { + "command": { + "find": "default", + "filter": { + "_id": 1 + } + }, + "command_name": "find" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + } + ] + } + } + }, + { + "description": "A local schema with no encryption is an error", + "clientOptions": { + "autoEncryptOpts": { + "schemaMap": { + "default.default": { + "properties": { + "test": { + "bsonType": "string" + } + }, + "bsonType": "object", + "required": [ + "test" + ] + } + }, + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encrypted_string": "string0" + } + }, + "result": { + "errorContains": "JSON schema keyword 'required' is only allowed with a remote schema" + } + } + ] + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/localSchema.yml b/src/test/spec/json/client-side-encryption/legacy/localSchema.yml new file mode 100644 index 000000000..89b4bd51d --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/localSchema.yml @@ -0,0 +1,65 @@ +runOn: + - minServerVersion: "4.1.10" +database_name: &database_name "default" +collection_name: &collection_name "default" + +data: [] +# configure an empty schema +json_schema: {} +key_vault_data: [{'status': 1, '_id': {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}, 'masterKey': {'provider': 'aws', 'key': 'arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0', 'region': 'us-east-1'}, 'updateDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyMaterial': {'$binary': {'base64': 'AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO', 'subType': '00'}}, 'creationDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyAltNames': ['altname', 'another_altname']}] + +tests: + - description: "A local schema should override" + clientOptions: + autoEncryptOpts: + schemaMap: + "default.default": {'properties': {'encrypted_w_altname': {'encrypt': {'keyId': '/altname', 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'random': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string_equivalent': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: insertOne + arguments: + document: &doc0 { _id: 1, encrypted_string: "string0" } + - name: find + arguments: + filter: { _id: 1 } + result: [*doc0] + expectations: + # Then key is fetched from the key vault. + - command_started_event: + command: + find: datakeys + filter: {"$or": [{"_id": {"$in": [ {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}} ] }}, {"keyAltNames": {"$in": []}}]} + $db: keyvault + readConcern: { level: "majority" } + command_name: find + - command_started_event: + command: + insert: *collection_name + documents: + - &doc0_encrypted { _id: 1, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==', 'subType': '06'}} } + ordered: true + command_name: insert + - command_started_event: + command: + find: *collection_name + filter: { _id: 1 } + command_name: find + outcome: + collection: + # Outcome is checked using a separate MongoClient without auto encryption. + data: + - *doc0_encrypted + - description: "A local schema with no encryption is an error" + clientOptions: + autoEncryptOpts: + schemaMap: + "default.default": {'properties': {'test': {'bsonType': 'string'}}, 'bsonType': 'object', 'required': ['test']} + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: insertOne + arguments: + document: { _id: 1, encrypted_string: "string0" } + result: + errorContains: "JSON schema keyword 'required' is only allowed with a remote schema" \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/malformedCiphertext.json b/src/test/spec/json/client-side-encryption/legacy/malformedCiphertext.json new file mode 100644 index 000000000..c81330ce8 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/malformedCiphertext.json @@ -0,0 +1,321 @@ +{ + "runOn": [ + { + "minServerVersion": "4.1.10" + } + ], + "database_name": "default", + "collection_name": "default", + "data": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", + "subType": "00" + } + } + }, + { + "_id": 2, + "encrypted_string": { + "$binary": { + "base64": "AQ==", + "subType": "06" + } + } + }, + { + "_id": 3, + "encrypted_string": { + "$binary": { + "base64": "AQAAa2V2aW4gYWxiZXJ0c29uCg==", + "subType": "06" + } + } + } + ], + "key_vault_data": [ + { + "status": 1, + "_id": { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + }, + "masterKey": { + "provider": "aws", + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "region": "us-east-1" + }, + "updateDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyMaterial": { + "$binary": { + "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyAltNames": [ + "altname", + "another_altname" + ] + } + ], + "tests": [ + { + "description": "Wrong subtype", + "clientOptions": { + "autoEncryptOpts": { + "schemaMap": { + "default.default": { + "properties": { + "encrypted_w_altname": { + "encrypt": { + "keyId": "/altname", + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "random": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string_equivalent": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + } + }, + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "find", + "arguments": { + "filter": { + "_id": 1 + } + }, + "result": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", + "subType": "00" + } + } + } + ] + } + ] + }, + { + "description": "Empty data", + "clientOptions": { + "autoEncryptOpts": { + "schemaMap": { + "default.default": { + "properties": { + "encrypted_w_altname": { + "encrypt": { + "keyId": "/altname", + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "random": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string_equivalent": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + } + }, + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "find", + "arguments": { + "filter": { + "_id": 2 + } + }, + "result": { + "errorContains": "malformed ciphertext" + } + } + ] + }, + { + "description": "Malformed data", + "clientOptions": { + "autoEncryptOpts": { + "schemaMap": { + "default.default": { + "properties": { + "encrypted_w_altname": { + "encrypt": { + "keyId": "/altname", + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "random": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string_equivalent": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + } + }, + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "find", + "arguments": { + "filter": { + "_id": 3 + } + }, + "result": { + "errorContains": "not all keys requested were satisfied" + } + } + ] + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/malformedCiphertext.yml b/src/test/spec/json/client-side-encryption/legacy/malformedCiphertext.yml new file mode 100644 index 000000000..e27c1dfdc --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/malformedCiphertext.yml @@ -0,0 +1,69 @@ +runOn: + - minServerVersion: "4.1.10" +database_name: &database_name "default" +collection_name: &collection_name "default" + +data: + - &doc0 + _id: 1 + encrypted_string: + $binary: + base64: AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg== + subType: "00" + - _id: 2 + encrypted_string: + $binary: + base64: "AQ==" + subType: "06" + - _id: 3 + encrypted_string: + $binary: + base64: "AQAAa2V2aW4gYWxiZXJ0c29uCg==" + subType: "06" + +# Since test requires invalid data to be inserted, use a local schema. +key_vault_data: [{'status': 1, '_id': {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}, 'masterKey': {'provider': 'aws', 'key': 'arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0', 'region': 'us-east-1'}, 'updateDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyMaterial': {'$binary': {'base64': 'AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO', 'subType': '00'}}, 'creationDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyAltNames': ['altname', 'another_altname']}] + +tests: + - description: "Wrong subtype" + clientOptions: + autoEncryptOpts: + schemaMap: + "default.default": {'properties': {'encrypted_w_altname': {'encrypt': {'keyId': '/altname', 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'random': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string_equivalent': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: find + arguments: + filter: { _id: 1 } + result: + # gets returned without decryption + - *doc0 + - description: "Empty data" + clientOptions: + autoEncryptOpts: + schemaMap: + "default.default": {'properties': {'encrypted_w_altname': {'encrypt': {'keyId': '/altname', 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'random': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string_equivalent': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: find + arguments: + filter: { _id: 2 } + result: + errorContains: "malformed ciphertext" + - description: "Malformed data" + clientOptions: + autoEncryptOpts: + schemaMap: + "default.default": {'properties': {'encrypted_w_altname': {'encrypt': {'keyId': '/altname', 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'random': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string_equivalent': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: find + arguments: + filter: { _id: 3 } + result: + # ciphertext can only validate subtype (which is correct) + # but takes the 16 byte UUID to look up key. Fails to find. + errorContains: "not all keys requested were satisfied" \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/maxWireVersion.json b/src/test/spec/json/client-side-encryption/legacy/maxWireVersion.json new file mode 100644 index 000000000..f04f58dff --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/maxWireVersion.json @@ -0,0 +1,74 @@ +{ + "runOn": [ + { + "maxServerVersion": "4.0.99" + } + ], + "database_name": "default", + "collection_name": "default", + "data": [], + "key_vault_data": [ + { + "status": 1, + "_id": { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + }, + "masterKey": { + "provider": "aws", + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "region": "us-east-1" + }, + "updateDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyMaterial": { + "$binary": { + "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyAltNames": [ + "altname", + "another_altname" + ] + } + ], + "tests": [ + { + "description": "operation fails with maxWireVersion < 8", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + }, + "extraOptions": { + "mongocryptdBypassSpawn": true + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "encrypted_string": "string0" + } + }, + "result": { + "errorContains": "Auto-encryption requires a minimum MongoDB version of 4.2" + } + } + ] + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/maxWireVersion.yml b/src/test/spec/json/client-side-encryption/legacy/maxWireVersion.yml new file mode 100644 index 000000000..87c4c993f --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/maxWireVersion.yml @@ -0,0 +1,22 @@ +runOn: + - maxServerVersion: "4.0.99" +database_name: &database_name "default" +collection_name: &collection_name "default" + +data: [] +key_vault_data: [{'status': 1, '_id': {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}, 'masterKey': {'provider': 'aws', 'key': 'arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0', 'region': 'us-east-1'}, 'updateDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyMaterial': {'$binary': {'base64': 'AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO', 'subType': '00'}}, 'creationDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyAltNames': ['altname', 'another_altname']}] + +tests: + - description: "operation fails with maxWireVersion < 8" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + extraOptions: + mongocryptdBypassSpawn: true # mongocryptd probably won't be on the path + operations: + - name: insertOne + arguments: + document: { encrypted_string: "string0" } + result: + errorContains: "Auto-encryption requires a minimum MongoDB version of 4.2" \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/missingKey.json b/src/test/spec/json/client-side-encryption/legacy/missingKey.json new file mode 100644 index 000000000..275147bb7 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/missingKey.json @@ -0,0 +1,179 @@ +{ + "runOn": [ + { + "minServerVersion": "4.1.10" + } + ], + "database_name": "default", + "collection_name": "default", + "data": [], + "json_schema": { + "properties": { + "encrypted_w_altname": { + "encrypt": { + "keyId": "/altname", + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "random": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string_equivalent": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + }, + "key_vault_data": [ + { + "status": 1, + "_id": { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + }, + "masterKey": { + "provider": "aws", + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "region": "us-east-1" + }, + "updateDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyMaterial": { + "$binary": { + "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyAltNames": [ + "altname", + "another_altname" + ] + } + ], + "tests": [ + { + "description": "Insert with encryption on a missing key", + "clientOptions": { + "autoEncryptOpts": { + "keyVaultNamespace": "keyvault.different", + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encrypted_string": "string0", + "random": "abc" + } + }, + "result": { + "errorContains": "not all keys requested were satisfied" + } + } + ], + "outcome": { + "collection": { + "data": [] + } + }, + "expectations": [ + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "default" + } + }, + "command_name": "listCollections" + } + }, + { + "command_started_event": { + "command": { + "find": "different", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + } + ] + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/missingKey.yml b/src/test/spec/json/client-side-encryption/legacy/missingKey.yml new file mode 100644 index 000000000..2be539510 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/missingKey.yml @@ -0,0 +1,42 @@ +runOn: + - minServerVersion: "4.1.10" +database_name: &database_name "default" +collection_name: &collection_name "default" + +data: [] +json_schema: {'properties': {'encrypted_w_altname': {'encrypt': {'keyId': '/altname', 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'random': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string_equivalent': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} +key_vault_data: [{'status': 1, '_id': {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}, 'masterKey': {'provider': 'aws', 'key': 'arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0', 'region': 'us-east-1'}, 'updateDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyMaterial': {'$binary': {'base64': 'AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO', 'subType': '00'}}, 'creationDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyAltNames': ['altname', 'another_altname']}] + +tests: + - description: "Insert with encryption on a missing key" + clientOptions: + autoEncryptOpts: + keyVaultNamespace: "keyvault.different" + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: insertOne + arguments: + document: &doc0 { _id: 1, encrypted_string: "string0", random: "abc" } + result: + errorContains: "not all keys requested were satisfied" + outcome: + collection: + # Outcome is checked using a separate MongoClient without auto encryption. + data: [] + expectations: + # Auto encryption will request the collection info. + - command_started_event: + command: + listCollections: 1 + filter: + name: *collection_name + command_name: listCollections + # Then key is fetched from the key vault. + - command_started_event: + command: + find: different + filter: {"$or": [{"_id": {"$in": [ {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}} ] }}, {"keyAltNames": {"$in": []}}]} + $db: keyvault + readConcern: { level: "majority" } + command_name: find \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/noSchema.json b/src/test/spec/json/client-side-encryption/legacy/noSchema.json new file mode 100644 index 000000000..095434f88 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/noSchema.json @@ -0,0 +1,67 @@ +{ + "runOn": [ + { + "minServerVersion": "4.1.10" + } + ], + "database_name": "default", + "collection_name": "unencrypted", + "tests": [ + { + "description": "Insert on an unencrypted collection", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1 + } + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "unencrypted" + } + }, + "command_name": "listCollections" + } + }, + { + "command_started_event": { + "command": { + "insert": "unencrypted", + "documents": [ + { + "_id": 1 + } + ], + "ordered": true + }, + "command_name": "insert" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1 + } + ] + } + } + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/noSchema.yml b/src/test/spec/json/client-side-encryption/legacy/noSchema.yml new file mode 100644 index 000000000..5c6811688 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/noSchema.yml @@ -0,0 +1,37 @@ +# Test auto encryption on a collection with no jsonSchema configured. +# This is a regression test for MONGOCRYPT-378/PYTHON-3188. +runOn: + - minServerVersion: "4.1.10" +database_name: &database_name "default" +collection_name: &collection_name "unencrypted" + +tests: + - description: "Insert on an unencrypted collection" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: insertOne + arguments: + document: &doc0 { _id: 1 } + expectations: + # Auto encryption will request the collection info. + - command_started_event: + command: + listCollections: 1 + filter: + name: *collection_name + command_name: listCollections + - command_started_event: + command: + insert: *collection_name + documents: + - *doc0 + ordered: true + command_name: insert + outcome: + collection: + # Outcome is checked using a separate MongoClient without auto encryption. + data: + - *doc0 \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/replaceOne.json b/src/test/spec/json/client-side-encryption/legacy/replaceOne.json new file mode 100644 index 000000000..975768681 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/replaceOne.json @@ -0,0 +1,239 @@ +{ + "runOn": [ + { + "minServerVersion": "4.1.10" + } + ], + "database_name": "default", + "collection_name": "default", + "data": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + } + ], + "json_schema": { + "properties": { + "encrypted_w_altname": { + "encrypt": { + "keyId": "/altname", + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "random": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string_equivalent": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + }, + "key_vault_data": [ + { + "status": 1, + "_id": { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + }, + "masterKey": { + "provider": "aws", + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "region": "us-east-1" + }, + "updateDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyMaterial": { + "$binary": { + "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyAltNames": [ + "altname", + "another_altname" + ] + } + ], + "tests": [ + { + "description": "replaceOne with encryption", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "replaceOne", + "arguments": { + "filter": { + "encrypted_string": "string0" + }, + "replacement": { + "encrypted_string": "string1", + "random": "abc" + } + }, + "result": { + "matchedCount": 1, + "modifiedCount": 1, + "upsertedCount": 0 + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "default" + } + }, + "command_name": "listCollections" + } + }, + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "update": "default", + "updates": [ + { + "q": { + "encrypted_string": { + "$eq": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + } + }, + "u": { + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", + "subType": "06" + } + }, + "random": { + "$$type": "binData" + } + } + } + ], + "ordered": true + }, + "command_name": "update" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", + "subType": "06" + } + }, + "random": { + "$$type": "binData" + } + } + ] + } + } + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/replaceOne.yml b/src/test/spec/json/client-side-encryption/legacy/replaceOne.yml new file mode 100644 index 000000000..e3b50a828 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/replaceOne.yml @@ -0,0 +1,54 @@ +runOn: + - minServerVersion: "4.1.10" +database_name: &database_name "default" +collection_name: &collection_name "default" + +data: + - &doc0_encrypted { _id: 1, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==', 'subType': '06'}} } +json_schema: {'properties': {'encrypted_w_altname': {'encrypt': {'keyId': '/altname', 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'random': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string_equivalent': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} +key_vault_data: [{'status': 1, '_id': {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}, 'masterKey': {'provider': 'aws', 'key': 'arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0', 'region': 'us-east-1'}, 'updateDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyMaterial': {'$binary': {'base64': 'AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO', 'subType': '00'}}, 'creationDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyAltNames': ['altname', 'another_altname']}] + +tests: + - description: "replaceOne with encryption" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: replaceOne + arguments: + filter: { encrypted_string: "string0" } + replacement: { encrypted_string: "string1", random: "abc" } + result: + matchedCount: 1 + modifiedCount: 1 + upsertedCount: 0 + expectations: + # Auto encryption will request the collection info. + - command_started_event: + command: + listCollections: 1 + filter: + name: *collection_name + command_name: listCollections + # Then key is fetched from the key vault. + - command_started_event: + command: + find: datakeys + filter: {"$or": [{"_id": {"$in": [ {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}} ] }}, {"keyAltNames": {"$in": []}}]} + $db: keyvault + readConcern: { level: "majority" } + command_name: find + - command_started_event: + command: + update: *collection_name + updates: + - q: { encrypted_string: { $eq: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==', 'subType': '06'}} } } + u: { encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==', 'subType': '06'}}, random: { $$type: "binData" } } + ordered: true + command_name: update + outcome: + collection: + # Outcome is checked using a separate MongoClient without auto encryption. + data: + - { _id: 1, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==', 'subType': '06'}}, random: { $$type: "binData" } } \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/timeoutMS.json b/src/test/spec/json/client-side-encryption/legacy/timeoutMS.json new file mode 100644 index 000000000..443aa0aa2 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/timeoutMS.json @@ -0,0 +1,200 @@ +{ + "runOn": [ + { + "minServerVersion": "4.4" + } + ], + "database_name": "cse-timeouts-db", + "collection_name": "cse-timeouts-coll", + "data": [], + "json_schema": { + "properties": { + "encrypted_w_altname": { + "encrypt": { + "keyId": "/altname", + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "random": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string_equivalent": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + }, + "key_vault_data": [ + { + "status": 1, + "_id": { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + }, + "masterKey": { + "provider": "aws", + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "region": "us-east-1" + }, + "updateDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyMaterial": { + "$binary": { + "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyAltNames": [ + "altname", + "another_altname" + ] + } + ], + "tests": [ + { + "description": "timeoutMS applied to listCollections to get collection schema", + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "times": 1 + }, + "data": { + "failCommands": [ + "listCollections" + ], + "blockConnection": true, + "blockTimeMS": 60 + } + }, + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + }, + "timeoutMS": 50 + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encrypted_string": "string0", + "random": "abc" + } + }, + "result": { + "isTimeoutError": true + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "cse-timeouts-coll" + }, + "maxTimeMS": { + "$$type": [ + "int", + "long" + ] + } + }, + "command_name": "listCollections" + } + } + ] + }, + { + "description": "remaining timeoutMS applied to find to get keyvault data", + "failPoint": { + "configureFailPoint": "failCommand", + "mode": { + "times": 3 + }, + "data": { + "failCommands": [ + "listCollections", + "find" + ], + "blockConnection": true, + "blockTimeMS": 20 + } + }, + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + }, + "timeoutMS": 50 + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encrypted_string": "string0", + "random": "abc" + } + }, + "result": { + "isTimeoutError": true + } + } + ] + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/timeoutMS.yml b/src/test/spec/json/client-side-encryption/legacy/timeoutMS.yml new file mode 100644 index 000000000..33321ad64 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/timeoutMS.yml @@ -0,0 +1,65 @@ +runOn: + - minServerVersion: "4.4" +database_name: &database_name "cse-timeouts-db" +collection_name: &collection_name "cse-timeouts-coll" + +data: [] +json_schema: {'properties': {'encrypted_w_altname': {'encrypt': {'keyId': '/altname', 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'random': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string_equivalent': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} +key_vault_data: [{'status': 1, '_id': {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}, 'masterKey': {'provider': 'aws', 'key': 'arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0', 'region': 'us-east-1'}, 'updateDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyMaterial': {'$binary': {'base64': 'AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO', 'subType': '00'}}, 'creationDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyAltNames': ['altname', 'another_altname']}] + +tests: + - description: "timeoutMS applied to listCollections to get collection schema" + failPoint: + configureFailPoint: failCommand + mode: { times: 1 } + data: + failCommands: ["listCollections"] + blockConnection: true + blockTimeMS: 60 + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + timeoutMS: 50 + operations: + - name: insertOne + arguments: + document: &doc0 { _id: 1, encrypted_string: "string0", random: "abc" } + result: + isTimeoutError: true + expectations: + # Auto encryption will request the collection info. + - command_started_event: + command: + listCollections: 1 + filter: + name: *collection_name + maxTimeMS: { $$type: ["int", "long"] } + command_name: listCollections + + # Test that timeoutMS applies to the sum of all operations done for client-side encryption. This is done by blocking + # listCollections and find for 20ms each and running an insertOne with timeoutMS=50. There should be two + # listCollections commands and one "find" command, so the sum should take more than timeoutMS. + # + # This test does not include command monitoring expectations because the exact command sequence is dependent on the + # amount of time taken by mongocryptd communication. In slow runs, mongocryptd communication can breach the timeout + # and result in the final "find" not being sent. + - description: "remaining timeoutMS applied to find to get keyvault data" + failPoint: + configureFailPoint: failCommand + mode: { times: 3 } + data: + failCommands: ["listCollections", "find"] + blockConnection: true + blockTimeMS: 20 + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + timeoutMS: 50 + operations: + - name: insertOne + arguments: + document: *doc0 + result: + isTimeoutError: true \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/types.json b/src/test/spec/json/client-side-encryption/legacy/types.json new file mode 100644 index 000000000..a6c6507e9 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/types.json @@ -0,0 +1,1646 @@ +{ + "runOn": [ + { + "minServerVersion": "4.1.10" + } + ], + "database_name": "default", + "collection_name": "default", + "data": [], + "json_schema": {}, + "key_vault_data": [ + { + "status": 1, + "_id": { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + }, + "masterKey": { + "provider": "aws", + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "region": "us-east-1" + }, + "updateDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyMaterial": { + "$binary": { + "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyAltNames": [ + "altname", + "another_altname" + ] + } + ], + "tests": [ + { + "description": "type=objectId", + "clientOptions": { + "autoEncryptOpts": { + "schemaMap": { + "default.default": { + "properties": { + "encrypted_objectId": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "objectId", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + } + }, + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encrypted_objectId": { + "$oid": "AAAAAAAAAAAAAAAAAAAAAAAA" + } + } + } + }, + { + "name": "findOne", + "arguments": { + "filter": { + "_id": 1 + } + }, + "result": { + "_id": 1, + "encrypted_objectId": { + "$oid": "AAAAAAAAAAAAAAAAAAAAAAAA" + } + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "insert": "default", + "documents": [ + { + "_id": 1, + "encrypted_objectId": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAAHmkTPqvzfHMWpvS1mEsrjOxVQ2dyihEgIFWD5E0eNEsiMBQsC0GuvjdqYRL5DHLFI1vKuGek7EYYp0Qyii/tHqA==", + "subType": "06" + } + } + } + ], + "ordered": true + }, + "command_name": "insert" + } + }, + { + "command_started_event": { + "command": { + "find": "default", + "filter": { + "_id": 1 + } + }, + "command_name": "find" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "encrypted_objectId": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAAHmkTPqvzfHMWpvS1mEsrjOxVQ2dyihEgIFWD5E0eNEsiMBQsC0GuvjdqYRL5DHLFI1vKuGek7EYYp0Qyii/tHqA==", + "subType": "06" + } + } + } + ] + } + } + }, + { + "description": "type=symbol", + "clientOptions": { + "autoEncryptOpts": { + "schemaMap": { + "default.default": { + "properties": { + "encrypted_symbol": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "symbol", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + } + }, + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encrypted_symbol": { + "$symbol": "test" + } + } + } + }, + { + "name": "findOne", + "arguments": { + "filter": { + "_id": 1 + } + }, + "result": { + "_id": 1, + "encrypted_symbol": { + "$symbol": "test" + } + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "insert": "default", + "documents": [ + { + "_id": 1, + "encrypted_symbol": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAAOOmvDmWjcuKsSCO7U/7t9HJ8eI73B6wduyMbdkvn7n7V4uTJes/j+BTtneSdyG2JHKHGkevWAJSIU2XoO66BSXw==", + "subType": "06" + } + } + } + ], + "ordered": true + }, + "command_name": "insert" + } + }, + { + "command_started_event": { + "command": { + "find": "default", + "filter": { + "_id": 1 + } + }, + "command_name": "find" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "encrypted_symbol": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAAOOmvDmWjcuKsSCO7U/7t9HJ8eI73B6wduyMbdkvn7n7V4uTJes/j+BTtneSdyG2JHKHGkevWAJSIU2XoO66BSXw==", + "subType": "06" + } + } + } + ] + } + } + }, + { + "description": "type=int", + "clientOptions": { + "autoEncryptOpts": { + "schemaMap": { + "default.default": { + "properties": { + "encrypted_int": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "int", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + } + }, + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encrypted_int": { + "$numberInt": "123" + } + } + } + }, + { + "name": "findOne", + "arguments": { + "filter": { + "_id": 1 + } + }, + "result": { + "_id": 1, + "encrypted_int": { + "$numberInt": "123" + } + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "insert": "default", + "documents": [ + { + "_id": 1, + "encrypted_int": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAAQPNXJVXMEjGZnftMuf2INKufXCtQIRHdw5wTgn6QYt3ejcoAXyiwI4XIUizkpsob494qpt2in4tWeiO7b9zkA8Q==", + "subType": "06" + } + } + } + ], + "ordered": true + }, + "command_name": "insert" + } + }, + { + "command_started_event": { + "command": { + "find": "default", + "filter": { + "_id": 1 + } + }, + "command_name": "find" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "encrypted_int": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAAQPNXJVXMEjGZnftMuf2INKufXCtQIRHdw5wTgn6QYt3ejcoAXyiwI4XIUizkpsob494qpt2in4tWeiO7b9zkA8Q==", + "subType": "06" + } + } + } + ] + } + } + }, + { + "description": "type=double", + "clientOptions": { + "autoEncryptOpts": { + "schemaMap": { + "default.default": { + "properties": { + "encrypted_double": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "double", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + } + }, + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encrypted_double": { + "$numberDouble": "1.23" + } + } + }, + "result": { + "errorContains": "element of type: double" + } + } + ] + }, + { + "description": "type=decimal", + "clientOptions": { + "autoEncryptOpts": { + "schemaMap": { + "default.default": { + "properties": { + "encrypted_decimal": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "decimal", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + } + }, + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encrypted_decimal": { + "$numberDecimal": "1.23" + } + } + }, + "result": { + "errorContains": "element of type: decimal" + } + } + ] + }, + { + "description": "type=binData", + "clientOptions": { + "autoEncryptOpts": { + "schemaMap": { + "default.default": { + "properties": { + "encrypted_binData": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "binData", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + } + }, + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encrypted_binData": { + "$binary": { + "base64": "AAAA", + "subType": "00" + } + } + } + } + }, + { + "name": "findOne", + "arguments": { + "filter": { + "_id": 1 + } + }, + "result": { + "_id": 1, + "encrypted_binData": { + "$binary": { + "base64": "AAAA", + "subType": "00" + } + } + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "insert": "default", + "documents": [ + { + "_id": 1, + "encrypted_binData": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAAFB/KHZQHaHHo8fctcl7v6kR+sLkJoTRx2cPSSck9ya+nbGROSeFhdhDRHaCzhV78fDEqnMDSVPNi+ZkbaIh46GQ==", + "subType": "06" + } + } + } + ], + "ordered": true + }, + "command_name": "insert" + } + }, + { + "command_started_event": { + "command": { + "find": "default", + "filter": { + "_id": 1 + } + }, + "command_name": "find" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "encrypted_binData": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAAFB/KHZQHaHHo8fctcl7v6kR+sLkJoTRx2cPSSck9ya+nbGROSeFhdhDRHaCzhV78fDEqnMDSVPNi+ZkbaIh46GQ==", + "subType": "06" + } + } + } + ] + } + } + }, + { + "description": "type=javascript", + "clientOptions": { + "autoEncryptOpts": { + "schemaMap": { + "default.default": { + "properties": { + "encrypted_javascript": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "javascript", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + } + }, + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encrypted_javascript": { + "$code": "var x = 1;" + } + } + } + }, + { + "name": "findOne", + "arguments": { + "filter": { + "_id": 1 + } + }, + "result": { + "_id": 1, + "encrypted_javascript": { + "$code": "var x = 1;" + } + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "insert": "default", + "documents": [ + { + "_id": 1, + "encrypted_javascript": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAANrvMgJkTKWGMc9wt3E2RBR2Hu5gL9p+vIIdHe9FcOm99t1W480/oX1Gnd87ON3B399DuFaxi/aaIiQSo7gTX6Lw==", + "subType": "06" + } + } + } + ], + "ordered": true + }, + "command_name": "insert" + } + }, + { + "command_started_event": { + "command": { + "find": "default", + "filter": { + "_id": 1 + } + }, + "command_name": "find" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "encrypted_javascript": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAANrvMgJkTKWGMc9wt3E2RBR2Hu5gL9p+vIIdHe9FcOm99t1W480/oX1Gnd87ON3B399DuFaxi/aaIiQSo7gTX6Lw==", + "subType": "06" + } + } + } + ] + } + } + }, + { + "description": "type=javascriptWithScope", + "clientOptions": { + "autoEncryptOpts": { + "schemaMap": { + "default.default": { + "properties": { + "encrypted_javascriptWithScope": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "javascriptWithScope", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + } + }, + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encrypted_javascriptWithScope": { + "$code": "var x = 1;", + "$scope": {} + } + } + }, + "result": { + "errorContains": "element of type: javascriptWithScope" + } + } + ] + }, + { + "description": "type=object", + "clientOptions": { + "autoEncryptOpts": { + "schemaMap": { + "default.default": { + "properties": { + "encrypted_object": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "object", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + } + }, + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encrypted_object": {} + } + }, + "result": { + "errorContains": "element of type: object" + } + } + ] + }, + { + "description": "type=timestamp", + "clientOptions": { + "autoEncryptOpts": { + "schemaMap": { + "default.default": { + "properties": { + "encrypted_timestamp": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "timestamp", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + } + }, + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encrypted_timestamp": { + "$timestamp": { + "t": 123, + "i": 456 + } + } + } + } + }, + { + "name": "findOne", + "arguments": { + "filter": { + "_id": 1 + } + }, + "result": { + "_id": 1, + "encrypted_timestamp": { + "$timestamp": { + "t": 123, + "i": 456 + } + } + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "insert": "default", + "documents": [ + { + "_id": 1, + "encrypted_timestamp": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAARJHaM4Gq3MpDTdBasBsEolQaOmxJQU1wsZVaSFAOLpEh1QihDglXI95xemePFMKhg+KNpFg7lw1ChCs2Wn/c26Q==", + "subType": "06" + } + } + } + ], + "ordered": true + }, + "command_name": "insert" + } + }, + { + "command_started_event": { + "command": { + "find": "default", + "filter": { + "_id": 1 + } + }, + "command_name": "find" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "encrypted_timestamp": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAARJHaM4Gq3MpDTdBasBsEolQaOmxJQU1wsZVaSFAOLpEh1QihDglXI95xemePFMKhg+KNpFg7lw1ChCs2Wn/c26Q==", + "subType": "06" + } + } + } + ] + } + } + }, + { + "description": "type=regex", + "clientOptions": { + "autoEncryptOpts": { + "schemaMap": { + "default.default": { + "properties": { + "encrypted_regex": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "regex", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + } + }, + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encrypted_regex": { + "$regularExpression": { + "pattern": "test", + "options": "" + } + } + } + } + }, + { + "name": "findOne", + "arguments": { + "filter": { + "_id": 1 + } + }, + "result": { + "_id": 1, + "encrypted_regex": { + "$regularExpression": { + "pattern": "test", + "options": "" + } + } + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "insert": "default", + "documents": [ + { + "_id": 1, + "encrypted_regex": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAALVnxM4UqGhqf5eXw6nsS08am3YJrTf1EvjKitT8tyyMAbHsICIU3GUjuC7EBofCHbusvgo7pDyaClGostFz44nA==", + "subType": "06" + } + } + } + ], + "ordered": true + }, + "command_name": "insert" + } + }, + { + "command_started_event": { + "command": { + "find": "default", + "filter": { + "_id": 1 + } + }, + "command_name": "find" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "encrypted_regex": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAALVnxM4UqGhqf5eXw6nsS08am3YJrTf1EvjKitT8tyyMAbHsICIU3GUjuC7EBofCHbusvgo7pDyaClGostFz44nA==", + "subType": "06" + } + } + } + ] + } + } + }, + { + "description": "type=date", + "clientOptions": { + "autoEncryptOpts": { + "schemaMap": { + "default.default": { + "properties": { + "encrypted_date": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "date", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + } + }, + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encrypted_date": { + "$date": { + "$numberLong": "123" + } + } + } + } + }, + { + "name": "findOne", + "arguments": { + "filter": { + "_id": 1 + } + }, + "result": { + "_id": 1, + "encrypted_date": { + "$date": { + "$numberLong": "123" + } + } + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "insert": "default", + "documents": [ + { + "_id": 1, + "encrypted_date": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAAJ5sN7u6l97+DswfKTqZAijSTSOo5htinGKQKUD7pHNJYlLXGOkB4glrCu7ibu0g3344RHQ5yUp4YxMEa8GD+Snw==", + "subType": "06" + } + } + } + ], + "ordered": true + }, + "command_name": "insert" + } + }, + { + "command_started_event": { + "command": { + "find": "default", + "filter": { + "_id": 1 + } + }, + "command_name": "find" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "encrypted_date": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAAJ5sN7u6l97+DswfKTqZAijSTSOo5htinGKQKUD7pHNJYlLXGOkB4glrCu7ibu0g3344RHQ5yUp4YxMEa8GD+Snw==", + "subType": "06" + } + } + } + ] + } + } + }, + { + "description": "type=minKey", + "clientOptions": { + "autoEncryptOpts": { + "schemaMap": { + "default.default": { + "properties": { + "encrypted_minKey": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "minKey", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + } + }, + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encrypted_minKey": { + "$minKey": 1 + } + } + }, + "result": { + "errorContains": "Cannot encrypt element of type: minKey" + } + } + ] + }, + { + "description": "type=maxKey", + "clientOptions": { + "autoEncryptOpts": { + "schemaMap": { + "default.default": { + "properties": { + "encrypted_maxKey": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "maxKey", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + } + }, + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encrypted_maxKey": { + "$maxKey": 1 + } + } + }, + "result": { + "errorContains": "Cannot encrypt element of type: maxKey" + } + } + ] + }, + { + "description": "type=undefined", + "clientOptions": { + "autoEncryptOpts": { + "schemaMap": { + "default.default": { + "properties": { + "encrypted_undefined": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "undefined", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + } + }, + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encrypted_undefined": { + "$undefined": true + } + } + }, + "result": { + "errorContains": "Cannot encrypt element of type: undefined" + } + } + ] + }, + { + "description": "type=array", + "clientOptions": { + "autoEncryptOpts": { + "schemaMap": { + "default.default": { + "properties": { + "encrypted_array": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "array", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + } + }, + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encrypted_array": [] + } + }, + "result": { + "errorContains": "element of type: array" + } + } + ] + }, + { + "description": "type=bool", + "clientOptions": { + "autoEncryptOpts": { + "schemaMap": { + "default.default": { + "properties": { + "encrypted_bool": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "bool", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + } + }, + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encrypted_bool": true + } + }, + "result": { + "errorContains": "element of type: bool" + } + } + ] + }, + { + "description": "type=null", + "clientOptions": { + "autoEncryptOpts": { + "schemaMap": { + "default.default": { + "properties": { + "encrypted_null": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "null", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + } + }, + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "insertOne", + "arguments": { + "document": { + "_id": 1, + "encrypted_null": true + } + }, + "result": { + "errorContains": "Cannot encrypt element of type: null" + } + } + ] + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/types.yml b/src/test/spec/json/client-side-encryption/legacy/types.yml new file mode 100644 index 000000000..871bc115f --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/types.yml @@ -0,0 +1,501 @@ +# Attempt to round trip some BSON types. +# Note: db pointer is excluded since it is deprecated and numberlong is excluded due to different driver interpretations of { $numberLong: '123' } in relaxed JSON parsing. + +runOn: + - minServerVersion: "4.1.10" +database_name: &database_name "default" +collection_name: &collection_name "default" + +data: [] +json_schema: {} +key_vault_data: [{'status': 1, '_id': {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}, 'masterKey': {'provider': 'aws', 'key': 'arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0', 'region': 'us-east-1'}, 'updateDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyMaterial': {'$binary': {'base64': 'AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO', 'subType': '00'}}, 'creationDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyAltNames': ['altname', 'another_altname']}] + +tests: + - description: "type=objectId" + clientOptions: + autoEncryptOpts: + schemaMap: + "default.default": {'properties': {'encrypted_objectId': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'objectId', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: insertOne + arguments: + document: &doc0 { _id: 1, encrypted_objectId: {"$oid": "AAAAAAAAAAAAAAAAAAAAAAAA"} } + - name: findOne + arguments: + filter: { _id: 1 } + result: *doc0 + expectations: + # Then key is fetched from the key vault. + - command_started_event: + command: + find: datakeys + filter: {"$or": [{"_id": {"$in": [ {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}} ] }}, {"keyAltNames": {"$in": []}}]} + $db: keyvault + readConcern: { level: "majority" } + command_name: find + - command_started_event: + command: + insert: *collection_name + documents: + - &doc0_encrypted { _id: 1, encrypted_objectId: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAAHmkTPqvzfHMWpvS1mEsrjOxVQ2dyihEgIFWD5E0eNEsiMBQsC0GuvjdqYRL5DHLFI1vKuGek7EYYp0Qyii/tHqA==', 'subType': '06'}} } + ordered: true + command_name: insert + - command_started_event: + command: + find: *collection_name + filter: {_id: 1} + command_name: find + outcome: + collection: + # Outcome is checked using a separate MongoClient without auto encryption. + data: + - *doc0_encrypted + - description: "type=symbol" + clientOptions: + autoEncryptOpts: + schemaMap: + "default.default": {'properties': {'encrypted_symbol': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'symbol', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: insertOne + arguments: + document: &doc1 { _id: 1, encrypted_symbol: {"$symbol": "test"} } + - name: findOne + arguments: + filter: { _id: 1 } + result: *doc1 + expectations: + # Then key is fetched from the key vault. + - command_started_event: + command: + find: datakeys + filter: {"$or": [{"_id": {"$in": [ {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}} ] }}, {"keyAltNames": {"$in": []}}]} + $db: keyvault + readConcern: { level: "majority" } + command_name: find + - command_started_event: + command: + insert: *collection_name + documents: + - &doc1_encrypted { _id: 1, encrypted_symbol: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAAOOmvDmWjcuKsSCO7U/7t9HJ8eI73B6wduyMbdkvn7n7V4uTJes/j+BTtneSdyG2JHKHGkevWAJSIU2XoO66BSXw==', 'subType': '06'}} } + ordered: true + command_name: insert + - command_started_event: + command: + find: *collection_name + filter: {_id: 1} + command_name: find + outcome: + collection: + # Outcome is checked using a separate MongoClient without auto encryption. + data: + - *doc1_encrypted + - description: "type=int" + clientOptions: + autoEncryptOpts: + schemaMap: + "default.default": {'properties': {'encrypted_int': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'int', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: insertOne + arguments: + document: &doc2 { _id: 1, encrypted_int: {"$numberInt": "123"} } + - name: findOne + arguments: + filter: { _id: 1 } + result: *doc2 + expectations: + # Then key is fetched from the key vault. + - command_started_event: + command: + find: datakeys + filter: {"$or": [{"_id": {"$in": [ {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}} ] }}, {"keyAltNames": {"$in": []}}]} + $db: keyvault + readConcern: { level: "majority" } + command_name: find + - command_started_event: + command: + insert: *collection_name + documents: + - &doc2_encrypted { _id: 1, encrypted_int: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAAQPNXJVXMEjGZnftMuf2INKufXCtQIRHdw5wTgn6QYt3ejcoAXyiwI4XIUizkpsob494qpt2in4tWeiO7b9zkA8Q==', 'subType': '06'}} } + ordered: true + command_name: insert + - command_started_event: + command: + find: *collection_name + filter: {_id: 1} + command_name: find + outcome: + collection: + # Outcome is checked using a separate MongoClient without auto encryption. + data: + - *doc2_encrypted + - description: "type=double" + clientOptions: + autoEncryptOpts: + schemaMap: + "default.default": {'properties': {'encrypted_double': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'double', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: insertOne + arguments: + document: &doc4 { _id: 1, encrypted_double: {"$numberDouble": "1.23"} } + result: + # DRIVERS-2272: The expected error message changed in mongocryptd 6.0. Before it was: + # "Cannot use deterministic encryption for element of type: double" + # After it is: + # "Cannot encrypt element of type: double" + # Only check for the common suffix. + errorContains: "element of type: double" + - description: "type=decimal" + clientOptions: + autoEncryptOpts: + schemaMap: + "default.default": {'properties': {'encrypted_decimal': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'decimal', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: insertOne + arguments: + document: &doc5 { _id: 1, encrypted_decimal: {"$numberDecimal": "1.23"} } + result: + # DRIVERS-2272: The expected error message changed in mongocryptd 6.0. Before it was: + # "Cannot use deterministic encryption for element of type: decimal" + # After it is: + # "Cannot encrypt element of type: decimal" + # Only check for the common suffix. + errorContains: "element of type: decimal" + - description: "type=binData" + clientOptions: + autoEncryptOpts: + schemaMap: + "default.default": {'properties': {'encrypted_binData': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'binData', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: insertOne + arguments: + document: &doc6 { _id: 1, encrypted_binData: {"$binary": { base64: "AAAA", subType: "00" } } } + - name: findOne + arguments: + filter: { _id: 1 } + result: *doc6 + expectations: + # Then key is fetched from the key vault. + - command_started_event: + command: + find: datakeys + filter: {"$or": [{"_id": {"$in": [ {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}} ] }}, {"keyAltNames": {"$in": []}}]} + $db: keyvault + readConcern: { level: "majority" } + command_name: find + - command_started_event: + command: + insert: *collection_name + documents: + - &doc6_encrypted { _id: 1, encrypted_binData: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAAFB/KHZQHaHHo8fctcl7v6kR+sLkJoTRx2cPSSck9ya+nbGROSeFhdhDRHaCzhV78fDEqnMDSVPNi+ZkbaIh46GQ==', 'subType': '06'}} } + ordered: true + command_name: insert + - command_started_event: + command: + find: *collection_name + filter: {_id: 1} + command_name: find + outcome: + collection: + # Outcome is checked using a separate MongoClient without auto encryption. + data: + - *doc6_encrypted + - description: "type=javascript" + clientOptions: + autoEncryptOpts: + schemaMap: + "default.default": {'properties': {'encrypted_javascript': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'javascript', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: insertOne + arguments: + document: &doc7 { _id: 1, encrypted_javascript: {"$code": "var x = 1;" } } + - name: findOne + arguments: + filter: { _id: 1 } + result: *doc7 + expectations: + # Then key is fetched from the key vault. + - command_started_event: + command: + find: datakeys + filter: {"$or": [{"_id": {"$in": [ {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}} ] }}, {"keyAltNames": {"$in": []}}]} + $db: keyvault + readConcern: { level: "majority" } + command_name: find + - command_started_event: + command: + insert: *collection_name + documents: + - &doc7_encrypted { _id: 1, encrypted_javascript: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAANrvMgJkTKWGMc9wt3E2RBR2Hu5gL9p+vIIdHe9FcOm99t1W480/oX1Gnd87ON3B399DuFaxi/aaIiQSo7gTX6Lw==', 'subType': '06'}} } + ordered: true + command_name: insert + - command_started_event: + command: + find: *collection_name + filter: {_id: 1} + command_name: find + outcome: + collection: + # Outcome is checked using a separate MongoClient without auto encryption. + data: + - *doc7_encrypted + - description: "type=javascriptWithScope" + clientOptions: + autoEncryptOpts: + schemaMap: + "default.default": {'properties': {'encrypted_javascriptWithScope': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'javascriptWithScope', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: insertOne + arguments: + document: &doc8 { _id: 1, encrypted_javascriptWithScope: {"$code": "var x = 1;", "$scope": {} } } + result: + # DRIVERS-2272: The expected error message changed in mongocryptd 6.0. Before it was: + # "Cannot use deterministic encryption for element of type: javascriptWithScope" + # After it is: + # "Cannot encrypt element of type: javascriptWithScope" + # Only check for the common suffix. + errorContains: "element of type: javascriptWithScope" + - description: "type=object" + clientOptions: + autoEncryptOpts: + schemaMap: + "default.default": {'properties': {'encrypted_object': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'object', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: insertOne + arguments: + document: &doc9 { _id: 1, encrypted_object: {} } + result: + # DRIVERS-2272: The expected error message changed in mongocryptd 6.0. Before it was: + # "Cannot use deterministic encryption for element of type: object" + # After it is: + # "Cannot encrypt element of type: object" + # Only check for the common suffix. + errorContains: "element of type: object" + - description: "type=timestamp" + clientOptions: + autoEncryptOpts: + schemaMap: + "default.default": {'properties': {'encrypted_timestamp': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'timestamp', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: insertOne + arguments: + document: &doc10 { _id: 1, encrypted_timestamp: {$timestamp: {t: 123, i: 456}} } + - name: findOne + arguments: + filter: { _id: 1 } + result: *doc10 + expectations: + # Then key is fetched from the key vault. + - command_started_event: + command: + find: datakeys + filter: {"$or": [{"_id": {"$in": [ {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}} ] }}, {"keyAltNames": {"$in": []}}]} + $db: keyvault + readConcern: { level: "majority" } + command_name: find + - command_started_event: + command: + insert: *collection_name + documents: + - &doc10_encrypted { _id: 1, encrypted_timestamp: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAARJHaM4Gq3MpDTdBasBsEolQaOmxJQU1wsZVaSFAOLpEh1QihDglXI95xemePFMKhg+KNpFg7lw1ChCs2Wn/c26Q==', 'subType': '06'}} } + ordered: true + command_name: insert + - command_started_event: + command: + find: *collection_name + filter: {_id: 1} + command_name: find + outcome: + collection: + # Outcome is checked using a separate MongoClient without auto encryption. + data: + - *doc10_encrypted + - description: "type=regex" + clientOptions: + autoEncryptOpts: + schemaMap: + "default.default": {'properties': {'encrypted_regex': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'regex', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: insertOne + arguments: + document: &doc11 { _id: 1, encrypted_regex: {$regularExpression: { pattern: "test", options: ""}} } + - name: findOne + arguments: + filter: { _id: 1 } + result: *doc11 + expectations: + # Then key is fetched from the key vault. + - command_started_event: + command: + find: datakeys + filter: {"$or": [{"_id": {"$in": [ {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}} ] }}, {"keyAltNames": {"$in": []}}]} + $db: keyvault + readConcern: { level: "majority" } + command_name: find + - command_started_event: + command: + insert: *collection_name + documents: + - &doc11_encrypted { _id: 1, encrypted_regex: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAALVnxM4UqGhqf5eXw6nsS08am3YJrTf1EvjKitT8tyyMAbHsICIU3GUjuC7EBofCHbusvgo7pDyaClGostFz44nA==', 'subType': '06'}} } + ordered: true + command_name: insert + - command_started_event: + command: + find: *collection_name + filter: {_id: 1} + command_name: find + outcome: + collection: + # Outcome is checked using a separate MongoClient without auto encryption. + data: + - *doc11_encrypted + - description: "type=date" + clientOptions: + autoEncryptOpts: + schemaMap: + "default.default": {'properties': {'encrypted_date': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'date', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: insertOne + arguments: + document: &doc13 { _id: 1, encrypted_date: {$date: { $numberLong: "123" }} } + - name: findOne + arguments: + filter: { _id: 1 } + result: *doc13 + expectations: + # Then key is fetched from the key vault. + - command_started_event: + command: + find: datakeys + filter: {"$or": [{"_id": {"$in": [ {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}} ] }}, {"keyAltNames": {"$in": []}}]} + $db: keyvault + readConcern: { level: "majority" } + command_name: find + - command_started_event: + command: + insert: *collection_name + documents: + - &doc13_encrypted { _id: 1, encrypted_date: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAAJ5sN7u6l97+DswfKTqZAijSTSOo5htinGKQKUD7pHNJYlLXGOkB4glrCu7ibu0g3344RHQ5yUp4YxMEa8GD+Snw==', 'subType': '06'}} } + ordered: true + command_name: insert + - command_started_event: + command: + find: *collection_name + filter: {_id: 1} + command_name: find + outcome: + collection: + # Outcome is checked using a separate MongoClient without auto encryption. + data: + - *doc13_encrypted + - description: "type=minKey" + clientOptions: + autoEncryptOpts: + schemaMap: + "default.default": {'properties': {'encrypted_minKey': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'minKey', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: insertOne + arguments: + document: &doc14 { _id: 1, encrypted_minKey: {$minKey: 1} } + result: + errorContains: "Cannot encrypt element of type: minKey" + - description: "type=maxKey" + clientOptions: + autoEncryptOpts: + schemaMap: + "default.default": {'properties': {'encrypted_maxKey': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'maxKey', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: insertOne + arguments: + document: &doc15 { _id: 1, encrypted_maxKey: {$maxKey: 1} } + result: + errorContains: "Cannot encrypt element of type: maxKey" + - description: "type=undefined" + clientOptions: + autoEncryptOpts: + schemaMap: + "default.default": {'properties': {'encrypted_undefined': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'undefined', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: insertOne + arguments: + document: &doc16 { _id: 1, encrypted_undefined: {$undefined: true} } + result: + errorContains: "Cannot encrypt element of type: undefined" + - description: "type=array" + clientOptions: + autoEncryptOpts: + schemaMap: + "default.default": {'properties': {'encrypted_array': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'array', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: insertOne + arguments: + document: &doc17 { _id: 1, encrypted_array: [] } + result: + # DRIVERS-2272: The expected error message changed in mongocryptd 6.0. Before it was: + # "Cannot use deterministic encryption for element of type: array" + # After it is: + # "Cannot encrypt element of type: array" + # Only check for the common suffix. + errorContains: "element of type: array" + - description: "type=bool" + clientOptions: + autoEncryptOpts: + schemaMap: + "default.default": {'properties': {'encrypted_bool': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'bool', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: insertOne + arguments: + document: &doc18 { _id: 1, encrypted_bool: true } + result: + # DRIVERS-2272: The expected error message changed in mongocryptd 6.0. Before it was: + # "Cannot use deterministic encryption for element of type: bool" + # After it is: + # "Cannot encrypt element of type: bool" + # Only check for the common suffix. + errorContains: "element of type: bool" + - description: "type=null" + clientOptions: + autoEncryptOpts: + schemaMap: + "default.default": {'properties': {'encrypted_null': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'null', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: insertOne + arguments: + document: &doc19 { _id: 1, encrypted_null: true } + result: + errorContains: "Cannot encrypt element of type: null" \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/unsupportedCommand.json b/src/test/spec/json/client-side-encryption/legacy/unsupportedCommand.json new file mode 100644 index 000000000..318871511 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/unsupportedCommand.json @@ -0,0 +1,152 @@ +{ + "runOn": [ + { + "minServerVersion": "4.1.10" + } + ], + "database_name": "default", + "collection_name": "default", + "data": [ + { + "_id": 1, + "x": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + }, + { + "_id": 2, + "x": 2, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", + "subType": "06" + } + } + } + ], + "json_schema": { + "properties": { + "encrypted_w_altname": { + "encrypt": { + "keyId": "/altname", + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "random": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string_equivalent": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + }, + "key_vault_data": [ + { + "status": 1, + "_id": { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + }, + "masterKey": { + "provider": "aws", + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "region": "us-east-1" + }, + "updateDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyMaterial": { + "$binary": { + "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyAltNames": [ + "altname", + "another_altname" + ] + } + ], + "tests": [ + { + "description": "mapReduce deterministic encryption (unsupported)", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "mapReduce", + "arguments": { + "map": { + "$code": "function inc() { return emit(0, this.x + 1) }" + }, + "reduce": { + "$code": "function sum(key, values) { return values.reduce((acc, x) => acc + x); }" + }, + "out": { + "inline": 1 + } + }, + "result": { + "errorContains": "command not supported for auto encryption: mapreduce" + } + } + ] + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/unsupportedCommand.yml b/src/test/spec/json/client-side-encryption/legacy/unsupportedCommand.yml new file mode 100644 index 000000000..e9edb0f58 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/unsupportedCommand.yml @@ -0,0 +1,25 @@ +runOn: + - minServerVersion: "4.1.10" +database_name: &database_name "default" +collection_name: &collection_name "default" + +data: + - &doc0_encrypted { _id: 1, x: 1, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==', 'subType': '06'}} } + - &doc1_encrypted { _id: 2, x: 2, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==', 'subType': '06'}} } +json_schema: {'properties': {'encrypted_w_altname': {'encrypt': {'keyId': '/altname', 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'random': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string_equivalent': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} +key_vault_data: [{'status': 1, '_id': {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}, 'masterKey': {'provider': 'aws', 'key': 'arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0', 'region': 'us-east-1'}, 'updateDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyMaterial': {'$binary': {'base64': 'AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO', 'subType': '00'}}, 'creationDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyAltNames': ['altname', 'another_altname']}] + +tests: + - description: "mapReduce deterministic encryption (unsupported)" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: mapReduce + arguments: + map: { $code: "function inc() { return emit(0, this.x + 1) }" } + reduce: { $code: "function sum(key, values) { return values.reduce((acc, x) => acc + x); }" } + out: { inline: 1 } + result: + errorContains: "command not supported for auto encryption: mapreduce" \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/updateMany.json b/src/test/spec/json/client-side-encryption/legacy/updateMany.json new file mode 100644 index 000000000..823909044 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/updateMany.json @@ -0,0 +1,307 @@ +{ + "runOn": [ + { + "minServerVersion": "4.1.10" + } + ], + "database_name": "default", + "collection_name": "default", + "data": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + }, + { + "_id": 2, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", + "subType": "06" + } + } + } + ], + "json_schema": { + "properties": { + "encrypted_w_altname": { + "encrypt": { + "keyId": "/altname", + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "random": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string_equivalent": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + }, + "key_vault_data": [ + { + "status": 1, + "_id": { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + }, + "masterKey": { + "provider": "aws", + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "region": "us-east-1" + }, + "updateDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyMaterial": { + "$binary": { + "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyAltNames": [ + "altname", + "another_altname" + ] + } + ], + "tests": [ + { + "description": "updateMany with deterministic encryption", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "updateMany", + "arguments": { + "filter": { + "encrypted_string": { + "$in": [ + "string0", + "string1" + ] + } + }, + "update": { + "$set": { + "encrypted_string": "string2", + "random": "abc" + } + } + }, + "result": { + "matchedCount": 2, + "modifiedCount": 2, + "upsertedCount": 0 + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "default" + } + }, + "command_name": "listCollections" + } + }, + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "update": "default", + "updates": [ + { + "q": { + "encrypted_string": { + "$in": [ + { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + }, + { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", + "subType": "06" + } + } + ] + } + }, + "u": { + "$set": { + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACQ76HWOut3DZtQuV90hp1aaCpZn95vZIaWmn+wrBehcEtcFwyJlBdlyzDzZTWPZCPgiFq72Wvh6Y7VbpU9NAp3A==", + "subType": "06" + } + }, + "random": { + "$$type": "binData" + } + } + }, + "multi": true, + "upsert": false + } + ], + "ordered": true + }, + "command_name": "update" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACQ76HWOut3DZtQuV90hp1aaCpZn95vZIaWmn+wrBehcEtcFwyJlBdlyzDzZTWPZCPgiFq72Wvh6Y7VbpU9NAp3A==", + "subType": "06" + } + }, + "random": { + "$$type": "binData" + } + }, + { + "_id": 2, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACQ76HWOut3DZtQuV90hp1aaCpZn95vZIaWmn+wrBehcEtcFwyJlBdlyzDzZTWPZCPgiFq72Wvh6Y7VbpU9NAp3A==", + "subType": "06" + } + }, + "random": { + "$$type": "binData" + } + } + ] + } + } + }, + { + "description": "updateMany fails when filtering on a random field", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "updateMany", + "arguments": { + "filter": { + "random": "abc" + }, + "update": { + "$set": { + "encrypted_string": "string1" + } + } + }, + "result": { + "errorContains": "Cannot query on fields encrypted with the randomized encryption" + } + } + ] + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/updateMany.yml b/src/test/spec/json/client-side-encryption/legacy/updateMany.yml new file mode 100644 index 000000000..6d8c7e970 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/updateMany.yml @@ -0,0 +1,70 @@ +runOn: + - minServerVersion: "4.1.10" +database_name: &database_name "default" +collection_name: &collection_name "default" + +data: + - &doc0_encrypted { _id: 1, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==', 'subType': '06'}} } + - &doc1_encrypted { _id: 2, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==', 'subType': '06'}} } +json_schema: {'properties': {'encrypted_w_altname': {'encrypt': {'keyId': '/altname', 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'random': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string_equivalent': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} +key_vault_data: [{'status': 1, '_id': {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}, 'masterKey': {'provider': 'aws', 'key': 'arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0', 'region': 'us-east-1'}, 'updateDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyMaterial': {'$binary': {'base64': 'AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO', 'subType': '00'}}, 'creationDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyAltNames': ['altname', 'another_altname']}] + +tests: + - description: "updateMany with deterministic encryption" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: updateMany + arguments: + filter: { encrypted_string: { $in: [ "string0", "string1" ] } } + update: { $set: { encrypted_string: "string2", random: "abc" } } + result: + matchedCount: 2 + modifiedCount: 2 + upsertedCount: 0 + expectations: + # Auto encryption will request the collection info. + - command_started_event: + command: + listCollections: 1 + filter: + name: *collection_name + command_name: listCollections + # Then key is fetched from the key vault. + - command_started_event: + command: + find: datakeys + filter: {"$or": [{"_id": {"$in": [ {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}} ] }}, {"keyAltNames": {"$in": []}}]} + $db: keyvault + readConcern: { level: "majority" } + command_name: find + - command_started_event: + command: + update: *collection_name + updates: + - q: { encrypted_string: { $in: [ {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==', 'subType': '06'}}, {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==', 'subType': '06'}} ] } } + u: { $set: { encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACQ76HWOut3DZtQuV90hp1aaCpZn95vZIaWmn+wrBehcEtcFwyJlBdlyzDzZTWPZCPgiFq72Wvh6Y7VbpU9NAp3A==', 'subType': '06'}}, random: { $$type: "binData" } } } + multi: true + upsert: false + ordered: true + command_name: update + outcome: + collection: + # Outcome is checked using a separate MongoClient without auto encryption. + data: + - { _id: 1, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACQ76HWOut3DZtQuV90hp1aaCpZn95vZIaWmn+wrBehcEtcFwyJlBdlyzDzZTWPZCPgiFq72Wvh6Y7VbpU9NAp3A==', 'subType': '06'}}, random: { $$type: "binData" } } + - { _id: 2, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACQ76HWOut3DZtQuV90hp1aaCpZn95vZIaWmn+wrBehcEtcFwyJlBdlyzDzZTWPZCPgiFq72Wvh6Y7VbpU9NAp3A==', 'subType': '06'}}, random: { $$type: "binData" } } + - description: "updateMany fails when filtering on a random field" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: updateMany + arguments: + filter: { random: "abc" } + update: { $set: { encrypted_string: "string1" } } + result: + errorContains: "Cannot query on fields encrypted with the randomized encryption" \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/updateOne.json b/src/test/spec/json/client-side-encryption/legacy/updateOne.json new file mode 100644 index 000000000..23bada964 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/updateOne.json @@ -0,0 +1,465 @@ +{ + "runOn": [ + { + "minServerVersion": "4.1.10" + } + ], + "database_name": "default", + "collection_name": "default", + "data": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + } + ], + "json_schema": { + "properties": { + "encrypted_w_altname": { + "encrypt": { + "keyId": "/altname", + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "random": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string_equivalent": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + }, + "key_vault_data": [ + { + "status": 1, + "_id": { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + }, + "masterKey": { + "provider": "aws", + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "region": "us-east-1" + }, + "updateDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyMaterial": { + "$binary": { + "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1552949630483" + } + }, + "keyAltNames": [ + "altname", + "another_altname" + ] + } + ], + "tests": [ + { + "description": "updateOne with deterministic encryption", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "updateOne", + "arguments": { + "filter": { + "encrypted_string": "string0" + }, + "update": { + "$set": { + "encrypted_string": "string1", + "random": "abc" + } + } + }, + "result": { + "matchedCount": 1, + "modifiedCount": 1, + "upsertedCount": 0 + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "default" + } + }, + "command_name": "listCollections" + } + }, + { + "command_started_event": { + "command": { + "find": "datakeys", + "filter": { + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] + }, + "$db": "keyvault", + "readConcern": { + "level": "majority" + } + }, + "command_name": "find" + } + }, + { + "command_started_event": { + "command": { + "update": "default", + "updates": [ + { + "q": { + "encrypted_string": { + "$eq": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + } + }, + "u": { + "$set": { + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", + "subType": "06" + } + }, + "random": { + "$$type": "binData" + } + } + } + } + ], + "ordered": true + }, + "command_name": "update" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "encrypted_string": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==", + "subType": "06" + } + }, + "random": { + "$$type": "binData" + } + } + ] + } + } + }, + { + "description": "updateOne fails when filtering on a random field", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "updateOne", + "arguments": { + "filter": { + "random": "abc" + }, + "update": { + "$set": { + "encrypted_string": "string1" + } + } + }, + "result": { + "errorContains": "Cannot query on fields encrypted with the randomized encryption" + } + } + ] + }, + { + "description": "$unset works with an encrypted field", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "updateOne", + "arguments": { + "filter": {}, + "update": { + "$unset": { + "encrypted_string": "" + } + } + }, + "result": { + "matchedCount": 1, + "modifiedCount": 1, + "upsertedCount": 0 + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "default" + } + }, + "command_name": "listCollections" + } + }, + { + "command_started_event": { + "command": { + "update": "default", + "updates": [ + { + "q": {}, + "u": { + "$unset": { + "encrypted_string": "" + } + } + } + ], + "ordered": true + }, + "command_name": "update" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1 + } + ] + } + } + }, + { + "description": "$rename works if target value has same encryption options", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "updateOne", + "arguments": { + "filter": {}, + "update": { + "$rename": { + "encrypted_string": "encrypted_string_equivalent" + } + } + }, + "result": { + "matchedCount": 1, + "modifiedCount": 1, + "upsertedCount": 0 + } + } + ], + "expectations": [ + { + "command_started_event": { + "command": { + "listCollections": 1, + "filter": { + "name": "default" + } + }, + "command_name": "listCollections" + } + }, + { + "command_started_event": { + "command": { + "update": "default", + "updates": [ + { + "q": {}, + "u": { + "$rename": { + "encrypted_string": "encrypted_string_equivalent" + } + } + } + ], + "ordered": true + }, + "command_name": "update" + } + } + ], + "outcome": { + "collection": { + "data": [ + { + "_id": 1, + "encrypted_string_equivalent": { + "$binary": { + "base64": "AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==", + "subType": "06" + } + } + } + ] + } + } + }, + { + "description": "$rename fails if target value has different encryption options", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "updateOne", + "arguments": { + "filter": {}, + "update": { + "$rename": { + "encrypted_string": "random" + } + } + }, + "result": { + "errorContains": "$rename between two encrypted fields must have the same metadata or both be unencrypted" + } + } + ] + }, + { + "description": "an invalid update (no $ operators) is validated and errors", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "aws": {} + } + } + }, + "operations": [ + { + "name": "updateOne", + "arguments": { + "filter": {}, + "update": { + "encrypted_string": "random" + } + }, + "result": { + "errorContains": "" + } + } + ] + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/updateOne.yml b/src/test/spec/json/client-side-encryption/legacy/updateOne.yml new file mode 100644 index 000000000..aef3716fa --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/updateOne.yml @@ -0,0 +1,160 @@ +runOn: + - minServerVersion: "4.1.10" +database_name: &database_name "default" +collection_name: &collection_name "default" + +data: + - &doc0_encrypted { _id: 1, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==', 'subType': '06'}} } +json_schema: {'properties': {'encrypted_w_altname': {'encrypt': {'keyId': '/altname', 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'random': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string_equivalent': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} +key_vault_data: [{'status': 1, '_id': {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}, 'masterKey': {'provider': 'aws', 'key': 'arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0', 'region': 'us-east-1'}, 'updateDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyMaterial': {'$binary': {'base64': 'AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gEqnsxXlR51T5EbEVezUqqKAAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDHa4jo6yp0Z18KgbUgIBEIB74sKxWtV8/YHje5lv5THTl0HIbhSwM6EqRlmBiFFatmEWaeMk4tO4xBX65eq670I5TWPSLMzpp8ncGHMmvHqRajNBnmFtbYxN3E3/WjxmdbOOe+OXpnGJPcGsftc7cB2shRfA4lICPnE26+oVNXT6p0Lo20nY5XC7jyCO', 'subType': '00'}}, 'creationDate': {'$date': {'$numberLong': '1552949630483'}}, 'keyAltNames': ['altname', 'another_altname']}] + +tests: + - description: "updateOne with deterministic encryption" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: updateOne + arguments: + filter: { encrypted_string: "string0" } + update: { $set: { encrypted_string: "string1", random: "abc" } } + result: + matchedCount: 1 + modifiedCount: 1 + upsertedCount: 0 + expectations: + # Auto encryption will request the collection info. + - command_started_event: + command: + listCollections: 1 + filter: + name: *collection_name + command_name: listCollections + # Then key is fetched from the key vault. + - command_started_event: + command: + find: datakeys + filter: {"$or": [{"_id": {"$in": [ {'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}} ] }}, {"keyAltNames": {"$in": []}}]} + $db: keyvault + readConcern: { level: "majority" } + command_name: find + - command_started_event: + command: + update: *collection_name + updates: + - q: { encrypted_string: { $eq: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==', 'subType': '06'}} } } + u: { $set: {encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==', 'subType': '06'}}, random: { $$type: "binData" } } } + ordered: true + command_name: update + outcome: + collection: + # Outcome is checked using a separate MongoClient without auto encryption. + data: + - { _id: 1, encrypted_string: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACDdw4KFz3ZLquhsbt7RmDjD0N67n0uSXx7IGnQNCLeIKvot6s/ouI21Eo84IOtb6lhwUNPlSEBNY0/hbszWAKJg==', 'subType': '06'}}, random: { $$type: "binData"} } + - description: "updateOne fails when filtering on a random field" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: updateOne + arguments: + filter: { random: "abc" } + update: { $set: { encrypted_string: "string1" } } + result: + errorContains: "Cannot query on fields encrypted with the randomized encryption" + - description: "$unset works with an encrypted field" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: updateOne + arguments: + filter: { } + update: { $unset: { encrypted_string: "" } } + result: + matchedCount: 1 + modifiedCount: 1 + upsertedCount: 0 + expectations: + # Auto encryption will request the collection info. + - command_started_event: + command: + listCollections: 1 + filter: + name: *collection_name + command_name: listCollections + - command_started_event: + command: + update: *collection_name + updates: + - q: { } + u: { $unset: {encrypted_string: "" } } + ordered: true + command_name: update + outcome: + collection: + # Outcome is checked using a separate MongoClient without auto encryption. + data: + - { _id: 1 } + - description: "$rename works if target value has same encryption options" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: updateOne + arguments: + filter: { } + update: { $rename: { encrypted_string: "encrypted_string_equivalent" } } + result: + matchedCount: 1 + modifiedCount: 1 + upsertedCount: 0 + expectations: + # Auto encryption will request the collection info. + - command_started_event: + command: + listCollections: 1 + filter: + name: *collection_name + command_name: listCollections + - command_started_event: + command: + update: *collection_name + updates: + - q: { } + u: { $rename: {encrypted_string: "encrypted_string_equivalent" } } + ordered: true + command_name: update + outcome: + collection: + # Outcome is checked using a separate MongoClient without auto encryption. + data: + - { _id: 1, encrypted_string_equivalent: {'$binary': {'base64': 'AQAAAAAAAAAAAAAAAAAAAAACwj+3zkv2VM+aTfk60RqhXq6a/77WlLwu/BxXFkL7EppGsju/m8f0x5kBDD3EZTtGALGXlym5jnpZAoSIkswHoA==', 'subType': '06'}} } + - description: "$rename fails if target value has different encryption options" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: updateOne + arguments: + filter: { } + update: { $rename: { encrypted_string: "random" } } + result: + errorContains: "$rename between two encrypted fields must have the same metadata or both be unencrypted" + - description: "an invalid update (no $ operators) is validated and errors" + clientOptions: + autoEncryptOpts: + kmsProviders: + aws: {} # Credentials filled in from environment. + operations: + - name: updateOne + arguments: + filter: { } + update: { encrypted_string: "random" } + result: + errorContains: "" # Note, drivers differ in the error message. Just ensure an error is thrown. \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/legacy/validatorAndPartialFieldExpression.json b/src/test/spec/json/client-side-encryption/legacy/validatorAndPartialFieldExpression.json new file mode 100644 index 000000000..e07137ce1 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/validatorAndPartialFieldExpression.json @@ -0,0 +1,642 @@ +{ + "runOn": [ + { + "minServerVersion": "6.0.0" + } + ], + "database_name": "default", + "collection_name": "default", + "data": [], + "tests": [ + { + "description": "create with a validator on an unencrypted field is OK", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "local": { + "key": { + "$binary": { + "base64": "Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk", + "subType": "00" + } + } + } + }, + "schemaMap": { + "default.encryptedCollection": { + "properties": { + "encrypted_w_altname": { + "encrypt": { + "keyId": "/altname", + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "random": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string_equivalent": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + } + } + } + }, + "operations": [ + { + "name": "dropCollection", + "object": "database", + "arguments": { + "collection": "encryptedCollection" + } + }, + { + "name": "createCollection", + "object": "database", + "arguments": { + "collection": "encryptedCollection", + "validator": { + "unencrypted_string": "foo" + } + } + }, + { + "name": "assertCollectionExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection" + } + } + ] + }, + { + "description": "create with a validator on an encrypted field is an error", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "local": { + "key": { + "$binary": { + "base64": "Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk", + "subType": "00" + } + } + } + }, + "schemaMap": { + "default.encryptedCollection": { + "properties": { + "encrypted_w_altname": { + "encrypt": { + "keyId": "/altname", + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "random": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string_equivalent": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + } + } + } + }, + "operations": [ + { + "name": "dropCollection", + "object": "database", + "arguments": { + "collection": "encryptedCollection" + } + }, + { + "name": "createCollection", + "object": "database", + "arguments": { + "collection": "encryptedCollection", + "validator": { + "encrypted_string": "foo" + } + }, + "result": { + "errorContains": "Comparison to encrypted fields not supported" + } + } + ] + }, + { + "description": "collMod with a validator on an unencrypted field is OK", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "local": { + "key": { + "$binary": { + "base64": "Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk", + "subType": "00" + } + } + } + }, + "schemaMap": { + "default.encryptedCollection": { + "properties": { + "encrypted_w_altname": { + "encrypt": { + "keyId": "/altname", + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "random": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string_equivalent": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + } + } + } + }, + "operations": [ + { + "name": "dropCollection", + "object": "database", + "arguments": { + "collection": "encryptedCollection" + } + }, + { + "name": "createCollection", + "object": "database", + "arguments": { + "collection": "encryptedCollection" + } + }, + { + "name": "runCommand", + "object": "database", + "arguments": { + "command": { + "collMod": "encryptedCollection", + "validator": { + "unencrypted_string": "foo" + } + } + } + } + ] + }, + { + "description": "collMod with a validator on an encrypted field is an error", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "local": { + "key": { + "$binary": { + "base64": "Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk", + "subType": "00" + } + } + } + }, + "schemaMap": { + "default.encryptedCollection": { + "properties": { + "encrypted_w_altname": { + "encrypt": { + "keyId": "/altname", + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "random": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string_equivalent": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + } + } + } + }, + "operations": [ + { + "name": "dropCollection", + "object": "database", + "arguments": { + "collection": "encryptedCollection" + } + }, + { + "name": "createCollection", + "object": "database", + "arguments": { + "collection": "encryptedCollection" + } + }, + { + "name": "runCommand", + "object": "database", + "arguments": { + "command": { + "collMod": "encryptedCollection", + "validator": { + "encrypted_string": "foo" + } + } + }, + "result": { + "errorContains": "Comparison to encrypted fields not supported" + } + } + ] + }, + { + "description": "createIndexes with a partialFilterExpression on an unencrypted field is OK", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "local": { + "key": { + "$binary": { + "base64": "Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk", + "subType": "00" + } + } + } + }, + "schemaMap": { + "default.encryptedCollection": { + "properties": { + "encrypted_w_altname": { + "encrypt": { + "keyId": "/altname", + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "random": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string_equivalent": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + } + } + } + }, + "operations": [ + { + "name": "dropCollection", + "object": "database", + "arguments": { + "collection": "encryptedCollection" + } + }, + { + "name": "createCollection", + "object": "database", + "arguments": { + "collection": "encryptedCollection" + } + }, + { + "name": "runCommand", + "object": "database", + "arguments": { + "command": { + "createIndexes": "encryptedCollection", + "indexes": [ + { + "name": "name", + "key": { + "name": 1 + }, + "partialFilterExpression": { + "unencrypted_string": "foo" + } + } + ] + } + } + }, + { + "name": "assertIndexExists", + "object": "testRunner", + "arguments": { + "database": "default", + "collection": "encryptedCollection", + "index": "name" + } + } + ] + }, + { + "description": "createIndexes with a partialFilterExpression on an encrypted field is an error", + "clientOptions": { + "autoEncryptOpts": { + "kmsProviders": { + "local": { + "key": { + "$binary": { + "base64": "Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk", + "subType": "00" + } + } + } + }, + "schemaMap": { + "default.encryptedCollection": { + "properties": { + "encrypted_w_altname": { + "encrypt": { + "keyId": "/altname", + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + }, + "random": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Random" + } + }, + "encrypted_string_equivalent": { + "encrypt": { + "keyId": [ + { + "$binary": { + "base64": "AAAAAAAAAAAAAAAAAAAAAA==", + "subType": "04" + } + } + ], + "bsonType": "string", + "algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic" + } + } + }, + "bsonType": "object" + } + } + } + }, + "operations": [ + { + "name": "dropCollection", + "object": "database", + "arguments": { + "collection": "encryptedCollection" + } + }, + { + "name": "createCollection", + "object": "database", + "arguments": { + "collection": "encryptedCollection" + } + }, + { + "name": "runCommand", + "object": "database", + "arguments": { + "command": { + "createIndexes": "encryptedCollection", + "indexes": [ + { + "name": "name", + "key": { + "name": 1 + }, + "partialFilterExpression": { + "encrypted_string": "foo" + } + } + ] + } + }, + "result": { + "errorContains": "Comparison to encrypted fields not supported" + } + } + ] + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/legacy/validatorAndPartialFieldExpression.yml b/src/test/spec/json/client-side-encryption/legacy/validatorAndPartialFieldExpression.yml new file mode 100644 index 000000000..d2b7ffaee --- /dev/null +++ b/src/test/spec/json/client-side-encryption/legacy/validatorAndPartialFieldExpression.yml @@ -0,0 +1,166 @@ +# This test requires libmongocrypt 1.5.0-alpha2. +runOn: + # Require server version 6.0.0 to get behavior added in SERVER-64911. + - minServerVersion: "6.0.0" + +database_name: &database_name "default" +collection_name: &collection_name "default" +data: [] +tests: + - description: "create with a validator on an unencrypted field is OK" + clientOptions: + autoEncryptOpts: + kmsProviders: + local: {'key': {'$binary': {'base64': 'Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk', 'subType': '00'}}} + schemaMap: + "default.encryptedCollection": {'properties': {'encrypted_w_altname': {'encrypt': {'keyId': '/altname', 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'random': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string_equivalent': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} + operations: + # Drop to remove a collection that may exist from previous test runs. + - name: dropCollection + object: database + arguments: + collection: "encryptedCollection" + - name: createCollection + object: database + arguments: + collection: "encryptedCollection" + validator: + unencrypted_string: "foo" + - name: assertCollectionExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection" + - description: "create with a validator on an encrypted field is an error" + clientOptions: + autoEncryptOpts: + kmsProviders: + local: {'key': {'$binary': {'base64': 'Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk', 'subType': '00'}}} + schemaMap: + "default.encryptedCollection": {'properties': {'encrypted_w_altname': {'encrypt': {'keyId': '/altname', 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'random': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string_equivalent': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} + operations: + # Drop to remove a collection that may exist from previous test runs. + - name: dropCollection + object: database + arguments: + collection: "encryptedCollection" + - name: createCollection + object: database + arguments: + collection: "encryptedCollection" + validator: + encrypted_string: "foo" + result: + errorContains: "Comparison to encrypted fields not supported" + - description: "collMod with a validator on an unencrypted field is OK" + clientOptions: + autoEncryptOpts: + kmsProviders: + local: {'key': {'$binary': {'base64': 'Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk', 'subType': '00'}}} + schemaMap: + "default.encryptedCollection": {'properties': {'encrypted_w_altname': {'encrypt': {'keyId': '/altname', 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'random': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string_equivalent': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} + operations: + # Drop to remove a collection that may exist from previous test runs. + - name: dropCollection + object: database + arguments: + collection: "encryptedCollection" + - name: createCollection + object: database + arguments: + collection: "encryptedCollection" + - name: runCommand + object: database + arguments: + command: + collMod: "encryptedCollection" + validator: + unencrypted_string: "foo" + - description: "collMod with a validator on an encrypted field is an error" + clientOptions: + autoEncryptOpts: + kmsProviders: + local: {'key': {'$binary': {'base64': 'Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk', 'subType': '00'}}} + schemaMap: + "default.encryptedCollection": {'properties': {'encrypted_w_altname': {'encrypt': {'keyId': '/altname', 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'random': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string_equivalent': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} + operations: + # Drop to remove a collection that may exist from previous test runs. + - name: dropCollection + object: database + arguments: + collection: "encryptedCollection" + - name: createCollection + object: database + arguments: + collection: "encryptedCollection" + - name: runCommand + object: database + arguments: + command: + collMod: "encryptedCollection" + validator: + encrypted_string: "foo" + result: + errorContains: "Comparison to encrypted fields not supported" + - description: "createIndexes with a partialFilterExpression on an unencrypted field is OK" + clientOptions: + autoEncryptOpts: + kmsProviders: + local: {'key': {'$binary': {'base64': 'Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk', 'subType': '00'}}} + schemaMap: + "default.encryptedCollection": {'properties': {'encrypted_w_altname': {'encrypt': {'keyId': '/altname', 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'random': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string_equivalent': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} + operations: + # Drop to remove a collection that may exist from previous test runs. + - name: dropCollection + object: database + arguments: + collection: "encryptedCollection" + - name: createCollection + object: database + arguments: + collection: "encryptedCollection" + - name: runCommand + object: database + arguments: + command: + createIndexes: "encryptedCollection" + indexes: + - name: "name" + key: { name: 1 } + partialFilterExpression: + unencrypted_string: "foo" + - name: assertIndexExists + object: testRunner + arguments: + database: *database_name + collection: "encryptedCollection" + index: name + - description: "createIndexes with a partialFilterExpression on an encrypted field is an error" + clientOptions: + autoEncryptOpts: + kmsProviders: + local: {'key': {'$binary': {'base64': 'Mng0NCt4ZHVUYUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk', 'subType': '00'}}} + schemaMap: + "default.encryptedCollection": {'properties': {'encrypted_w_altname': {'encrypt': {'keyId': '/altname', 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}, 'random': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Random'}}, 'encrypted_string_equivalent': {'encrypt': {'keyId': [{'$binary': {'base64': 'AAAAAAAAAAAAAAAAAAAAAA==', 'subType': '04'}}], 'bsonType': 'string', 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'}}}, 'bsonType': 'object'} + operations: + # Drop to remove a collection that may exist from previous test runs. + - name: dropCollection + object: database + arguments: + collection: "encryptedCollection" + - name: createCollection + object: database + arguments: + collection: "encryptedCollection" + - name: runCommand + object: database + arguments: + command: + createIndexes: "encryptedCollection" + indexes: + - name: "name" + key: { name: 1 } + partialFilterExpression: + encrypted_string: "foo" + result: + errorContains: "Comparison to encrypted fields not supported" \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/testdata/encryptedFields.json b/src/test/spec/json/client-side-encryption/testdata/encryptedFields.json deleted file mode 100644 index a117a61a1..000000000 --- a/src/test/spec/json/client-side-encryption/testdata/encryptedFields.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "escCollection": "enxcol_.default.esc", - "eccCollection": "enxcol_.default.ecc", - "ecocCollection": "enxcol_.default.ecoc", - "fields": [ - { - "keyId": { - "$binary": { - "base64": "EjRWeBI0mHYSNBI0VniQEg==", - "subType": "04" - } - }, - "path": "encryptedIndexed", - "bsonType": "string", - "queries": { - "queryType": "equality", - "contention": { - "$numberLong": "0" - } - } - }, - { - "keyId": { - "$binary": { - "base64": "q83vqxI0mHYSNBI0VniQEg==", - "subType": "04" - } - }, - "path": "encryptedUnindexed", - "bsonType": "string" - } - ] - } \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/testdata/key1-document.json b/src/test/spec/json/client-side-encryption/testdata/key1-document.json deleted file mode 100644 index 2e0308bc3..000000000 --- a/src/test/spec/json/client-side-encryption/testdata/key1-document.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "_id": { - "$binary": { - "base64": "EjRWeBI0mHYSNBI0VniQEg==", - "subType": "04" - } - }, - "keyMaterial": { - "$binary": { - "base64": "sHe0kz57YW7v8g9VP9sf/+K1ex4JqKc5rf/URX3n3p8XdZ6+15uXPaSayC6adWbNxkFskuMCOifDoTT+rkqMtFkDclOy884RuGGtUysq3X7zkAWYTKi8QAfKkajvVbZl2y23UqgVasdQu3OVBQCrH/xY00nNAs/52e958nVjBuzQkSb1T8pKJAyjZsHJ60+FtnfafDZSTAIBJYn7UWBCwQ==", - "subType": "00" - } - }, - "creationDate": { - "$date": { - "$numberLong": "1648914851981" - } - }, - "updateDate": { - "$date": { - "$numberLong": "1648914851981" - } - }, - "status": { - "$numberInt": "0" - }, - "masterKey": { - "provider": "local" - } -} \ No newline at end of file diff --git a/src/test/spec/json/client-side-encryption/unified/addKeyAltName.json b/src/test/spec/json/client-side-encryption/unified/addKeyAltName.json new file mode 100644 index 000000000..f70bc572a --- /dev/null +++ b/src/test/spec/json/client-side-encryption/unified/addKeyAltName.json @@ -0,0 +1,609 @@ +{ + "description": "addKeyAltName", + "schemaVersion": "1.8", + "runOnRequirements": [ + { + "csfle": true + } + ], + "createEntities": [ + { + "client": { + "id": "client0", + "observeEvents": [ + "commandStartedEvent" + ] + } + }, + { + "clientEncryption": { + "id": "clientEncryption0", + "clientEncryptionOpts": { + "keyVaultClient": "client0", + "keyVaultNamespace": "keyvault.datakeys", + "kmsProviders": { + "local": { + "key": { + "$$placeholder": 1 + } + } + } + } + } + }, + { + "database": { + "id": "database0", + "client": "client0", + "databaseName": "keyvault" + } + }, + { + "collection": { + "id": "collection0", + "database": "database0", + "collectionName": "datakeys" + } + } + ], + "initialData": [ + { + "databaseName": "keyvault", + "collectionName": "datakeys", + "documents": [ + { + "_id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + }, + "keyMaterial": { + "$binary": { + "base64": "ABKBldDEoDW323yejOnIRk6YQmlD9d3eQthd16scKL75nz2LjNL9fgPDZWrFFOlqlhMCFaSrNJfGrFUjYk5JFDO7soG5Syb50k1niJoKg4ilsj0L4mpimFUtTpOr2nzZOeQtvAksEXc7gsFgq8gV7t/U3lsaXPY7I0t42DfSE8EGlPdxRjFdHnxh+OR8h7U9b8Qs5K5UuhgyeyxaBZ1Hgw==", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "status": 1, + "masterKey": { + "provider": "local" + } + } + ] + } + ], + "tests": [ + { + "description": "add keyAltName to non-existent data key", + "operations": [ + { + "name": "addKeyAltName", + "object": "clientEncryption0", + "arguments": { + "id": { + "$binary": { + "base64": "AAAjYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + }, + "keyAltName": "new_key_alt_name" + }, + "expectResult": { + "$$unsetOrMatches": null + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "findAndModify": "datakeys", + "query": { + "_id": { + "$binary": { + "base64": "AAAjYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + } + }, + "update": { + "$addToSet": { + "keyAltNames": "new_key_alt_name" + } + }, + "writeConcern": { + "w": "majority" + } + } + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "datakeys", + "databaseName": "keyvault", + "documents": [ + { + "_id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + }, + "keyMaterial": { + "$binary": { + "base64": "ABKBldDEoDW323yejOnIRk6YQmlD9d3eQthd16scKL75nz2LjNL9fgPDZWrFFOlqlhMCFaSrNJfGrFUjYk5JFDO7soG5Syb50k1niJoKg4ilsj0L4mpimFUtTpOr2nzZOeQtvAksEXc7gsFgq8gV7t/U3lsaXPY7I0t42DfSE8EGlPdxRjFdHnxh+OR8h7U9b8Qs5K5UuhgyeyxaBZ1Hgw==", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "status": 1, + "masterKey": { + "provider": "local" + } + } + ] + } + ] + }, + { + "description": "add new keyAltName to data key with no keyAltNames", + "operations": [ + { + "name": "addKeyAltName", + "object": "clientEncryption0", + "arguments": { + "id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + }, + "keyAltName": "local_key" + }, + "expectResult": { + "_id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + }, + "keyMaterial": { + "$binary": { + "base64": "ABKBldDEoDW323yejOnIRk6YQmlD9d3eQthd16scKL75nz2LjNL9fgPDZWrFFOlqlhMCFaSrNJfGrFUjYk5JFDO7soG5Syb50k1niJoKg4ilsj0L4mpimFUtTpOr2nzZOeQtvAksEXc7gsFgq8gV7t/U3lsaXPY7I0t42DfSE8EGlPdxRjFdHnxh+OR8h7U9b8Qs5K5UuhgyeyxaBZ1Hgw==", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "status": 1, + "masterKey": { + "provider": "local" + } + } + }, + { + "name": "find", + "object": "collection0", + "arguments": { + "filter": {}, + "projection": { + "_id": 0, + "keyAltNames": 1 + } + }, + "expectResult": [ + { + "keyAltNames": [ + "local_key" + ] + } + ] + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "findAndModify": "datakeys", + "query": { + "_id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + } + }, + "update": { + "$addToSet": { + "keyAltNames": "local_key" + } + }, + "writeConcern": { + "w": "majority" + } + } + } + }, + { + "commandStartedEvent": { + "commandName": "find" + } + } + ] + } + ] + }, + { + "description": "add existing keyAltName to existing data key", + "operations": [ + { + "name": "addKeyAltName", + "object": "clientEncryption0", + "arguments": { + "id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + }, + "keyAltName": "local_key" + }, + "expectResult": { + "_id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + }, + "keyMaterial": { + "$binary": { + "base64": "ABKBldDEoDW323yejOnIRk6YQmlD9d3eQthd16scKL75nz2LjNL9fgPDZWrFFOlqlhMCFaSrNJfGrFUjYk5JFDO7soG5Syb50k1niJoKg4ilsj0L4mpimFUtTpOr2nzZOeQtvAksEXc7gsFgq8gV7t/U3lsaXPY7I0t42DfSE8EGlPdxRjFdHnxh+OR8h7U9b8Qs5K5UuhgyeyxaBZ1Hgw==", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "status": 1, + "masterKey": { + "provider": "local" + } + } + }, + { + "name": "addKeyAltName", + "object": "clientEncryption0", + "arguments": { + "id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + }, + "keyAltName": "local_key" + }, + "expectResult": { + "_id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + }, + "keyAltNames": [ + "local_key" + ], + "keyMaterial": { + "$$type": "binData" + }, + "creationDate": { + "$$type": "date" + }, + "updateDate": { + "$$type": "date" + }, + "status": 1, + "masterKey": { + "provider": "local" + } + } + }, + { + "name": "find", + "object": "collection0", + "arguments": { + "filter": {}, + "projection": { + "_id": 0, + "keyAltNames": 1 + } + }, + "expectResult": [ + { + "keyAltNames": [ + "local_key" + ] + } + ] + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "findAndModify": "datakeys", + "query": { + "_id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + } + }, + "update": { + "$addToSet": { + "keyAltNames": "local_key" + } + }, + "writeConcern": { + "w": "majority" + } + } + } + }, + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "findAndModify": "datakeys", + "query": { + "_id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + } + }, + "update": { + "$addToSet": { + "keyAltNames": "local_key" + } + }, + "writeConcern": { + "w": "majority" + } + } + } + }, + { + "commandStartedEvent": { + "commandName": "find" + } + } + ] + } + ] + }, + { + "description": "add new keyAltName to data key with keyAltNames", + "operations": [ + { + "name": "addKeyAltName", + "object": "clientEncryption0", + "arguments": { + "id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + }, + "keyAltName": "local_key" + }, + "expectResult": { + "_id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + }, + "keyMaterial": { + "$binary": { + "base64": "ABKBldDEoDW323yejOnIRk6YQmlD9d3eQthd16scKL75nz2LjNL9fgPDZWrFFOlqlhMCFaSrNJfGrFUjYk5JFDO7soG5Syb50k1niJoKg4ilsj0L4mpimFUtTpOr2nzZOeQtvAksEXc7gsFgq8gV7t/U3lsaXPY7I0t42DfSE8EGlPdxRjFdHnxh+OR8h7U9b8Qs5K5UuhgyeyxaBZ1Hgw==", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "status": 1, + "masterKey": { + "provider": "local" + } + } + }, + { + "name": "addKeyAltName", + "object": "clientEncryption0", + "arguments": { + "id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + }, + "keyAltName": "another_name" + }, + "expectResult": { + "_id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + }, + "keyAltNames": [ + "local_key" + ], + "keyMaterial": { + "$$type": "binData" + }, + "creationDate": { + "$$type": "date" + }, + "updateDate": { + "$$type": "date" + }, + "status": 1, + "masterKey": { + "provider": "local" + } + } + }, + { + "name": "aggregate", + "object": "collection0", + "arguments": { + "pipeline": [ + { + "$project": { + "_id": 0, + "keyAltNames": "$keyAltNames" + } + }, + { + "$unwind": "$keyAltNames" + }, + { + "$sort": { + "keyAltNames": 1 + } + } + ] + }, + "expectResult": [ + { + "keyAltNames": "another_name" + }, + { + "keyAltNames": "local_key" + } + ] + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "findAndModify": "datakeys", + "query": { + "_id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + } + }, + "update": { + "$addToSet": { + "keyAltNames": "local_key" + } + }, + "writeConcern": { + "w": "majority" + } + } + } + }, + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "findAndModify": "datakeys", + "query": { + "_id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + } + }, + "update": { + "$addToSet": { + "keyAltNames": "another_name" + } + }, + "writeConcern": { + "w": "majority" + } + } + } + }, + { + "commandStartedEvent": { + "commandName": "aggregate" + } + } + ] + } + ] + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/unified/addKeyAltName.yml b/src/test/spec/json/client-side-encryption/unified/addKeyAltName.yml new file mode 100644 index 000000000..7d52fd1a3 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/unified/addKeyAltName.yml @@ -0,0 +1,194 @@ +description: addKeyAltName + +schemaVersion: "1.8" + +runOnRequirements: + - csfle: true + +createEntities: + - client: + id: &client0 client0 + observeEvents: + - commandStartedEvent + - clientEncryption: + id: &clientEncryption0 clientEncryption0 + clientEncryptionOpts: + keyVaultClient: *client0 + keyVaultNamespace: keyvault.datakeys + kmsProviders: + local: { key: { $$placeholder: 1 } } + - database: + id: &database0 database0 + client: *client0 + databaseName: &database0Name keyvault + - collection: + id: &collection0 collection0 + database: *database0 + collectionName: &collection0Name datakeys + +initialData: + - databaseName: *database0Name + collectionName: *collection0Name + documents: + - &local_key_doc + _id: &local_key_id { $binary: { base64: bG9jYWxrZXlsb2NhbGtleQ==, subType: "04" } } + keyMaterial: { $binary: { base64: ABKBldDEoDW323yejOnIRk6YQmlD9d3eQthd16scKL75nz2LjNL9fgPDZWrFFOlqlhMCFaSrNJfGrFUjYk5JFDO7soG5Syb50k1niJoKg4ilsj0L4mpimFUtTpOr2nzZOeQtvAksEXc7gsFgq8gV7t/U3lsaXPY7I0t42DfSE8EGlPdxRjFdHnxh+OR8h7U9b8Qs5K5UuhgyeyxaBZ1Hgw==, subType: "00" } } + creationDate: { $date: { $numberLong: "1641024000000" } } + updateDate: { $date: { $numberLong: "1641024000000" } } + status: 1 + masterKey: + provider: local + +tests: + - description: add keyAltName to non-existent data key + operations: + - name: addKeyAltName + object: *clientEncryption0 + arguments: + # First 3 letters of local_key_id replaced with 'A' (value: "#alkeylocalkey"). + id: &non_existent_id { $binary: { base64: AAAjYWxrZXlsb2NhbGtleQ==, subType: "04" } } + keyAltName: new_key_alt_name + expectResult: { $$unsetOrMatches: null } + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + databaseName: *database0Name + command: + findAndModify: *collection0Name + query: { _id: *non_existent_id } + update: { $addToSet: { keyAltNames: new_key_alt_name } } + writeConcern: { w: majority } + outcome: + - collectionName: *collection0Name + databaseName: *database0Name + documents: + - *local_key_doc + + - description: add new keyAltName to data key with no keyAltNames + operations: + - name: addKeyAltName + object: *clientEncryption0 + arguments: + id: *local_key_id + keyAltName: local_key + expectResult: *local_key_doc + - name: find + object: *collection0 + arguments: + filter: {} + projection: { _id: 0, keyAltNames: 1 } + expectResult: + - keyAltNames: [local_key] + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + databaseName: *database0Name + command: + findAndModify: *collection0Name + query: { _id: *local_key_id } + update: { $addToSet: { keyAltNames: local_key } } + writeConcern: { w: majority } + - commandStartedEvent: { commandName: find } + + - description: add existing keyAltName to existing data key + operations: + - name: addKeyAltName + object: *clientEncryption0 + arguments: + id: *local_key_id + keyAltName: local_key + expectResult: *local_key_doc + - name: addKeyAltName + # Attempting to add a duplicate keyAltName to the data key should not be an error. + object: *clientEncryption0 + arguments: + id: *local_key_id + keyAltName: local_key + expectResult: + _id: *local_key_id + keyAltNames: [local_key] + keyMaterial: { $$type: binData } + creationDate: { $$type: date } + updateDate: { $$type: date } + status: 1 + masterKey: + provider: local + - name: find + object: *collection0 + arguments: + filter: {} + projection: { _id: 0, keyAltNames: 1 } + expectResult: + - keyAltNames: [local_key] + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + databaseName: *database0Name + command: + findAndModify: *collection0Name + query: { _id: *local_key_id } + update: { $addToSet: { keyAltNames: local_key } } + writeConcern: { w: majority } + - commandStartedEvent: + databaseName: *database0Name + command: + findAndModify: *collection0Name + query: { _id: *local_key_id } + update: { $addToSet: { keyAltNames: local_key } } + writeConcern: { w: majority } + - commandStartedEvent: { commandName: find } + + - description: add new keyAltName to data key with keyAltNames + operations: + - name: addKeyAltName + object: *clientEncryption0 + arguments: + id: *local_key_id + keyAltName: local_key + expectResult: *local_key_doc + - name: addKeyAltName + object: *clientEncryption0 + arguments: + id: *local_key_id + keyAltName: another_name + expectResult: + _id: *local_key_id + keyAltNames: [local_key] + keyMaterial: { $$type: binData } + creationDate: { $$type: date } + updateDate: { $$type: date } + status: 1 + masterKey: + provider: local + - name: aggregate + object: *collection0 + arguments: + pipeline: + # Ensure keyAltNames are in deterministically sorted order. + - $project: { _id: 0, keyAltNames: $keyAltNames } + - $unwind: $keyAltNames + - $sort: { keyAltNames: 1 } + expectResult: + - keyAltNames: another_name + - keyAltNames: local_key + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + databaseName: *database0Name + command: + findAndModify: *collection0Name + query: { _id: *local_key_id } + update: { $addToSet: { keyAltNames: local_key } } + writeConcern: { w: majority } + - commandStartedEvent: + databaseName: *database0Name + command: + findAndModify: *collection0Name + query: { _id: *local_key_id } + update: { $addToSet: { keyAltNames: another_name } } + writeConcern: { w: majority } + - commandStartedEvent: { commandName: aggregate } diff --git a/src/test/spec/json/client-side-encryption/unified/createDataKey-kms_providers-invalid.json b/src/test/spec/json/client-side-encryption/unified/createDataKey-kms_providers-invalid.json new file mode 100644 index 000000000..2344a61a9 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/unified/createDataKey-kms_providers-invalid.json @@ -0,0 +1,119 @@ +{ + "description": "createDataKey-kms_providers-invalid", + "schemaVersion": "1.8", + "runOnRequirements": [ + { + "csfle": true + } + ], + "createEntities": [ + { + "client": { + "id": "client0", + "observeEvents": [ + "commandStartedEvent", + "commandSucceededEvent", + "commandFailedEvent" + ] + } + }, + { + "clientEncryption": { + "id": "clientEncryption0", + "clientEncryptionOpts": { + "keyVaultClient": "client0", + "keyVaultNamespace": "keyvault.datakeys", + "kmsProviders": { + "aws": { + "accessKeyId": { + "$$placeholder": 1 + }, + "secretAccessKey": { + "$$placeholder": 1 + } + } + } + } + } + } + ], + "tests": [ + { + "description": "create data key without required master key fields", + "operations": [ + { + "name": "createDataKey", + "object": "clientEncryption0", + "arguments": { + "kmsProvider": "aws", + "opts": { + "masterKey": {} + } + }, + "expectError": { + "isClientError": true + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [] + } + ] + }, + { + "description": "create data key with invalid master key field", + "operations": [ + { + "name": "createDataKey", + "object": "clientEncryption0", + "arguments": { + "kmsProvider": "local", + "opts": { + "masterKey": { + "invalid": 1 + } + } + }, + "expectError": { + "isClientError": true + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [] + } + ] + }, + { + "description": "create data key with invalid master key", + "operations": [ + { + "name": "createDataKey", + "object": "clientEncryption0", + "arguments": { + "kmsProvider": "aws", + "opts": { + "masterKey": { + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "region": "invalid" + } + } + }, + "expectError": { + "isClientError": true + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [] + } + ] + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/unified/createDataKey-kms_providers-invalid.yml b/src/test/spec/json/client-side-encryption/unified/createDataKey-kms_providers-invalid.yml new file mode 100644 index 000000000..f692a0907 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/unified/createDataKey-kms_providers-invalid.yml @@ -0,0 +1,67 @@ +description: createDataKey-kms_providers-invalid + +schemaVersion: "1.8" + +runOnRequirements: + - csfle: true + +createEntities: + - client: + id: &client0 client0 + observeEvents: + - commandStartedEvent + - commandSucceededEvent + - commandFailedEvent + - clientEncryption: + id: &clientEncryption0 clientEncryption0 + clientEncryptionOpts: + keyVaultClient: *client0 + keyVaultNamespace: keyvault.datakeys + kmsProviders: + aws: { accessKeyId: { $$placeholder: 1 }, secretAccessKey: { $$placeholder: 1 } } + +tests: + - description: create data key without required master key fields + operations: + - name: createDataKey + object: *clientEncryption0 + arguments: + kmsProvider: aws + opts: + masterKey: {} + expectError: + isClientError: true + expectEvents: + - client: *client0 + events: [] + + - description: create data key with invalid master key field + operations: + - name: createDataKey + object: *clientEncryption0 + arguments: + kmsProvider: local + opts: + masterKey: + invalid: 1 + expectError: + isClientError: true + expectEvents: + - client: *client0 + events: [] + + - description: create data key with invalid master key + operations: + - name: createDataKey + object: *clientEncryption0 + arguments: + kmsProvider: aws + opts: + masterKey: + key: arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0 + region: invalid + expectError: + isClientError: true + expectEvents: + - client: *client0 + events: [] diff --git a/src/test/spec/json/client-side-encryption/unified/createDataKey.json b/src/test/spec/json/client-side-encryption/unified/createDataKey.json new file mode 100644 index 000000000..110c726f9 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/unified/createDataKey.json @@ -0,0 +1,711 @@ +{ + "description": "createDataKey", + "schemaVersion": "1.8", + "runOnRequirements": [ + { + "csfle": true + } + ], + "createEntities": [ + { + "client": { + "id": "client0", + "observeEvents": [ + "commandStartedEvent" + ] + } + }, + { + "clientEncryption": { + "id": "clientEncryption0", + "clientEncryptionOpts": { + "keyVaultClient": "client0", + "keyVaultNamespace": "keyvault.datakeys", + "kmsProviders": { + "aws": { + "accessKeyId": { + "$$placeholder": 1 + }, + "secretAccessKey": { + "$$placeholder": 1 + } + }, + "azure": { + "tenantId": { + "$$placeholder": 1 + }, + "clientId": { + "$$placeholder": 1 + }, + "clientSecret": { + "$$placeholder": 1 + } + }, + "gcp": { + "email": { + "$$placeholder": 1 + }, + "privateKey": { + "$$placeholder": 1 + } + }, + "kmip": { + "endpoint": { + "$$placeholder": 1 + } + }, + "local": { + "key": { + "$$placeholder": 1 + } + } + } + } + } + }, + { + "database": { + "id": "database0", + "client": "client0", + "databaseName": "keyvault" + } + }, + { + "collection": { + "id": "collection0", + "database": "database0", + "collectionName": "datakeys" + } + } + ], + "initialData": [ + { + "databaseName": "keyvault", + "collectionName": "datakeys", + "documents": [] + } + ], + "tests": [ + { + "description": "create data key with AWS KMS provider", + "operations": [ + { + "name": "createDataKey", + "object": "clientEncryption0", + "arguments": { + "kmsProvider": "aws", + "opts": { + "masterKey": { + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "region": "us-east-1" + } + } + }, + "expectResult": { + "$$type": "binData" + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "insert": "datakeys", + "documents": [ + { + "_id": { + "$$type": "binData" + }, + "keyMaterial": { + "$$type": "binData" + }, + "creationDate": { + "$$type": "date" + }, + "updateDate": { + "$$type": "date" + }, + "status": { + "$$exists": true + }, + "masterKey": { + "provider": "aws", + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "region": "us-east-1" + } + } + ], + "writeConcern": { + "w": "majority" + } + } + } + } + ] + } + ] + }, + { + "description": "create datakey with Azure KMS provider", + "operations": [ + { + "name": "createDataKey", + "object": "clientEncryption0", + "arguments": { + "kmsProvider": "azure", + "opts": { + "masterKey": { + "keyVaultEndpoint": "key-vault-csfle.vault.azure.net", + "keyName": "key-name-csfle" + } + } + }, + "expectResult": { + "$$type": "binData" + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "insert": "datakeys", + "documents": [ + { + "_id": { + "$$type": "binData" + }, + "keyMaterial": { + "$$type": "binData" + }, + "creationDate": { + "$$type": "date" + }, + "updateDate": { + "$$type": "date" + }, + "status": { + "$$exists": true + }, + "masterKey": { + "provider": "azure", + "keyVaultEndpoint": "key-vault-csfle.vault.azure.net", + "keyName": "key-name-csfle" + } + } + ], + "writeConcern": { + "w": "majority" + } + } + } + } + ] + } + ] + }, + { + "description": "create datakey with GCP KMS provider", + "operations": [ + { + "name": "createDataKey", + "object": "clientEncryption0", + "arguments": { + "kmsProvider": "gcp", + "opts": { + "masterKey": { + "projectId": "devprod-drivers", + "location": "global", + "keyRing": "key-ring-csfle", + "keyName": "key-name-csfle" + } + } + }, + "expectResult": { + "$$type": "binData" + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "insert": "datakeys", + "documents": [ + { + "_id": { + "$$type": "binData" + }, + "keyMaterial": { + "$$type": "binData" + }, + "creationDate": { + "$$type": "date" + }, + "updateDate": { + "$$type": "date" + }, + "status": { + "$$exists": true + }, + "masterKey": { + "provider": "gcp", + "projectId": "devprod-drivers", + "location": "global", + "keyRing": "key-ring-csfle", + "keyName": "key-name-csfle" + } + } + ], + "writeConcern": { + "w": "majority" + } + } + } + } + ] + } + ] + }, + { + "description": "create datakey with KMIP KMS provider", + "operations": [ + { + "name": "createDataKey", + "object": "clientEncryption0", + "arguments": { + "kmsProvider": "kmip" + }, + "expectResult": { + "$$type": "binData" + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "insert": "datakeys", + "documents": [ + { + "_id": { + "$$type": "binData" + }, + "keyMaterial": { + "$$type": "binData" + }, + "creationDate": { + "$$type": "date" + }, + "updateDate": { + "$$type": "date" + }, + "status": { + "$$exists": true + }, + "masterKey": { + "provider": "kmip", + "keyId": { + "$$type": "string" + } + } + } + ], + "writeConcern": { + "w": "majority" + } + } + } + } + ] + } + ] + }, + { + "description": "create datakey with local KMS provider", + "operations": [ + { + "name": "createDataKey", + "object": "clientEncryption0", + "arguments": { + "kmsProvider": "local" + }, + "expectResult": { + "$$type": "binData" + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "insert": "datakeys", + "documents": [ + { + "_id": { + "$$type": "binData" + }, + "keyMaterial": { + "$$type": "binData" + }, + "creationDate": { + "$$type": "date" + }, + "updateDate": { + "$$type": "date" + }, + "status": { + "$$exists": true + }, + "masterKey": { + "provider": "local" + } + } + ], + "writeConcern": { + "w": "majority" + } + } + } + } + ] + } + ] + }, + { + "description": "create datakey with no keyAltName", + "operations": [ + { + "name": "createDataKey", + "object": "clientEncryption0", + "arguments": { + "kmsProvider": "local", + "opts": { + "keyAltNames": [] + } + }, + "expectResult": { + "$$type": "binData" + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "insert": "datakeys", + "documents": [ + { + "_id": { + "$$type": "binData" + }, + "keyAltNames": { + "$$exists": false + }, + "keyMaterial": { + "$$type": "binData" + }, + "creationDate": { + "$$type": "date" + }, + "updateDate": { + "$$type": "date" + }, + "status": { + "$$type": "int" + }, + "masterKey": { + "$$type": "object" + } + } + ], + "writeConcern": { + "w": "majority" + } + } + } + } + ] + } + ] + }, + { + "description": "create datakey with single keyAltName", + "operations": [ + { + "name": "createDataKey", + "object": "clientEncryption0", + "arguments": { + "kmsProvider": "local", + "opts": { + "keyAltNames": [ + "local_key" + ] + } + }, + "expectResult": { + "$$type": "binData" + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "insert": "datakeys", + "documents": [ + { + "_id": { + "$$type": "binData" + }, + "keyAltNames": [ + "local_key" + ], + "keyMaterial": { + "$$type": "binData" + }, + "creationDate": { + "$$type": "date" + }, + "updateDate": { + "$$type": "date" + }, + "status": { + "$$type": "int" + }, + "masterKey": { + "$$type": "object" + } + } + ], + "writeConcern": { + "w": "majority" + } + } + } + } + ] + } + ] + }, + { + "description": "create datakey with multiple keyAltNames", + "operations": [ + { + "name": "createDataKey", + "object": "clientEncryption0", + "arguments": { + "kmsProvider": "local", + "opts": { + "keyAltNames": [ + "abc", + "def" + ] + } + }, + "expectResult": { + "$$type": "binData" + } + }, + { + "name": "aggregate", + "object": "collection0", + "arguments": { + "pipeline": [ + { + "$project": { + "_id": 0, + "keyAltNames": 1 + } + }, + { + "$unwind": "$keyAltNames" + }, + { + "$sort": { + "keyAltNames": 1 + } + } + ] + }, + "expectResult": [ + { + "keyAltNames": "abc" + }, + { + "keyAltNames": "def" + } + ] + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "insert": "datakeys", + "documents": [ + { + "_id": { + "$$type": "binData" + }, + "keyAltNames": { + "$$type": "array" + }, + "keyMaterial": { + "$$type": "binData" + }, + "creationDate": { + "$$type": "date" + }, + "updateDate": { + "$$type": "date" + }, + "status": { + "$$type": "int" + }, + "masterKey": { + "$$type": "object" + } + } + ], + "writeConcern": { + "w": "majority" + } + } + } + }, + { + "commandStartedEvent": { + "commandName": "aggregate" + } + } + ] + } + ] + }, + { + "description": "create datakey with custom key material", + "operations": [ + { + "name": "createDataKey", + "object": "clientEncryption0", + "arguments": { + "kmsProvider": "local", + "opts": { + "keyMaterial": { + "$binary": { + "base64": "a2V5X21hdGVyaWFsa2V5X21hdGVyaWFsa2V5X21hdGVyaWFsa2V5X21hdGVyaWFsa2V5X21hdGVyaWFsa2V5X21hdGVyaWFsa2V5X21hdGVyaWFsa2V5X21hdGVyaWFs", + "subType": "00" + } + } + } + }, + "expectResult": { + "$$type": "binData" + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "insert": "datakeys", + "documents": [ + { + "_id": { + "$$type": "binData" + }, + "keyMaterial": { + "$$type": "binData" + }, + "creationDate": { + "$$type": "date" + }, + "updateDate": { + "$$type": "date" + }, + "status": { + "$$type": "int" + }, + "masterKey": { + "$$type": "object" + } + } + ], + "writeConcern": { + "w": "majority" + } + } + } + } + ] + } + ] + }, + { + "description": "create datakey with invalid custom key material (too short)", + "operations": [ + { + "name": "createDataKey", + "object": "clientEncryption0", + "arguments": { + "kmsProvider": "local", + "opts": { + "keyMaterial": { + "$binary": { + "base64": "a2V5X21hdGVyaWFsa2V5X21hdGVyaWFsa2V5X21hdGVyaWFsa2V5X21hdGVyaWFsa2V5X21hdGVyaWFsa2V5X21hdGVyaWFsa2V5X21hdGVyaWFs", + "subType": "00" + } + } + } + }, + "expectError": { + "isClientError": true + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [] + } + ] + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/unified/createDataKey.yml b/src/test/spec/json/client-side-encryption/unified/createDataKey.yml new file mode 100644 index 000000000..dd1463863 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/unified/createDataKey.yml @@ -0,0 +1,309 @@ +description: createDataKey + +schemaVersion: "1.8" + +runOnRequirements: + - csfle: true + +createEntities: + - client: + id: &client0 client0 + observeEvents: + - commandStartedEvent + - clientEncryption: + id: &clientEncryption0 clientEncryption0 + clientEncryptionOpts: + keyVaultClient: *client0 + keyVaultNamespace: keyvault.datakeys + kmsProviders: + aws: { accessKeyId: { $$placeholder: 1 }, secretAccessKey: { $$placeholder: 1 } } + azure: { tenantId: { $$placeholder: 1 }, clientId: { $$placeholder: 1 }, clientSecret: { $$placeholder: 1 } } + gcp: { email: { $$placeholder: 1 }, privateKey: { $$placeholder: 1 } } + kmip: { endpoint: { $$placeholder: 1 } } + local: { key: { $$placeholder: 1 } } + - database: + id: &database0 database0 + client: *client0 + databaseName: &database0Name keyvault + - collection: + id: &collection0 collection0 + database: *database0 + collectionName: &collection0Name datakeys + +initialData: + - databaseName: *database0Name + collectionName: *collection0Name + documents: [] + +tests: + - description: create data key with AWS KMS provider + operations: + - name: createDataKey + object: *clientEncryption0 + arguments: + kmsProvider: aws + opts: + masterKey: &new_aws_masterkey + key: arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0 + region: us-east-1 + expectResult: { $$type: binData } + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + databaseName: *database0Name + command: + insert: *collection0Name + documents: + - _id: { $$type: binData } + keyMaterial: { $$type: binData } + creationDate: { $$type: date } + updateDate: { $$type: date } + status: { $$exists: true } + masterKey: + provider: aws + <<: *new_aws_masterkey + writeConcern: { w: majority } + + - description: create datakey with Azure KMS provider + operations: + - name: createDataKey + object: *clientEncryption0 + arguments: + kmsProvider: azure + opts: + masterKey: &new_azure_masterkey + keyVaultEndpoint: key-vault-csfle.vault.azure.net + keyName: key-name-csfle + expectResult: { $$type: binData } + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + databaseName: *database0Name + command: + insert: *collection0Name + documents: + - _id: { $$type: binData } + keyMaterial: { $$type: binData } + creationDate: { $$type: date } + updateDate: { $$type: date } + status: { $$exists: true } + masterKey: + provider: azure + <<: *new_azure_masterkey + writeConcern: { w: majority } + + - description: create datakey with GCP KMS provider + operations: + - name: createDataKey + object: *clientEncryption0 + arguments: + kmsProvider: gcp + opts: + masterKey: &new_gcp_masterkey + projectId: devprod-drivers + location: global + keyRing: key-ring-csfle + keyName: key-name-csfle + expectResult: { $$type: binData } + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + databaseName: *database0Name + command: + insert: *collection0Name + documents: + - _id: { $$type: binData } + keyMaterial: { $$type: binData } + creationDate: { $$type: date } + updateDate: { $$type: date } + status: { $$exists: true } + masterKey: + provider: gcp + <<: *new_gcp_masterkey + writeConcern: { w: majority } + + - description: create datakey with KMIP KMS provider + operations: + - name: createDataKey + object: *clientEncryption0 + arguments: + kmsProvider: kmip + expectResult: { $$type: binData } + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + databaseName: *database0Name + command: + insert: *collection0Name + documents: + - _id: { $$type: binData } + keyMaterial: { $$type: binData } + creationDate: { $$type: date } + updateDate: { $$type: date } + status: { $$exists: true } + masterKey: + provider: kmip + keyId: { $$type: string } + writeConcern: { w: majority } + + - description: create datakey with local KMS provider + operations: + - name: createDataKey + object: *clientEncryption0 + arguments: + kmsProvider: local + expectResult: { $$type: binData } + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + databaseName: *database0Name + command: + insert: *collection0Name + documents: + - _id: { $$type: binData } + keyMaterial: { $$type: binData } + creationDate: { $$type: date } + updateDate: { $$type: date } + status: { $$exists: true } + masterKey: + provider: local + writeConcern: { w: majority } + + - description: create datakey with no keyAltName + operations: + - name: createDataKey + object: *clientEncryption0 + arguments: + kmsProvider: local + opts: + keyAltNames: [] + expectResult: { $$type: binData } + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + databaseName: *database0Name + command: + insert: *collection0Name + documents: + - _id: { $$type: binData } + # keyAltNames field should not exist if no keyAltNames are given. + keyAltNames: { $$exists: false } + keyMaterial: { $$type: binData } + creationDate: { $$type: date } + updateDate: { $$type: date } + status: { $$type: int } + masterKey: { $$type: object } + writeConcern: { w: majority } + + - description: create datakey with single keyAltName + operations: + - name: createDataKey + object: *clientEncryption0 + arguments: + kmsProvider: local + opts: + keyAltNames: ["local_key"] + expectResult: { $$type: binData } + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + databaseName: *database0Name + command: + insert: *collection0Name + documents: + - _id: { $$type: binData } + keyAltNames: [local_key] + keyMaterial: { $$type: binData } + creationDate: { $$type: date } + updateDate: { $$type: date } + status: { $$type: int } + masterKey: { $$type: object } + writeConcern: { w: majority } + + - description: create datakey with multiple keyAltNames + operations: + - name: createDataKey + object: *clientEncryption0 + arguments: + kmsProvider: local + opts: + keyAltNames: ["abc", "def"] + expectResult: { $$type: binData } + - name: aggregate + object: *collection0 + arguments: + # Need to use pipeline to sort keyAltNames for deterministic matching + # because keyAltNames is not required to be sorted. + pipeline: + - $project: { _id: 0, keyAltNames: 1 } + - $unwind: $keyAltNames + - $sort: { keyAltNames: 1 } + expectResult: + - keyAltNames: abc + - keyAltNames: def + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + databaseName: *database0Name + command: + insert: *collection0Name + documents: + - _id: { $$type: binData } + keyAltNames: { $$type: array } + keyMaterial: { $$type: binData } + creationDate: { $$type: date } + updateDate: { $$type: date } + status: { $$type: int } + masterKey: { $$type: object } + writeConcern: { w: majority } + - commandStartedEvent: { commandName: aggregate } + + - description: create datakey with custom key material + operations: + - name: createDataKey + object: *clientEncryption0 + arguments: + kmsProvider: local + opts: + # "key_material" repeated 8 times. + keyMaterial: &custom_key_material { $binary: { base64: a2V5X21hdGVyaWFsa2V5X21hdGVyaWFsa2V5X21hdGVyaWFsa2V5X21hdGVyaWFsa2V5X21hdGVyaWFsa2V5X21hdGVyaWFsa2V5X21hdGVyaWFsa2V5X21hdGVyaWFs, subType: "00" } } + expectResult: { $$type: binData } + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + databaseName: *database0Name + command: + insert: *collection0Name + documents: + - _id: { $$type: binData } + # Cannot match exact value of encrypted key material. + keyMaterial: { $$type: binData } + creationDate: { $$type: date } + updateDate: { $$type: date } + status: { $$type: int } + masterKey: { $$type: object } + writeConcern: { w: majority } + + - description: create datakey with invalid custom key material (too short) + operations: + - name: createDataKey + object: *clientEncryption0 + arguments: + kmsProvider: local + opts: + # "key_material" repeated only 7 times (key material length == 84). + keyMaterial: { $binary: { base64: a2V5X21hdGVyaWFsa2V5X21hdGVyaWFsa2V5X21hdGVyaWFsa2V5X21hdGVyaWFsa2V5X21hdGVyaWFsa2V5X21hdGVyaWFsa2V5X21hdGVyaWFs, subType: "00" } } + expectError: + isClientError: true + expectEvents: + - client: *client0 + events: [] diff --git a/src/test/spec/json/client-side-encryption/unified/deleteKey.json b/src/test/spec/json/client-side-encryption/unified/deleteKey.json new file mode 100644 index 000000000..3a10fb082 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/unified/deleteKey.json @@ -0,0 +1,557 @@ +{ + "description": "deleteKey", + "schemaVersion": "1.8", + "runOnRequirements": [ + { + "csfle": true + } + ], + "createEntities": [ + { + "client": { + "id": "client0", + "observeEvents": [ + "commandStartedEvent" + ] + } + }, + { + "clientEncryption": { + "id": "clientEncryption0", + "clientEncryptionOpts": { + "keyVaultClient": "client0", + "keyVaultNamespace": "keyvault.datakeys", + "kmsProviders": { + "local": { + "key": { + "$$placeholder": 1 + } + } + } + } + } + }, + { + "database": { + "id": "database0", + "client": "client0", + "databaseName": "keyvault" + } + }, + { + "collection": { + "id": "collection0", + "database": "database0", + "collectionName": "datakeys" + } + } + ], + "initialData": [ + { + "databaseName": "keyvault", + "collectionName": "datakeys", + "documents": [ + { + "_id": { + "$binary": { + "base64": "YXdzYXdzYXdzYXdzYXdzYQ==", + "subType": "04" + } + }, + "keyAltNames": [ + "aws_key" + ], + "keyMaterial": { + "$binary": { + "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gFXJqbF0Fy872MD7xl56D/2AAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDO7HPisPUlGzaio9vgIBEIB7/Qow46PMh/8JbEUbdXgTGhLfXPE+KIVW7T8s6YEMlGiRvMu7TV0QCIUJlSHPKZxzlJ2iwuz5yXeOag+EdY+eIQ0RKrsJ3b8UTisZYzGjfzZnxUKLzLoeXremtRCm3x47wCuHKd1dhh6FBbYt5TL2tDaj+vL2GBrKat2L", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "status": 1, + "masterKey": { + "provider": "aws", + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "region": "us-east-1" + } + }, + { + "_id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + }, + "keyAltNames": [ + "local_key" + ], + "keyMaterial": { + "$binary": { + "base64": "ABKBldDEoDW323yejOnIRk6YQmlD9d3eQthd16scKL75nz2LjNL9fgPDZWrFFOlqlhMCFaSrNJfGrFUjYk5JFDO7soG5Syb50k1niJoKg4ilsj0L4mpimFUtTpOr2nzZOeQtvAksEXc7gsFgq8gV7t/U3lsaXPY7I0t42DfSE8EGlPdxRjFdHnxh+OR8h7U9b8Qs5K5UuhgyeyxaBZ1Hgw==", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "status": 1, + "masterKey": { + "provider": "local" + } + } + ] + } + ], + "tests": [ + { + "description": "delete non-existent data key", + "operations": [ + { + "name": "deleteKey", + "object": "clientEncryption0", + "arguments": { + "id": { + "$binary": { + "base64": "AAAzYXdzYXdzYXdzYXdzYQ==", + "subType": "04" + } + } + }, + "expectResult": { + "deletedCount": 0 + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "delete": "datakeys", + "deletes": [ + { + "q": { + "_id": { + "$binary": { + "base64": "AAAzYXdzYXdzYXdzYXdzYQ==", + "subType": "04" + } + } + }, + "limit": 1 + } + ], + "writeConcern": { + "w": "majority" + } + } + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "datakeys", + "databaseName": "keyvault", + "documents": [ + { + "_id": { + "$binary": { + "base64": "YXdzYXdzYXdzYXdzYXdzYQ==", + "subType": "04" + } + }, + "keyAltNames": [ + "aws_key" + ], + "keyMaterial": { + "$binary": { + "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gFXJqbF0Fy872MD7xl56D/2AAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDO7HPisPUlGzaio9vgIBEIB7/Qow46PMh/8JbEUbdXgTGhLfXPE+KIVW7T8s6YEMlGiRvMu7TV0QCIUJlSHPKZxzlJ2iwuz5yXeOag+EdY+eIQ0RKrsJ3b8UTisZYzGjfzZnxUKLzLoeXremtRCm3x47wCuHKd1dhh6FBbYt5TL2tDaj+vL2GBrKat2L", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "status": 1, + "masterKey": { + "provider": "aws", + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "region": "us-east-1" + } + }, + { + "_id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + }, + "keyAltNames": [ + "local_key" + ], + "keyMaterial": { + "$binary": { + "base64": "ABKBldDEoDW323yejOnIRk6YQmlD9d3eQthd16scKL75nz2LjNL9fgPDZWrFFOlqlhMCFaSrNJfGrFUjYk5JFDO7soG5Syb50k1niJoKg4ilsj0L4mpimFUtTpOr2nzZOeQtvAksEXc7gsFgq8gV7t/U3lsaXPY7I0t42DfSE8EGlPdxRjFdHnxh+OR8h7U9b8Qs5K5UuhgyeyxaBZ1Hgw==", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "status": 1, + "masterKey": { + "provider": "local" + } + } + ] + } + ] + }, + { + "description": "delete existing AWS data key", + "operations": [ + { + "name": "deleteKey", + "object": "clientEncryption0", + "arguments": { + "id": { + "$binary": { + "base64": "YXdzYXdzYXdzYXdzYXdzYQ==", + "subType": "04" + } + } + }, + "expectResult": { + "deletedCount": 1 + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "delete": "datakeys", + "deletes": [ + { + "q": { + "_id": { + "$binary": { + "base64": "YXdzYXdzYXdzYXdzYXdzYQ==", + "subType": "04" + } + } + }, + "limit": 1 + } + ], + "writeConcern": { + "w": "majority" + } + } + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "datakeys", + "databaseName": "keyvault", + "documents": [ + { + "_id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + }, + "keyAltNames": [ + "local_key" + ], + "keyMaterial": { + "$binary": { + "base64": "ABKBldDEoDW323yejOnIRk6YQmlD9d3eQthd16scKL75nz2LjNL9fgPDZWrFFOlqlhMCFaSrNJfGrFUjYk5JFDO7soG5Syb50k1niJoKg4ilsj0L4mpimFUtTpOr2nzZOeQtvAksEXc7gsFgq8gV7t/U3lsaXPY7I0t42DfSE8EGlPdxRjFdHnxh+OR8h7U9b8Qs5K5UuhgyeyxaBZ1Hgw==", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "status": 1, + "masterKey": { + "provider": "local" + } + } + ] + } + ] + }, + { + "description": "delete existing local data key", + "operations": [ + { + "name": "deleteKey", + "object": "clientEncryption0", + "arguments": { + "id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + } + }, + "expectResult": { + "deletedCount": 1 + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "delete": "datakeys", + "deletes": [ + { + "q": { + "_id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + } + }, + "limit": 1 + } + ], + "writeConcern": { + "w": "majority" + } + } + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "datakeys", + "databaseName": "keyvault", + "documents": [ + { + "_id": { + "$binary": { + "base64": "YXdzYXdzYXdzYXdzYXdzYQ==", + "subType": "04" + } + }, + "keyAltNames": [ + "aws_key" + ], + "keyMaterial": { + "$binary": { + "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gFXJqbF0Fy872MD7xl56D/2AAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDO7HPisPUlGzaio9vgIBEIB7/Qow46PMh/8JbEUbdXgTGhLfXPE+KIVW7T8s6YEMlGiRvMu7TV0QCIUJlSHPKZxzlJ2iwuz5yXeOag+EdY+eIQ0RKrsJ3b8UTisZYzGjfzZnxUKLzLoeXremtRCm3x47wCuHKd1dhh6FBbYt5TL2tDaj+vL2GBrKat2L", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "status": 1, + "masterKey": { + "provider": "aws", + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "region": "us-east-1" + } + } + ] + } + ] + }, + { + "description": "delete existing data key twice", + "operations": [ + { + "name": "deleteKey", + "object": "clientEncryption0", + "arguments": { + "id": { + "$binary": { + "base64": "YXdzYXdzYXdzYXdzYXdzYQ==", + "subType": "04" + } + } + }, + "expectResult": { + "deletedCount": 1 + } + }, + { + "name": "deleteKey", + "object": "clientEncryption0", + "arguments": { + "id": { + "$binary": { + "base64": "YXdzYXdzYXdzYXdzYXdzYQ==", + "subType": "04" + } + } + }, + "expectResult": { + "deletedCount": 0 + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "delete": "datakeys", + "deletes": [ + { + "q": { + "_id": { + "$binary": { + "base64": "YXdzYXdzYXdzYXdzYXdzYQ==", + "subType": "04" + } + } + }, + "limit": 1 + } + ], + "writeConcern": { + "w": "majority" + } + } + } + }, + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "delete": "datakeys", + "deletes": [ + { + "q": { + "_id": { + "$binary": { + "base64": "YXdzYXdzYXdzYXdzYXdzYQ==", + "subType": "04" + } + } + }, + "limit": 1 + } + ], + "writeConcern": { + "w": "majority" + } + } + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "datakeys", + "databaseName": "keyvault", + "documents": [ + { + "_id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + }, + "keyAltNames": [ + "local_key" + ], + "keyMaterial": { + "$binary": { + "base64": "ABKBldDEoDW323yejOnIRk6YQmlD9d3eQthd16scKL75nz2LjNL9fgPDZWrFFOlqlhMCFaSrNJfGrFUjYk5JFDO7soG5Syb50k1niJoKg4ilsj0L4mpimFUtTpOr2nzZOeQtvAksEXc7gsFgq8gV7t/U3lsaXPY7I0t42DfSE8EGlPdxRjFdHnxh+OR8h7U9b8Qs5K5UuhgyeyxaBZ1Hgw==", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "status": 1, + "masterKey": { + "provider": "local" + } + } + ] + } + ] + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/unified/deleteKey.yml b/src/test/spec/json/client-side-encryption/unified/deleteKey.yml new file mode 100644 index 000000000..c598e9469 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/unified/deleteKey.yml @@ -0,0 +1,159 @@ +description: deleteKey + +schemaVersion: "1.8" + +runOnRequirements: + - csfle: true + +createEntities: + - client: + id: &client0 client0 + observeEvents: + - commandStartedEvent + - clientEncryption: + id: &clientEncryption0 clientEncryption0 + clientEncryptionOpts: + keyVaultClient: *client0 + keyVaultNamespace: keyvault.datakeys + kmsProviders: + local: { key: { $$placeholder: 1 } } + - database: + id: &database0 database0 + client: *client0 + databaseName: &database0Name keyvault + - collection: + id: &collection0 collection0 + database: *database0 + collectionName: &collection0Name datakeys + +initialData: + - databaseName: *database0Name + collectionName: *collection0Name + documents: + - &aws_key_doc + _id: &aws_key_id { $binary: { base64: YXdzYXdzYXdzYXdzYXdzYQ==, subType: "04" } } + keyAltNames: ["aws_key"] + keyMaterial: { $binary: { base64: AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gFXJqbF0Fy872MD7xl56D/2AAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDO7HPisPUlGzaio9vgIBEIB7/Qow46PMh/8JbEUbdXgTGhLfXPE+KIVW7T8s6YEMlGiRvMu7TV0QCIUJlSHPKZxzlJ2iwuz5yXeOag+EdY+eIQ0RKrsJ3b8UTisZYzGjfzZnxUKLzLoeXremtRCm3x47wCuHKd1dhh6FBbYt5TL2tDaj+vL2GBrKat2L, subType: "00" } } + creationDate: { $date: { $numberLong: "1641024000000" } } + updateDate: { $date: { $numberLong: "1641024000000" } } + status: 1 + masterKey: + provider: aws + key: arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0 + region: us-east-1 + - &local_key_doc + _id: &local_key_id { $binary: { base64: bG9jYWxrZXlsb2NhbGtleQ==, subType: "04" } } + keyAltNames: ["local_key"] + keyMaterial: { $binary: { base64: ABKBldDEoDW323yejOnIRk6YQmlD9d3eQthd16scKL75nz2LjNL9fgPDZWrFFOlqlhMCFaSrNJfGrFUjYk5JFDO7soG5Syb50k1niJoKg4ilsj0L4mpimFUtTpOr2nzZOeQtvAksEXc7gsFgq8gV7t/U3lsaXPY7I0t42DfSE8EGlPdxRjFdHnxh+OR8h7U9b8Qs5K5UuhgyeyxaBZ1Hgw==, subType: "00" } } + creationDate: { $date: { $numberLong: "1641024000000" } } + updateDate: { $date: { $numberLong: "1641024000000" } } + status: 1 + masterKey: + provider: local + +tests: + - description: delete non-existent data key + operations: + - name: deleteKey + object: *clientEncryption0 + arguments: + # *aws_key_id with first three letters replaced with 'A' (value: "3awsawsawsawsa"). + id: &non_existent_id { $binary: { base64: AAAzYXdzYXdzYXdzYXdzYQ==, subType: "04" } } + expectResult: + deletedCount: 0 + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + databaseName: *database0Name + command: + delete: *collection0Name + deletes: [{ q: { _id: *non_existent_id }, limit: 1 }] + writeConcern: { w: majority } + outcome: + - collectionName: *collection0Name + databaseName: *database0Name + documents: + - *aws_key_doc + - *local_key_doc + + - description: delete existing AWS data key + operations: + - name: deleteKey + object: *clientEncryption0 + arguments: + id: *aws_key_id + expectResult: + deletedCount: 1 + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + databaseName: *database0Name + command: + delete: *collection0Name + deletes: [{ q: { _id: *aws_key_id }, limit: 1 }] + writeConcern: { w: majority } + outcome: + - collectionName: *collection0Name + databaseName: *database0Name + documents: + - *local_key_doc + + - description: delete existing local data key + operations: + - name: deleteKey + object: *clientEncryption0 + arguments: + id: *local_key_id + expectResult: + deletedCount: 1 + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + databaseName: *database0Name + command: + delete: *collection0Name + deletes: [{ q: { _id: *local_key_id }, limit: 1 }] + writeConcern: { w: majority } + outcome: + - collectionName: *collection0Name + databaseName: *database0Name + documents: + - *aws_key_doc + + - description: delete existing data key twice + operations: + - name: deleteKey + object: *clientEncryption0 + arguments: + id: *aws_key_id + expectResult: + deletedCount: 1 + - name: deleteKey + object: *clientEncryption0 + arguments: + id: *aws_key_id + expectResult: + deletedCount: 0 + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + databaseName: *database0Name + command: + delete: *collection0Name + deletes: [{ q: { _id: *aws_key_id }, limit: 1 }] + writeConcern: { w: majority } + - commandStartedEvent: + databaseName: *database0Name + command: + delete: *collection0Name + deletes: [{ q: { _id: *aws_key_id }, limit: 1 }] + writeConcern: { w: majority } + outcome: + - collectionName: *collection0Name + databaseName: *database0Name + documents: + - *local_key_doc diff --git a/src/test/spec/json/client-side-encryption/unified/getKey.json b/src/test/spec/json/client-side-encryption/unified/getKey.json new file mode 100644 index 000000000..2ea3fe735 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/unified/getKey.json @@ -0,0 +1,319 @@ +{ + "description": "getKey", + "schemaVersion": "1.8", + "runOnRequirements": [ + { + "csfle": true + } + ], + "createEntities": [ + { + "client": { + "id": "client0", + "observeEvents": [ + "commandStartedEvent" + ] + } + }, + { + "clientEncryption": { + "id": "clientEncryption0", + "clientEncryptionOpts": { + "keyVaultClient": "client0", + "keyVaultNamespace": "keyvault.datakeys", + "kmsProviders": { + "local": { + "key": { + "$$placeholder": 1 + } + } + } + } + } + }, + { + "database": { + "id": "database0", + "client": "client0", + "databaseName": "keyvault" + } + }, + { + "collection": { + "id": "collection0", + "database": "database0", + "collectionName": "datakeys" + } + } + ], + "initialData": [ + { + "databaseName": "keyvault", + "collectionName": "datakeys", + "documents": [ + { + "_id": { + "$binary": { + "base64": "YXdzYXdzYXdzYXdzYXdzYQ==", + "subType": "04" + } + }, + "keyAltNames": [ + "aws_key" + ], + "keyMaterial": { + "$binary": { + "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gFXJqbF0Fy872MD7xl56D/2AAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDO7HPisPUlGzaio9vgIBEIB7/Qow46PMh/8JbEUbdXgTGhLfXPE+KIVW7T8s6YEMlGiRvMu7TV0QCIUJlSHPKZxzlJ2iwuz5yXeOag+EdY+eIQ0RKrsJ3b8UTisZYzGjfzZnxUKLzLoeXremtRCm3x47wCuHKd1dhh6FBbYt5TL2tDaj+vL2GBrKat2L", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "status": 1, + "masterKey": { + "provider": "aws", + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "region": "us-east-1" + } + }, + { + "_id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + }, + "keyAltNames": [ + "local_key" + ], + "keyMaterial": { + "$binary": { + "base64": "ABKBldDEoDW323yejOnIRk6YQmlD9d3eQthd16scKL75nz2LjNL9fgPDZWrFFOlqlhMCFaSrNJfGrFUjYk5JFDO7soG5Syb50k1niJoKg4ilsj0L4mpimFUtTpOr2nzZOeQtvAksEXc7gsFgq8gV7t/U3lsaXPY7I0t42DfSE8EGlPdxRjFdHnxh+OR8h7U9b8Qs5K5UuhgyeyxaBZ1Hgw==", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "status": 1, + "masterKey": { + "provider": "local" + } + } + ] + } + ], + "tests": [ + { + "description": "get non-existent data key", + "operations": [ + { + "name": "getKey", + "object": "clientEncryption0", + "arguments": { + "id": { + "$binary": { + "base64": "AAAzYXdzYXdzYXdzYXdzYQ==", + "subType": "04" + } + } + }, + "expectResult": { + "$$unsetOrMatches": null + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "find": "datakeys", + "filter": { + "_id": { + "$binary": { + "base64": "AAAzYXdzYXdzYXdzYXdzYQ==", + "subType": "04" + } + } + }, + "readConcern": { + "level": "majority" + } + } + } + } + ] + } + ] + }, + { + "description": "get existing AWS data key", + "operations": [ + { + "name": "getKey", + "object": "clientEncryption0", + "arguments": { + "id": { + "$binary": { + "base64": "YXdzYXdzYXdzYXdzYXdzYQ==", + "subType": "04" + } + } + }, + "expectResult": { + "_id": { + "$binary": { + "base64": "YXdzYXdzYXdzYXdzYXdzYQ==", + "subType": "04" + } + }, + "keyAltNames": [ + "aws_key" + ], + "keyMaterial": { + "$binary": { + "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gFXJqbF0Fy872MD7xl56D/2AAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDO7HPisPUlGzaio9vgIBEIB7/Qow46PMh/8JbEUbdXgTGhLfXPE+KIVW7T8s6YEMlGiRvMu7TV0QCIUJlSHPKZxzlJ2iwuz5yXeOag+EdY+eIQ0RKrsJ3b8UTisZYzGjfzZnxUKLzLoeXremtRCm3x47wCuHKd1dhh6FBbYt5TL2tDaj+vL2GBrKat2L", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "status": 1, + "masterKey": { + "provider": "aws", + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "region": "us-east-1" + } + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "find": "datakeys", + "filter": { + "_id": { + "$binary": { + "base64": "YXdzYXdzYXdzYXdzYXdzYQ==", + "subType": "04" + } + } + }, + "readConcern": { + "level": "majority" + } + } + } + } + ] + } + ] + }, + { + "description": "get existing local data key", + "operations": [ + { + "name": "getKey", + "object": "clientEncryption0", + "arguments": { + "id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + } + }, + "expectResult": { + "_id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + }, + "keyAltNames": [ + "local_key" + ], + "keyMaterial": { + "$binary": { + "base64": "ABKBldDEoDW323yejOnIRk6YQmlD9d3eQthd16scKL75nz2LjNL9fgPDZWrFFOlqlhMCFaSrNJfGrFUjYk5JFDO7soG5Syb50k1niJoKg4ilsj0L4mpimFUtTpOr2nzZOeQtvAksEXc7gsFgq8gV7t/U3lsaXPY7I0t42DfSE8EGlPdxRjFdHnxh+OR8h7U9b8Qs5K5UuhgyeyxaBZ1Hgw==", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "status": 1, + "masterKey": { + "provider": "local" + } + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "find": "datakeys", + "filter": { + "_id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + } + }, + "readConcern": { + "level": "majority" + } + } + } + } + ] + } + ] + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/unified/getKey.yml b/src/test/spec/json/client-side-encryption/unified/getKey.yml new file mode 100644 index 000000000..149922761 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/unified/getKey.yml @@ -0,0 +1,105 @@ +description: getKey + +schemaVersion: "1.8" + +runOnRequirements: + - csfle: true + +createEntities: + - client: + id: &client0 client0 + observeEvents: + - commandStartedEvent + - clientEncryption: + id: &clientEncryption0 clientEncryption0 + clientEncryptionOpts: + keyVaultClient: *client0 + keyVaultNamespace: keyvault.datakeys + kmsProviders: + local: { key: { $$placeholder: 1 } } + - database: + id: &database0 database0 + client: *client0 + databaseName: &database0Name keyvault + - collection: + id: &collection0 collection0 + database: *database0 + collectionName: &collection0Name datakeys + +initialData: + - databaseName: *database0Name + collectionName: *collection0Name + documents: + - &aws_key_doc + _id: &aws_key_id { $binary: { base64: YXdzYXdzYXdzYXdzYXdzYQ==, subType: "04" } } + keyAltNames: ["aws_key"] + keyMaterial: { $binary: { base64: AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gFXJqbF0Fy872MD7xl56D/2AAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDO7HPisPUlGzaio9vgIBEIB7/Qow46PMh/8JbEUbdXgTGhLfXPE+KIVW7T8s6YEMlGiRvMu7TV0QCIUJlSHPKZxzlJ2iwuz5yXeOag+EdY+eIQ0RKrsJ3b8UTisZYzGjfzZnxUKLzLoeXremtRCm3x47wCuHKd1dhh6FBbYt5TL2tDaj+vL2GBrKat2L, subType: "00" } } + creationDate: { $date: { $numberLong: "1641024000000" } } + updateDate: { $date: { $numberLong: "1641024000000" } } + status: 1 + masterKey: + provider: aws + key: arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0 + region: us-east-1 + - &local_key_doc + _id: &local_key_id { $binary: { base64: bG9jYWxrZXlsb2NhbGtleQ==, subType: "04" } } + keyAltNames: ["local_key"] + keyMaterial: { $binary: { base64: ABKBldDEoDW323yejOnIRk6YQmlD9d3eQthd16scKL75nz2LjNL9fgPDZWrFFOlqlhMCFaSrNJfGrFUjYk5JFDO7soG5Syb50k1niJoKg4ilsj0L4mpimFUtTpOr2nzZOeQtvAksEXc7gsFgq8gV7t/U3lsaXPY7I0t42DfSE8EGlPdxRjFdHnxh+OR8h7U9b8Qs5K5UuhgyeyxaBZ1Hgw==, subType: "00" } } + creationDate: { $date: { $numberLong: "1641024000000" } } + updateDate: { $date: { $numberLong: "1641024000000" } } + status: 1 + masterKey: + provider: local + +tests: + - description: get non-existent data key + operations: + - name: getKey + object: *clientEncryption0 + arguments: + # *aws_key_id with first three letters replaced with 'A' (value: "3awsawsawsawsa"). + id: &non_existent_id { $binary: { base64: AAAzYXdzYXdzYXdzYXdzYQ==, subType: "04" } } + expectResult: { $$unsetOrMatches: null } + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + databaseName: *database0Name + command: + find: *collection0Name + filter: { _id: *non_existent_id } + readConcern: { level: majority } + + - description: get existing AWS data key + operations: + - name: getKey + object: *clientEncryption0 + arguments: + id: *aws_key_id + expectResult: *aws_key_doc + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + databaseName: *database0Name + command: + find: *collection0Name + filter: { _id: *aws_key_id } + readConcern: { level: majority } + + - description: get existing local data key + operations: + - name: getKey + object: *clientEncryption0 + arguments: + id: *local_key_id + expectResult: *local_key_doc + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + databaseName: *database0Name + command: + find: *collection0Name + filter: { _id: *local_key_id } + readConcern: { level: majority } diff --git a/src/test/spec/json/client-side-encryption/unified/getKeyByAltName.json b/src/test/spec/json/client-side-encryption/unified/getKeyByAltName.json new file mode 100644 index 000000000..2505abc16 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/unified/getKeyByAltName.json @@ -0,0 +1,289 @@ +{ + "description": "getKeyByAltName", + "schemaVersion": "1.8", + "runOnRequirements": [ + { + "csfle": true + } + ], + "createEntities": [ + { + "client": { + "id": "client0", + "observeEvents": [ + "commandStartedEvent" + ] + } + }, + { + "clientEncryption": { + "id": "clientEncryption0", + "clientEncryptionOpts": { + "keyVaultClient": "client0", + "keyVaultNamespace": "keyvault.datakeys", + "kmsProviders": { + "local": { + "key": { + "$$placeholder": 1 + } + } + } + } + } + }, + { + "database": { + "id": "database0", + "client": "client0", + "databaseName": "keyvault" + } + }, + { + "collection": { + "id": "collection0", + "database": "database0", + "collectionName": "datakeys" + } + } + ], + "initialData": [ + { + "databaseName": "keyvault", + "collectionName": "datakeys", + "documents": [ + { + "_id": { + "$binary": { + "base64": "YXdzYXdzYXdzYXdzYXdzYQ==", + "subType": "04" + } + }, + "keyAltNames": [ + "aws_key" + ], + "keyMaterial": { + "$binary": { + "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gFXJqbF0Fy872MD7xl56D/2AAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDO7HPisPUlGzaio9vgIBEIB7/Qow46PMh/8JbEUbdXgTGhLfXPE+KIVW7T8s6YEMlGiRvMu7TV0QCIUJlSHPKZxzlJ2iwuz5yXeOag+EdY+eIQ0RKrsJ3b8UTisZYzGjfzZnxUKLzLoeXremtRCm3x47wCuHKd1dhh6FBbYt5TL2tDaj+vL2GBrKat2L", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "status": 1, + "masterKey": { + "provider": "aws", + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "region": "us-east-1" + } + }, + { + "_id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + }, + "keyAltNames": [ + "local_key" + ], + "keyMaterial": { + "$binary": { + "base64": "ABKBldDEoDW323yejOnIRk6YQmlD9d3eQthd16scKL75nz2LjNL9fgPDZWrFFOlqlhMCFaSrNJfGrFUjYk5JFDO7soG5Syb50k1niJoKg4ilsj0L4mpimFUtTpOr2nzZOeQtvAksEXc7gsFgq8gV7t/U3lsaXPY7I0t42DfSE8EGlPdxRjFdHnxh+OR8h7U9b8Qs5K5UuhgyeyxaBZ1Hgw==", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "status": 1, + "masterKey": { + "provider": "local" + } + } + ] + } + ], + "tests": [ + { + "description": "get non-existent data key", + "operations": [ + { + "name": "getKeyByAltName", + "object": "clientEncryption0", + "arguments": { + "keyAltName": "does_not_exist" + }, + "expectResult": { + "$$unsetOrMatches": null + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "find": "datakeys", + "filter": { + "keyAltNames": "does_not_exist" + }, + "readConcern": { + "level": "majority" + } + } + } + } + ] + } + ] + }, + { + "description": "get existing AWS data key", + "operations": [ + { + "name": "getKeyByAltName", + "object": "clientEncryption0", + "arguments": { + "keyAltName": "aws_key" + }, + "expectResult": { + "_id": { + "$binary": { + "base64": "YXdzYXdzYXdzYXdzYXdzYQ==", + "subType": "04" + } + }, + "keyAltNames": [ + "aws_key" + ], + "keyMaterial": { + "$binary": { + "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gFXJqbF0Fy872MD7xl56D/2AAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDO7HPisPUlGzaio9vgIBEIB7/Qow46PMh/8JbEUbdXgTGhLfXPE+KIVW7T8s6YEMlGiRvMu7TV0QCIUJlSHPKZxzlJ2iwuz5yXeOag+EdY+eIQ0RKrsJ3b8UTisZYzGjfzZnxUKLzLoeXremtRCm3x47wCuHKd1dhh6FBbYt5TL2tDaj+vL2GBrKat2L", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "status": 1, + "masterKey": { + "provider": "aws", + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "region": "us-east-1" + } + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "find": "datakeys", + "filter": { + "keyAltNames": "aws_key" + }, + "readConcern": { + "level": "majority" + } + } + } + } + ] + } + ] + }, + { + "description": "get existing local data key", + "operations": [ + { + "name": "getKeyByAltName", + "object": "clientEncryption0", + "arguments": { + "keyAltName": "local_key" + }, + "expectResult": { + "_id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + }, + "keyAltNames": [ + "local_key" + ], + "keyMaterial": { + "$binary": { + "base64": "ABKBldDEoDW323yejOnIRk6YQmlD9d3eQthd16scKL75nz2LjNL9fgPDZWrFFOlqlhMCFaSrNJfGrFUjYk5JFDO7soG5Syb50k1niJoKg4ilsj0L4mpimFUtTpOr2nzZOeQtvAksEXc7gsFgq8gV7t/U3lsaXPY7I0t42DfSE8EGlPdxRjFdHnxh+OR8h7U9b8Qs5K5UuhgyeyxaBZ1Hgw==", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "status": 1, + "masterKey": { + "provider": "local" + } + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "find": "datakeys", + "filter": { + "keyAltNames": "local_key" + }, + "readConcern": { + "level": "majority" + } + } + } + } + ] + } + ] + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/unified/getKeyByAltName.yml b/src/test/spec/json/client-side-encryption/unified/getKeyByAltName.yml new file mode 100644 index 000000000..b0cada879 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/unified/getKeyByAltName.yml @@ -0,0 +1,104 @@ +description: getKeyByAltName + +schemaVersion: "1.8" + +runOnRequirements: + - csfle: true + +createEntities: + - client: + id: &client0 client0 + observeEvents: + - commandStartedEvent + - clientEncryption: + id: &clientEncryption0 clientEncryption0 + clientEncryptionOpts: + keyVaultClient: *client0 + keyVaultNamespace: keyvault.datakeys + kmsProviders: + local: { key: { $$placeholder: 1 } } + - database: + id: &database0 database0 + client: *client0 + databaseName: &database0Name keyvault + - collection: + id: &collection0 collection0 + database: *database0 + collectionName: &collection0Name datakeys + +initialData: + - databaseName: *database0Name + collectionName: *collection0Name + documents: + - &aws_key_doc + _id: { $binary: { base64: YXdzYXdzYXdzYXdzYXdzYQ==, subType: "04" } } + keyAltNames: ["aws_key"] + keyMaterial: { $binary: { base64: AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gFXJqbF0Fy872MD7xl56D/2AAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDO7HPisPUlGzaio9vgIBEIB7/Qow46PMh/8JbEUbdXgTGhLfXPE+KIVW7T8s6YEMlGiRvMu7TV0QCIUJlSHPKZxzlJ2iwuz5yXeOag+EdY+eIQ0RKrsJ3b8UTisZYzGjfzZnxUKLzLoeXremtRCm3x47wCuHKd1dhh6FBbYt5TL2tDaj+vL2GBrKat2L, subType: "00" } } + creationDate: { $date: { $numberLong: "1641024000000" } } + updateDate: { $date: { $numberLong: "1641024000000" } } + status: 1 + masterKey: + provider: aws + key: arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0 + region: us-east-1 + - &local_key_doc + _id: { $binary: { base64: bG9jYWxrZXlsb2NhbGtleQ==, subType: "04" } } + keyAltNames: ["local_key"] + keyMaterial: { $binary: { base64: ABKBldDEoDW323yejOnIRk6YQmlD9d3eQthd16scKL75nz2LjNL9fgPDZWrFFOlqlhMCFaSrNJfGrFUjYk5JFDO7soG5Syb50k1niJoKg4ilsj0L4mpimFUtTpOr2nzZOeQtvAksEXc7gsFgq8gV7t/U3lsaXPY7I0t42DfSE8EGlPdxRjFdHnxh+OR8h7U9b8Qs5K5UuhgyeyxaBZ1Hgw==, subType: "00" } } + creationDate: { $date: { $numberLong: "1641024000000" } } + updateDate: { $date: { $numberLong: "1641024000000" } } + status: 1 + masterKey: + provider: local + +tests: + - description: get non-existent data key + operations: + - name: getKeyByAltName + object: *clientEncryption0 + arguments: + keyAltName: does_not_exist + expectResult: { $$unsetOrMatches: null } + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + databaseName: *database0Name + command: + find: *collection0Name + filter: { keyAltNames: does_not_exist } + readConcern: { level: majority } + + - description: get existing AWS data key + operations: + - name: getKeyByAltName + object: *clientEncryption0 + arguments: + keyAltName: aws_key + expectResult: *aws_key_doc + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + databaseName: *database0Name + command: + find: *collection0Name + filter: { keyAltNames: aws_key } + readConcern: { level: majority } + + - description: get existing local data key + operations: + - name: getKeyByAltName + object: *clientEncryption0 + arguments: + keyAltName: local_key + expectResult: *local_key_doc + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + databaseName: *database0Name + command: + find: *collection0Name + filter: { keyAltNames: local_key } + readConcern: { level: majority } diff --git a/src/test/spec/json/client-side-encryption/unified/getKeys.json b/src/test/spec/json/client-side-encryption/unified/getKeys.json new file mode 100644 index 000000000..d94471235 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/unified/getKeys.json @@ -0,0 +1,260 @@ +{ + "description": "getKeys", + "schemaVersion": "1.8", + "runOnRequirements": [ + { + "csfle": true + } + ], + "createEntities": [ + { + "client": { + "id": "client0", + "observeEvents": [ + "commandStartedEvent" + ] + } + }, + { + "clientEncryption": { + "id": "clientEncryption0", + "clientEncryptionOpts": { + "keyVaultClient": "client0", + "keyVaultNamespace": "keyvault.datakeys", + "kmsProviders": { + "local": { + "key": { + "$$placeholder": 1 + } + } + } + } + } + }, + { + "database": { + "id": "database0", + "client": "client0", + "databaseName": "keyvault" + } + }, + { + "collection": { + "id": "collection0", + "database": "database0", + "collectionName": "datakeys" + } + } + ], + "initialData": [ + { + "databaseName": "keyvault", + "collectionName": "datakeys", + "documents": [] + } + ], + "tests": [ + { + "description": "getKeys with zero key documents", + "operations": [ + { + "name": "getKeys", + "object": "clientEncryption0", + "expectResult": [] + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "find": "datakeys", + "filter": {}, + "readConcern": { + "level": "majority" + } + } + } + } + ] + } + ] + }, + { + "description": "getKeys with single key documents", + "operations": [ + { + "name": "createDataKey", + "object": "clientEncryption0", + "arguments": { + "kmsProvider": "local", + "opts": { + "keyAltNames": [ + "abc" + ] + } + }, + "expectResult": { + "$$type": "binData" + } + }, + { + "name": "getKeys", + "object": "clientEncryption0", + "expectResult": [ + { + "_id": { + "$$type": "binData" + }, + "keyAltNames": [ + "abc" + ], + "keyMaterial": { + "$$type": "binData" + }, + "creationDate": { + "$$type": "date" + }, + "updateDate": { + "$$type": "date" + }, + "status": { + "$$type": "int" + }, + "masterKey": { + "$$type": "object" + } + } + ] + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "commandName": "insert" + } + }, + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "find": "datakeys", + "filter": {}, + "readConcern": { + "level": "majority" + } + } + } + } + ] + } + ] + }, + { + "description": "getKeys with many key documents", + "operations": [ + { + "name": "createDataKey", + "object": "clientEncryption0", + "arguments": { + "kmsProvider": "local" + }, + "expectResult": { + "$$type": "binData" + } + }, + { + "name": "createDataKey", + "object": "clientEncryption0", + "arguments": { + "kmsProvider": "local" + }, + "expectResult": { + "$$type": "binData" + } + }, + { + "name": "getKeys", + "object": "clientEncryption0", + "expectResult": [ + { + "_id": { + "$$type": "binData" + }, + "keyMaterial": { + "$$type": "binData" + }, + "creationDate": { + "$$type": "date" + }, + "updateDate": { + "$$type": "date" + }, + "status": { + "$$type": "int" + }, + "masterKey": { + "$$type": "object" + } + }, + { + "_id": { + "$$type": "binData" + }, + "keyMaterial": { + "$$type": "binData" + }, + "creationDate": { + "$$type": "date" + }, + "updateDate": { + "$$type": "date" + }, + "status": { + "$$type": "int" + }, + "masterKey": { + "$$type": "object" + } + } + ] + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "commandName": "insert" + } + }, + { + "commandStartedEvent": { + "commandName": "insert" + } + }, + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "find": "datakeys", + "filter": {}, + "readConcern": { + "level": "majority" + } + } + } + } + ] + } + ] + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/unified/getKeys.yml b/src/test/spec/json/client-side-encryption/unified/getKeys.yml new file mode 100644 index 000000000..f39643943 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/unified/getKeys.yml @@ -0,0 +1,122 @@ +description: getKeys + +schemaVersion: "1.8" + +runOnRequirements: + - csfle: true + +createEntities: + - client: + id: &client0 client0 + observeEvents: + - commandStartedEvent + - clientEncryption: + id: &clientEncryption0 clientEncryption0 + clientEncryptionOpts: + keyVaultClient: *client0 + keyVaultNamespace: keyvault.datakeys + kmsProviders: + local: { key: { $$placeholder: 1 } } + - database: + id: &database0 database0 + client: *client0 + databaseName: &database0Name keyvault + - collection: + id: &collection0 collection0 + database: *database0 + collectionName: &collection0Name datakeys + +initialData: + - databaseName: *database0Name + collectionName: *collection0Name + documents: [] + +tests: + - description: getKeys with zero key documents + operations: + - name: getKeys + object: *clientEncryption0 + expectResult: [] + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + databaseName: *database0Name + command: + find: *collection0Name + filter: {} + readConcern: { level: majority } + + - description: getKeys with single key documents + operations: + - name: createDataKey + object: *clientEncryption0 + arguments: + kmsProvider: local + opts: + keyAltNames: ["abc"] + expectResult: { $$type: binData } + - name: getKeys + object: *clientEncryption0 + expectResult: + - _id: { $$type: binData } + keyAltNames: ["abc"] + keyMaterial: { $$type: binData } + creationDate: { $$type: date } + updateDate: { $$type: date } + status: { $$type: int } + masterKey: { $$type: object } + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + commandName: insert + - commandStartedEvent: + databaseName: *database0Name + command: + find: *collection0Name + filter: {} + readConcern: { level: majority } + + - description: getKeys with many key documents + operations: + - name: createDataKey + object: *clientEncryption0 + arguments: + kmsProvider: local + expectResult: { $$type: binData } + - name: createDataKey + object: *clientEncryption0 + arguments: + kmsProvider: local + expectResult: { $$type: binData } + - name: getKeys + object: *clientEncryption0 + expectResult: + # Cannot expect deterministic order of results, so only assert that + # exactly two key documents are returned. + - _id: { $$type: binData } + keyMaterial: { $$type: binData } + creationDate: { $$type: date } + updateDate: { $$type: date } + status: { $$type: int } + masterKey: { $$type: object } + - _id: { $$type: binData } + keyMaterial: { $$type: binData } + creationDate: { $$type: date } + updateDate: { $$type: date } + status: { $$type: int } + masterKey: { $$type: object } + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + commandName: insert + - commandStartedEvent: + commandName: insert + - commandStartedEvent: + databaseName: *database0Name + command: + find: *collection0Name + filter: {} + readConcern: { level: majority } diff --git a/src/test/spec/json/client-side-encryption/unified/removeKeyAltName.json b/src/test/spec/json/client-side-encryption/unified/removeKeyAltName.json new file mode 100644 index 000000000..1b7077077 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/unified/removeKeyAltName.json @@ -0,0 +1,672 @@ +{ + "description": "removeKeyAltName", + "schemaVersion": "1.8", + "runOnRequirements": [ + { + "csfle": true + } + ], + "createEntities": [ + { + "client": { + "id": "client0", + "observeEvents": [ + "commandStartedEvent" + ] + } + }, + { + "clientEncryption": { + "id": "clientEncryption0", + "clientEncryptionOpts": { + "keyVaultClient": "client0", + "keyVaultNamespace": "keyvault.datakeys", + "kmsProviders": { + "local": { + "key": { + "$$placeholder": 1 + } + } + } + } + } + }, + { + "database": { + "id": "database0", + "client": "client0", + "databaseName": "keyvault" + } + }, + { + "collection": { + "id": "collection0", + "database": "database0", + "collectionName": "datakeys" + } + } + ], + "initialData": [ + { + "databaseName": "keyvault", + "collectionName": "datakeys", + "documents": [ + { + "_id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + }, + "keyAltNames": [ + "alternate_name", + "local_key" + ], + "keyMaterial": { + "$binary": { + "base64": "ABKBldDEoDW323yejOnIRk6YQmlD9d3eQthd16scKL75nz2LjNL9fgPDZWrFFOlqlhMCFaSrNJfGrFUjYk5JFDO7soG5Syb50k1niJoKg4ilsj0L4mpimFUtTpOr2nzZOeQtvAksEXc7gsFgq8gV7t/U3lsaXPY7I0t42DfSE8EGlPdxRjFdHnxh+OR8h7U9b8Qs5K5UuhgyeyxaBZ1Hgw==", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "status": 1, + "masterKey": { + "provider": "local" + } + } + ] + } + ], + "tests": [ + { + "description": "remove keyAltName from non-existent data key", + "operations": [ + { + "name": "removeKeyAltName", + "object": "clientEncryption0", + "arguments": { + "id": { + "$binary": { + "base64": "AAAjYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + }, + "keyAltName": "does_not_exist" + }, + "expectResult": { + "$$unsetOrMatches": null + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "findAndModify": "datakeys", + "query": { + "_id": { + "$binary": { + "base64": "AAAjYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + } + }, + "update": [ + { + "$set": { + "keyAltNames": { + "$cond": [ + { + "$eq": [ + "$keyAltNames", + [ + "does_not_exist" + ] + ] + }, + "$$REMOVE", + { + "$filter": { + "input": "$keyAltNames", + "cond": { + "$ne": [ + "$$this", + "does_not_exist" + ] + } + } + } + ] + } + } + } + ], + "writeConcern": { + "w": "majority" + } + } + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "datakeys", + "databaseName": "keyvault", + "documents": [ + { + "_id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + }, + "keyAltNames": [ + "alternate_name", + "local_key" + ], + "keyMaterial": { + "$binary": { + "base64": "ABKBldDEoDW323yejOnIRk6YQmlD9d3eQthd16scKL75nz2LjNL9fgPDZWrFFOlqlhMCFaSrNJfGrFUjYk5JFDO7soG5Syb50k1niJoKg4ilsj0L4mpimFUtTpOr2nzZOeQtvAksEXc7gsFgq8gV7t/U3lsaXPY7I0t42DfSE8EGlPdxRjFdHnxh+OR8h7U9b8Qs5K5UuhgyeyxaBZ1Hgw==", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "status": 1, + "masterKey": { + "provider": "local" + } + } + ] + } + ] + }, + { + "description": "remove non-existent keyAltName from existing data key", + "operations": [ + { + "name": "removeKeyAltName", + "object": "clientEncryption0", + "arguments": { + "id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + }, + "keyAltName": "does_not_exist" + }, + "expectResult": { + "_id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + }, + "keyAltNames": [ + "alternate_name", + "local_key" + ], + "keyMaterial": { + "$binary": { + "base64": "ABKBldDEoDW323yejOnIRk6YQmlD9d3eQthd16scKL75nz2LjNL9fgPDZWrFFOlqlhMCFaSrNJfGrFUjYk5JFDO7soG5Syb50k1niJoKg4ilsj0L4mpimFUtTpOr2nzZOeQtvAksEXc7gsFgq8gV7t/U3lsaXPY7I0t42DfSE8EGlPdxRjFdHnxh+OR8h7U9b8Qs5K5UuhgyeyxaBZ1Hgw==", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "status": 1, + "masterKey": { + "provider": "local" + } + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "findAndModify": "datakeys", + "query": { + "_id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + } + }, + "update": [ + { + "$set": { + "keyAltNames": { + "$cond": [ + { + "$eq": [ + "$keyAltNames", + [ + "does_not_exist" + ] + ] + }, + "$$REMOVE", + { + "$filter": { + "input": "$keyAltNames", + "cond": { + "$ne": [ + "$$this", + "does_not_exist" + ] + } + } + } + ] + } + } + } + ], + "writeConcern": { + "w": "majority" + } + } + } + } + ] + } + ], + "outcome": [ + { + "collectionName": "datakeys", + "databaseName": "keyvault", + "documents": [ + { + "_id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + }, + "keyAltNames": [ + "alternate_name", + "local_key" + ], + "keyMaterial": { + "$binary": { + "base64": "ABKBldDEoDW323yejOnIRk6YQmlD9d3eQthd16scKL75nz2LjNL9fgPDZWrFFOlqlhMCFaSrNJfGrFUjYk5JFDO7soG5Syb50k1niJoKg4ilsj0L4mpimFUtTpOr2nzZOeQtvAksEXc7gsFgq8gV7t/U3lsaXPY7I0t42DfSE8EGlPdxRjFdHnxh+OR8h7U9b8Qs5K5UuhgyeyxaBZ1Hgw==", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "status": 1, + "masterKey": { + "provider": "local" + } + } + ] + } + ] + }, + { + "description": "remove an existing keyAltName from an existing data key", + "operations": [ + { + "name": "removeKeyAltName", + "object": "clientEncryption0", + "arguments": { + "id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + }, + "keyAltName": "alternate_name" + }, + "expectResult": { + "_id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + }, + "keyAltNames": [ + "alternate_name", + "local_key" + ], + "keyMaterial": { + "$binary": { + "base64": "ABKBldDEoDW323yejOnIRk6YQmlD9d3eQthd16scKL75nz2LjNL9fgPDZWrFFOlqlhMCFaSrNJfGrFUjYk5JFDO7soG5Syb50k1niJoKg4ilsj0L4mpimFUtTpOr2nzZOeQtvAksEXc7gsFgq8gV7t/U3lsaXPY7I0t42DfSE8EGlPdxRjFdHnxh+OR8h7U9b8Qs5K5UuhgyeyxaBZ1Hgw==", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "status": 1, + "masterKey": { + "provider": "local" + } + } + }, + { + "name": "find", + "object": "collection0", + "arguments": { + "filter": {}, + "projection": { + "_id": 0, + "keyAltNames": 1 + } + }, + "expectResult": [ + { + "keyAltNames": [ + "local_key" + ] + } + ] + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "findAndModify": "datakeys", + "query": { + "_id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + } + }, + "update": [ + { + "$set": { + "keyAltNames": { + "$cond": [ + { + "$eq": [ + "$keyAltNames", + [ + "alternate_name" + ] + ] + }, + "$$REMOVE", + { + "$filter": { + "input": "$keyAltNames", + "cond": { + "$ne": [ + "$$this", + "alternate_name" + ] + } + } + } + ] + } + } + } + ], + "writeConcern": { + "w": "majority" + } + } + } + }, + { + "commandStartedEvent": { + "commandName": "find" + } + } + ] + } + ] + }, + { + "description": "remove the last keyAltName from an existing data key", + "operations": [ + { + "name": "removeKeyAltName", + "object": "clientEncryption0", + "arguments": { + "id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + }, + "keyAltName": "alternate_name" + }, + "expectResult": { + "_id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + }, + "keyAltNames": [ + "alternate_name", + "local_key" + ], + "keyMaterial": { + "$binary": { + "base64": "ABKBldDEoDW323yejOnIRk6YQmlD9d3eQthd16scKL75nz2LjNL9fgPDZWrFFOlqlhMCFaSrNJfGrFUjYk5JFDO7soG5Syb50k1niJoKg4ilsj0L4mpimFUtTpOr2nzZOeQtvAksEXc7gsFgq8gV7t/U3lsaXPY7I0t42DfSE8EGlPdxRjFdHnxh+OR8h7U9b8Qs5K5UuhgyeyxaBZ1Hgw==", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "status": 1, + "masterKey": { + "provider": "local" + } + } + }, + { + "name": "removeKeyAltName", + "object": "clientEncryption0", + "arguments": { + "id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + }, + "keyAltName": "local_key" + }, + "expectResult": { + "_id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + }, + "keyAltNames": [ + "local_key" + ], + "keyMaterial": { + "$$type": "binData" + }, + "creationDate": { + "$$type": "date" + }, + "updateDate": { + "$$type": "date" + }, + "status": 1, + "masterKey": { + "provider": "local" + } + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "findAndModify": "datakeys", + "query": { + "_id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + } + }, + "update": [ + { + "$set": { + "keyAltNames": { + "$cond": [ + { + "$eq": [ + "$keyAltNames", + [ + "alternate_name" + ] + ] + }, + "$$REMOVE", + { + "$filter": { + "input": "$keyAltNames", + "cond": { + "$ne": [ + "$$this", + "alternate_name" + ] + } + } + } + ] + } + } + } + ], + "writeConcern": { + "w": "majority" + } + } + } + }, + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "findAndModify": "datakeys", + "query": { + "_id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + } + }, + "update": [ + { + "$set": { + "keyAltNames": { + "$cond": [ + { + "$eq": [ + "$keyAltNames", + [ + "local_key" + ] + ] + }, + "$$REMOVE", + { + "$filter": { + "input": "$keyAltNames", + "cond": { + "$ne": [ + "$$this", + "local_key" + ] + } + } + } + ] + } + } + } + ] + } + } + } + ] + } + ] + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/unified/removeKeyAltName.yml b/src/test/spec/json/client-side-encryption/unified/removeKeyAltName.yml new file mode 100644 index 000000000..02394609b --- /dev/null +++ b/src/test/spec/json/client-side-encryption/unified/removeKeyAltName.yml @@ -0,0 +1,157 @@ +description: removeKeyAltName + +schemaVersion: "1.8" + +runOnRequirements: + - csfle: true + +createEntities: + - client: + id: &client0 client0 + observeEvents: + - commandStartedEvent + - clientEncryption: + id: &clientEncryption0 clientEncryption0 + clientEncryptionOpts: + keyVaultClient: *client0 + keyVaultNamespace: keyvault.datakeys + kmsProviders: + local: { key: { $$placeholder: 1 } } + - database: + id: &database0 database0 + client: *client0 + databaseName: &database0Name keyvault + - collection: + id: &collection0 collection0 + database: *database0 + collectionName: &collection0Name datakeys + +initialData: + - databaseName: *database0Name + collectionName: *collection0Name + documents: + - &local_key_doc + _id: &local_key_id { $binary: { base64: bG9jYWxrZXlsb2NhbGtleQ==, subType: "04" } } + keyAltNames: [alternate_name, local_key] + keyMaterial: { $binary: { base64: ABKBldDEoDW323yejOnIRk6YQmlD9d3eQthd16scKL75nz2LjNL9fgPDZWrFFOlqlhMCFaSrNJfGrFUjYk5JFDO7soG5Syb50k1niJoKg4ilsj0L4mpimFUtTpOr2nzZOeQtvAksEXc7gsFgq8gV7t/U3lsaXPY7I0t42DfSE8EGlPdxRjFdHnxh+OR8h7U9b8Qs5K5UuhgyeyxaBZ1Hgw==, subType: "00" } } + creationDate: { $date: { $numberLong: "1641024000000" } } + updateDate: { $date: { $numberLong: "1641024000000" } } + status: 1 + masterKey: + provider: local + +tests: + - description: remove keyAltName from non-existent data key + operations: + - name: removeKeyAltName + object: *clientEncryption0 + arguments: + # First 3 letters of local_key_id replaced with 'A' (value: "#alkeylocalkey"). + id: &non_existent_id { $binary: { base64: AAAjYWxrZXlsb2NhbGtleQ==, subType: "04" } } + keyAltName: does_not_exist + expectResult: { $$unsetOrMatches: null } + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + databaseName: *database0Name + command: + findAndModify: *collection0Name + query: { _id: *non_existent_id } + update: [{ $set: { keyAltNames: { $cond: [{ $eq: [$keyAltNames, [does_not_exist]] }, $$REMOVE, { $filter: { input: $keyAltNames, cond: { $ne: [$$this, does_not_exist] } } }] } } }] + writeConcern: { w: majority } + outcome: + - collectionName: *collection0Name + databaseName: *database0Name + documents: + - *local_key_doc + + - description: remove non-existent keyAltName from existing data key + operations: + - name: removeKeyAltName + object: *clientEncryption0 + arguments: + id: *local_key_id + keyAltName: does_not_exist + expectResult: *local_key_doc + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + databaseName: *database0Name + command: + findAndModify: *collection0Name + query: { _id: *local_key_id } + update: [{ $set: { keyAltNames: { $cond: [{ $eq: [$keyAltNames, [does_not_exist]] }, $$REMOVE, { $filter: { input: $keyAltNames, cond: { $ne: [$$this, does_not_exist] } } }] } } }] + writeConcern: { w: majority } + outcome: + - collectionName: *collection0Name + databaseName: *database0Name + documents: + - *local_key_doc + + - description: remove an existing keyAltName from an existing data key + operations: + - name: removeKeyAltName + object: *clientEncryption0 + arguments: + id: *local_key_id + keyAltName: alternate_name + expectResult: *local_key_doc + - name: find + object: *collection0 + arguments: + filter: {} + projection: { _id: 0, keyAltNames: 1 } + expectResult: + - keyAltNames: [local_key] + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + databaseName: *database0Name + command: + findAndModify: *collection0Name + query: { _id: *local_key_id } + update: [{ $set: { keyAltNames: { $cond: [{ $eq: [$keyAltNames, [alternate_name]] }, $$REMOVE, { $filter: { input: $keyAltNames, cond: { $ne: [$$this, alternate_name] } } }] } } }] + writeConcern: { w: majority } + - commandStartedEvent: { commandName: find } + + - description: remove the last keyAltName from an existing data key + operations: + - name: removeKeyAltName + object: *clientEncryption0 + arguments: + id: *local_key_id + keyAltName: alternate_name + expectResult: *local_key_doc + - name: removeKeyAltName + object: *clientEncryption0 + arguments: + id: *local_key_id + keyAltName: local_key + expectResult: + _id: *local_key_id + keyAltNames: [local_key] + keyMaterial: { $$type: binData } + creationDate: { $$type: date } + updateDate: { $$type: date } + status: 1 + masterKey: + provider: local + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + databaseName: *database0Name + command: + findAndModify: *collection0Name + query: { _id: *local_key_id } + update: [{ $set: { keyAltNames: { $cond: [{ $eq: [$keyAltNames, [alternate_name]] }, $$REMOVE, { $filter: { input: $keyAltNames, cond: { $ne: [$$this, alternate_name] } } }] } } }] + writeConcern: { w: majority } + - commandStartedEvent: + databaseName: *database0Name + command: + findAndModify: *collection0Name + query: { _id: *local_key_id } + update: [{ $set: { keyAltNames: { $cond: [{ $eq: [$keyAltNames, [local_key]] }, $$REMOVE, { $filter: { input: $keyAltNames, cond: { $ne: [$$this, local_key] } } }] } } }] diff --git a/src/test/spec/json/client-side-encryption/unified/rewrapManyDataKey-decrypt_failure.json b/src/test/spec/json/client-side-encryption/unified/rewrapManyDataKey-decrypt_failure.json new file mode 100644 index 000000000..4c7d4e804 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/unified/rewrapManyDataKey-decrypt_failure.json @@ -0,0 +1,162 @@ +{ + "description": "rewrapManyDataKey-decrypt_failure", + "schemaVersion": "1.8", + "runOnRequirements": [ + { + "csfle": true + } + ], + "createEntities": [ + { + "client": { + "id": "client0", + "observeEvents": [ + "commandStartedEvent" + ] + } + }, + { + "clientEncryption": { + "id": "clientEncryption0", + "clientEncryptionOpts": { + "keyVaultClient": "client0", + "keyVaultNamespace": "keyvault.datakeys", + "kmsProviders": { + "aws": { + "accessKeyId": { + "$$placeholder": 1 + }, + "secretAccessKey": { + "$$placeholder": 1 + } + }, + "azure": { + "tenantId": { + "$$placeholder": 1 + }, + "clientId": { + "$$placeholder": 1 + }, + "clientSecret": { + "$$placeholder": 1 + } + }, + "gcp": { + "email": { + "$$placeholder": 1 + }, + "privateKey": { + "$$placeholder": 1 + } + }, + "kmip": { + "endpoint": { + "$$placeholder": 1 + } + }, + "local": { + "key": { + "$$placeholder": 1 + } + } + } + } + } + }, + { + "database": { + "id": "database0", + "client": "client0", + "databaseName": "keyvault" + } + }, + { + "collection": { + "id": "collection0", + "database": "database0", + "collectionName": "datakeys" + } + } + ], + "initialData": [ + { + "databaseName": "keyvault", + "collectionName": "datakeys", + "documents": [ + { + "_id": { + "$binary": { + "base64": "YXdzYXdzYXdzYXdzYXdzYQ==", + "subType": "04" + } + }, + "keyAltNames": [ + "aws_key" + ], + "keyMaterial": { + "$binary": { + "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gFXJqbF0Fy872MD7xl56D/2AAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDO7HPisPUlGzaio9vgIBEIB7/Qow46PMh/8JbEUbdXgTGhLfXPE+KIVW7T8s6YEMlGiRvMu7TV0QCIUJlSHPKZxzlJ2iwuz5yXeOag+EdY+eIQ0RKrsJ3b8UTisZYzGjfzZnxUKLzLoeXremtRCm3x47wCuHKd1dhh6FBbYt5TL2tDaj+vL2GBrKat2L", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "status": 1, + "masterKey": { + "provider": "aws", + "key": "arn:aws:kms:us-east-2:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "region": "us-east-2" + } + } + ] + } + ], + "tests": [ + { + "description": "rewrap data key that fails during decryption due to invalid masterKey", + "operations": [ + { + "name": "rewrapManyDataKey", + "object": "clientEncryption0", + "arguments": { + "filter": {}, + "opts": { + "provider": "local" + } + }, + "expectError": { + "isClientError": true + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "commandName": "find", + "databaseName": "keyvault", + "command": { + "find": "datakeys", + "filter": {}, + "readConcern": { + "level": "majority" + } + } + } + } + ] + } + ] + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/unified/rewrapManyDataKey-decrypt_failure.yml b/src/test/spec/json/client-side-encryption/unified/rewrapManyDataKey-decrypt_failure.yml new file mode 100644 index 000000000..3a6e52188 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/unified/rewrapManyDataKey-decrypt_failure.yml @@ -0,0 +1,69 @@ +description: rewrapManyDataKey-decrypt_failure + +schemaVersion: "1.8" + +runOnRequirements: + - csfle: true + +createEntities: + - client: + id: &client0 client0 + observeEvents: + - commandStartedEvent + - clientEncryption: + id: &clientEncryption0 clientEncryption0 + clientEncryptionOpts: + keyVaultClient: *client0 + keyVaultNamespace: keyvault.datakeys + kmsProviders: + aws: { accessKeyId: { $$placeholder: 1 }, secretAccessKey: { $$placeholder: 1 } } + azure: { tenantId: { $$placeholder: 1 }, clientId: { $$placeholder: 1 }, clientSecret: { $$placeholder: 1 } } + gcp: { email: { $$placeholder: 1 }, privateKey: { $$placeholder: 1 } } + kmip: { endpoint: { $$placeholder: 1 } } + local: { key: { $$placeholder: 1 } } + - database: + id: &database0 database0 + client: *client0 + databaseName: &database0Name keyvault + - collection: + id: &collection0 collection0 + database: *database0 + collectionName: &collection0Name datakeys + +initialData: + - databaseName: *database0Name + collectionName: *collection0Name + documents: + - _id: { $binary: { base64: YXdzYXdzYXdzYXdzYXdzYQ==, subType: "04" } } + keyAltNames: ["aws_key"] + keyMaterial: { $binary: { base64: AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gFXJqbF0Fy872MD7xl56D/2AAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDO7HPisPUlGzaio9vgIBEIB7/Qow46PMh/8JbEUbdXgTGhLfXPE+KIVW7T8s6YEMlGiRvMu7TV0QCIUJlSHPKZxzlJ2iwuz5yXeOag+EdY+eIQ0RKrsJ3b8UTisZYzGjfzZnxUKLzLoeXremtRCm3x47wCuHKd1dhh6FBbYt5TL2tDaj+vL2GBrKat2L, subType: "00" } } + creationDate: { $date: { $numberLong: "1641024000000" } } + updateDate: { $date: { $numberLong: "1641024000000" } } + status: 1 + masterKey: + provider: aws + # "us-east-1" changed to "us-east-2" in both key and region. + key: arn:aws:kms:us-east-2:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0 + region: us-east-2 + +tests: + - description: "rewrap data key that fails during decryption due to invalid masterKey" + operations: + - name: rewrapManyDataKey + object: *clientEncryption0 + arguments: + filter: {} + opts: + provider: local + expectError: + isClientError: true + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + commandName: find + databaseName: *database0Name + command: + find: *collection0Name + filter: {} + readConcern: { level: majority } diff --git a/src/test/spec/json/client-side-encryption/unified/rewrapManyDataKey-encrypt_failure.json b/src/test/spec/json/client-side-encryption/unified/rewrapManyDataKey-encrypt_failure.json new file mode 100644 index 000000000..cd2d20c25 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/unified/rewrapManyDataKey-encrypt_failure.json @@ -0,0 +1,250 @@ +{ + "description": "rewrapManyDataKey-encrypt_failure", + "schemaVersion": "1.8", + "runOnRequirements": [ + { + "csfle": true + } + ], + "createEntities": [ + { + "client": { + "id": "client0", + "observeEvents": [ + "commandStartedEvent" + ] + } + }, + { + "clientEncryption": { + "id": "clientEncryption0", + "clientEncryptionOpts": { + "keyVaultClient": "client0", + "keyVaultNamespace": "keyvault.datakeys", + "kmsProviders": { + "aws": { + "accessKeyId": { + "$$placeholder": 1 + }, + "secretAccessKey": { + "$$placeholder": 1 + } + }, + "azure": { + "tenantId": { + "$$placeholder": 1 + }, + "clientId": { + "$$placeholder": 1 + }, + "clientSecret": { + "$$placeholder": 1 + } + }, + "gcp": { + "email": { + "$$placeholder": 1 + }, + "privateKey": { + "$$placeholder": 1 + } + }, + "kmip": { + "endpoint": { + "$$placeholder": 1 + } + }, + "local": { + "key": { + "$$placeholder": 1 + } + } + } + } + } + }, + { + "database": { + "id": "database0", + "client": "client0", + "databaseName": "keyvault" + } + }, + { + "collection": { + "id": "collection0", + "database": "database0", + "collectionName": "datakeys" + } + } + ], + "initialData": [ + { + "databaseName": "keyvault", + "collectionName": "datakeys", + "documents": [ + { + "_id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + }, + "keyAltNames": [ + "local_key" + ], + "keyMaterial": { + "$binary": { + "base64": "ABKBldDEoDW323yejOnIRk6YQmlD9d3eQthd16scKL75nz2LjNL9fgPDZWrFFOlqlhMCFaSrNJfGrFUjYk5JFDO7soG5Syb50k1niJoKg4ilsj0L4mpimFUtTpOr2nzZOeQtvAksEXc7gsFgq8gV7t/U3lsaXPY7I0t42DfSE8EGlPdxRjFdHnxh+OR8h7U9b8Qs5K5UuhgyeyxaBZ1Hgw==", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "status": 1, + "masterKey": { + "provider": "local" + } + } + ] + } + ], + "tests": [ + { + "description": "rewrap with invalid masterKey for AWS KMS provider", + "operations": [ + { + "name": "rewrapManyDataKey", + "object": "clientEncryption0", + "arguments": { + "filter": {}, + "opts": { + "provider": "aws", + "masterKey": { + "key": "arn:aws:kms:us-east-2:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "region": "us-east-2" + } + } + }, + "expectError": { + "isClientError": true + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "commandName": "find", + "databaseName": "keyvault", + "command": { + "find": "datakeys", + "filter": {}, + "readConcern": { + "level": "majority" + } + } + } + } + ] + } + ] + }, + { + "description": "rewrap with invalid masterKey for Azure KMS provider", + "operations": [ + { + "name": "rewrapManyDataKey", + "object": "clientEncryption0", + "arguments": { + "filter": {}, + "opts": { + "provider": "azure", + "masterKey": { + "keyVaultEndpoint": "invalid-vault-csfle.vault.azure.net", + "keyName": "invalid-name-csfle" + } + } + }, + "expectError": { + "isClientError": true + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "commandName": "find", + "databaseName": "keyvault", + "command": { + "find": "datakeys", + "filter": {}, + "readConcern": { + "level": "majority" + } + } + } + } + ] + } + ] + }, + { + "description": "rewrap with invalid masterKey for GCP KMS provider", + "operations": [ + { + "name": "rewrapManyDataKey", + "object": "clientEncryption0", + "arguments": { + "filter": {}, + "opts": { + "provider": "gcp", + "masterKey": { + "projectId": "devprod-drivers", + "location": "global", + "keyRing": "invalid-ring-csfle", + "keyName": "invalid-name-csfle" + } + } + }, + "expectError": { + "isClientError": true + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "commandName": "find", + "databaseName": "keyvault", + "command": { + "find": "datakeys", + "filter": {}, + "readConcern": { + "level": "majority" + } + } + } + } + ] + } + ] + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/unified/rewrapManyDataKey-encrypt_failure.yml b/src/test/spec/json/client-side-encryption/unified/rewrapManyDataKey-encrypt_failure.yml new file mode 100644 index 000000000..b947c8ce7 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/unified/rewrapManyDataKey-encrypt_failure.yml @@ -0,0 +1,122 @@ +description: rewrapManyDataKey-encrypt_failure + +schemaVersion: "1.8" + +runOnRequirements: + - csfle: true + +createEntities: + - client: + id: &client0 client0 + observeEvents: + - commandStartedEvent + - clientEncryption: + id: &clientEncryption0 clientEncryption0 + clientEncryptionOpts: + keyVaultClient: *client0 + keyVaultNamespace: keyvault.datakeys + kmsProviders: + aws: { accessKeyId: { $$placeholder: 1 }, secretAccessKey: { $$placeholder: 1 } } + azure: { tenantId: { $$placeholder: 1 }, clientId: { $$placeholder: 1 }, clientSecret: { $$placeholder: 1 } } + gcp: { email: { $$placeholder: 1 }, privateKey: { $$placeholder: 1 } } + kmip: { endpoint: { $$placeholder: 1 } } + local: { key: { $$placeholder: 1 } } + - database: + id: &database0 database0 + client: *client0 + databaseName: &database0Name keyvault + - collection: + id: &collection0 collection0 + database: *database0 + collectionName: &collection0Name datakeys + +initialData: + - databaseName: *database0Name + collectionName: *collection0Name + documents: + - _id: { $binary: { base64: bG9jYWxrZXlsb2NhbGtleQ==, subType: "04" } } + keyAltNames: ["local_key"] + keyMaterial: { $binary: { base64: ABKBldDEoDW323yejOnIRk6YQmlD9d3eQthd16scKL75nz2LjNL9fgPDZWrFFOlqlhMCFaSrNJfGrFUjYk5JFDO7soG5Syb50k1niJoKg4ilsj0L4mpimFUtTpOr2nzZOeQtvAksEXc7gsFgq8gV7t/U3lsaXPY7I0t42DfSE8EGlPdxRjFdHnxh+OR8h7U9b8Qs5K5UuhgyeyxaBZ1Hgw==, subType: "00" } } + creationDate: { $date: { $numberLong: "1641024000000" } } + updateDate: { $date: { $numberLong: "1641024000000" } } + status: 1 + masterKey: + provider: local + +tests: + - description: "rewrap with invalid masterKey for AWS KMS provider" + operations: + - name: rewrapManyDataKey + object: *clientEncryption0 + arguments: + filter: {} + opts: + provider: aws + masterKey: + # "us-east-1" changed to "us-east-2" in both key and region. + key: arn:aws:kms:us-east-2:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0 + region: us-east-2 + expectError: + isClientError: true + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + commandName: find + databaseName: *database0Name + command: + find: *collection0Name + filter: {} + readConcern: { level: majority } + + - description: "rewrap with invalid masterKey for Azure KMS provider" + operations: + - name: rewrapManyDataKey + object: *clientEncryption0 + arguments: + filter: {} + opts: + provider: azure + masterKey: + # "key" changed to "invalid" in both keyVaultEndpoint and keyName. + keyVaultEndpoint: invalid-vault-csfle.vault.azure.net + keyName: invalid-name-csfle + expectError: + isClientError: true + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + commandName: find + databaseName: *database0Name + command: + find: *collection0Name + filter: {} + readConcern: { level: majority } + + - description: "rewrap with invalid masterKey for GCP KMS provider" + operations: + - name: rewrapManyDataKey + object: *clientEncryption0 + arguments: + filter: {} + opts: + provider: gcp + masterKey: + # "key" changed to "invalid" in both keyRing and keyName. + projectId: devprod-drivers + location: global + keyRing: invalid-ring-csfle + keyName: invalid-name-csfle + expectError: + isClientError: true + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + commandName: find + databaseName: *database0Name + command: + find: *collection0Name + filter: {} + readConcern: { level: majority } diff --git a/src/test/spec/json/client-side-encryption/unified/rewrapManyDataKey.json b/src/test/spec/json/client-side-encryption/unified/rewrapManyDataKey.json new file mode 100644 index 000000000..89860de0c --- /dev/null +++ b/src/test/spec/json/client-side-encryption/unified/rewrapManyDataKey.json @@ -0,0 +1,1475 @@ +{ + "description": "rewrapManyDataKey", + "schemaVersion": "1.8", + "runOnRequirements": [ + { + "csfle": true + } + ], + "createEntities": [ + { + "client": { + "id": "client0", + "observeEvents": [ + "commandStartedEvent" + ] + } + }, + { + "clientEncryption": { + "id": "clientEncryption0", + "clientEncryptionOpts": { + "keyVaultClient": "client0", + "keyVaultNamespace": "keyvault.datakeys", + "kmsProviders": { + "aws": { + "accessKeyId": { + "$$placeholder": 1 + }, + "secretAccessKey": { + "$$placeholder": 1 + } + }, + "azure": { + "tenantId": { + "$$placeholder": 1 + }, + "clientId": { + "$$placeholder": 1 + }, + "clientSecret": { + "$$placeholder": 1 + } + }, + "gcp": { + "email": { + "$$placeholder": 1 + }, + "privateKey": { + "$$placeholder": 1 + } + }, + "kmip": { + "endpoint": { + "$$placeholder": 1 + } + }, + "local": { + "key": { + "$$placeholder": 1 + } + } + } + } + } + }, + { + "database": { + "id": "database0", + "client": "client0", + "databaseName": "keyvault" + } + }, + { + "collection": { + "id": "collection0", + "database": "database0", + "collectionName": "datakeys" + } + } + ], + "initialData": [ + { + "databaseName": "keyvault", + "collectionName": "datakeys", + "documents": [ + { + "_id": { + "$binary": { + "base64": "YXdzYXdzYXdzYXdzYXdzYQ==", + "subType": "04" + } + }, + "keyAltNames": [ + "aws_key" + ], + "keyMaterial": { + "$binary": { + "base64": "AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gFXJqbF0Fy872MD7xl56D/2AAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDO7HPisPUlGzaio9vgIBEIB7/Qow46PMh/8JbEUbdXgTGhLfXPE+KIVW7T8s6YEMlGiRvMu7TV0QCIUJlSHPKZxzlJ2iwuz5yXeOag+EdY+eIQ0RKrsJ3b8UTisZYzGjfzZnxUKLzLoeXremtRCm3x47wCuHKd1dhh6FBbYt5TL2tDaj+vL2GBrKat2L", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "status": 1, + "masterKey": { + "provider": "aws", + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "region": "us-east-1" + } + }, + { + "_id": { + "$binary": { + "base64": "YXp1cmVhenVyZWF6dXJlYQ==", + "subType": "04" + } + }, + "keyAltNames": [ + "azure_key" + ], + "keyMaterial": { + "$binary": { + "base64": "pr01l7qDygUkFE/0peFwpnNlv3iIy8zrQK38Q9i12UCN2jwZHDmfyx8wokiIKMb9kAleeY+vnt3Cf1MKu9kcDmI+KxbNDd+V3ytAAGzOVLDJr77CiWjF9f8ntkXRHrAY9WwnVDANYkDwXlyU0Y2GQFTiW65jiQhUtYLYH63Tk48SsJuQvnWw1Q+PzY8ga+QeVec8wbcThwtm+r2IHsCFnc72Gv73qq7weISw+O4mN08z3wOp5FOS2ZM3MK7tBGmPdBcktW7F8ODGsOQ1FU53OrWUnyX2aTi2ftFFFMWVHqQo7EYuBZHru8RRODNKMyQk0BFfKovAeTAVRv9WH9QU7g==", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "status": 1, + "masterKey": { + "provider": "azure", + "keyVaultEndpoint": "key-vault-csfle.vault.azure.net", + "keyName": "key-name-csfle" + } + }, + { + "_id": { + "$binary": { + "base64": "Z2NwZ2NwZ2NwZ2NwZ2NwZw==", + "subType": "04" + } + }, + "keyAltNames": [ + "gcp_key" + ], + "keyMaterial": { + "$binary": { + "base64": "CiQAIgLj0USbQtof/pYRLQO96yg/JEtZbD1UxKueaC37yzT5tTkSiQEAhClWB5ZCSgzHgxv8raWjNB4r7e8ePGdsmSuYTYmLC5oHHS/BdQisConzNKFaobEQZHamTCjyhy5NotKF8MWoo+dyfQApwI29+vAGyrUIQCXzKwRnNdNQ+lb3vJtS5bqvLTvSxKHpVca2kqyC9nhonV+u4qru5Q2bAqUgVFc8fL4pBuvlowZFTQ==", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "status": 1, + "masterKey": { + "provider": "gcp", + "projectId": "devprod-drivers", + "location": "global", + "keyRing": "key-ring-csfle", + "keyName": "key-name-csfle" + } + }, + { + "_id": { + "$binary": { + "base64": "a21pcGttaXBrbWlwa21pcA==", + "subType": "04" + } + }, + "keyAltNames": [ + "kmip_key" + ], + "keyMaterial": { + "$binary": { + "base64": "CklVctHzke4mcytd0TxGqvepkdkQN8NUF4+jV7aZQITAKdz6WjdDpq3lMt9nSzWGG2vAEfvRb3mFEVjV57qqGqxjq2751gmiMRHXz0btStbIK3mQ5xbY9kdye4tsixlCryEwQONr96gwlwKKI9Nubl9/8+uRF6tgYjje7Q7OjauEf1SrJwKcoQ3WwnjZmEqAug0kImCpJ/irhdqPzivRiA==", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "status": 1, + "masterKey": { + "provider": "kmip", + "keyId": "1" + } + }, + { + "_id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + }, + "keyAltNames": [ + "local_key" + ], + "keyMaterial": { + "$binary": { + "base64": "ABKBldDEoDW323yejOnIRk6YQmlD9d3eQthd16scKL75nz2LjNL9fgPDZWrFFOlqlhMCFaSrNJfGrFUjYk5JFDO7soG5Syb50k1niJoKg4ilsj0L4mpimFUtTpOr2nzZOeQtvAksEXc7gsFgq8gV7t/U3lsaXPY7I0t42DfSE8EGlPdxRjFdHnxh+OR8h7U9b8Qs5K5UuhgyeyxaBZ1Hgw==", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1641024000000" + } + }, + "status": 1, + "masterKey": { + "provider": "local" + } + } + ] + } + ], + "tests": [ + { + "description": "no keys to rewrap due to no filter matches", + "operations": [ + { + "name": "rewrapManyDataKey", + "object": "clientEncryption0", + "arguments": { + "filter": { + "keyAltNames": "no_matching_keys" + }, + "opts": { + "provider": "local" + } + }, + "expectResult": { + "bulkWriteResult": { + "$$exists": false + } + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "find": "datakeys", + "filter": { + "keyAltNames": "no_matching_keys" + }, + "readConcern": { + "level": "majority" + } + } + } + } + ] + } + ] + }, + { + "description": "rewrap with new AWS KMS provider", + "operations": [ + { + "name": "rewrapManyDataKey", + "object": "clientEncryption0", + "arguments": { + "filter": { + "keyAltNames": { + "$ne": "aws_key" + } + }, + "opts": { + "provider": "aws", + "masterKey": { + "key": "arn:aws:kms:us-east-1:579766882180:key/061334ae-07a8-4ceb-a813-8135540e837d", + "region": "us-east-1" + } + } + }, + "expectResult": { + "bulkWriteResult": { + "insertedCount": 0, + "matchedCount": 4, + "modifiedCount": 4, + "deletedCount": 0, + "upsertedCount": 0, + "upsertedIds": {} + } + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "find": "datakeys", + "filter": { + "keyAltNames": { + "$ne": "aws_key" + } + }, + "readConcern": { + "level": "majority" + } + } + } + }, + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "update": "datakeys", + "ordered": true, + "updates": [ + { + "q": { + "_id": { + "$$type": "binData" + } + }, + "u": { + "$set": { + "masterKey": { + "provider": "aws", + "key": "arn:aws:kms:us-east-1:579766882180:key/061334ae-07a8-4ceb-a813-8135540e837d", + "region": "us-east-1" + }, + "keyMaterial": { + "$$type": "binData" + } + }, + "$currentDate": { + "updateDate": true + } + }, + "multi": { + "$$unsetOrMatches": false + }, + "upsert": { + "$$unsetOrMatches": false + } + }, + { + "q": { + "_id": { + "$$type": "binData" + } + }, + "u": { + "$set": { + "masterKey": { + "provider": "aws", + "key": "arn:aws:kms:us-east-1:579766882180:key/061334ae-07a8-4ceb-a813-8135540e837d", + "region": "us-east-1" + }, + "keyMaterial": { + "$$type": "binData" + } + }, + "$currentDate": { + "updateDate": true + } + }, + "multi": { + "$$unsetOrMatches": false + }, + "upsert": { + "$$unsetOrMatches": false + } + }, + { + "q": { + "_id": { + "$$type": "binData" + } + }, + "u": { + "$set": { + "masterKey": { + "provider": "aws", + "key": "arn:aws:kms:us-east-1:579766882180:key/061334ae-07a8-4ceb-a813-8135540e837d", + "region": "us-east-1" + }, + "keyMaterial": { + "$$type": "binData" + } + }, + "$currentDate": { + "updateDate": true + } + }, + "multi": { + "$$unsetOrMatches": false + }, + "upsert": { + "$$unsetOrMatches": false + } + }, + { + "q": { + "_id": { + "$$type": "binData" + } + }, + "u": { + "$set": { + "masterKey": { + "provider": "aws", + "key": "arn:aws:kms:us-east-1:579766882180:key/061334ae-07a8-4ceb-a813-8135540e837d", + "region": "us-east-1" + }, + "keyMaterial": { + "$$type": "binData" + } + }, + "$currentDate": { + "updateDate": true + } + }, + "multi": { + "$$unsetOrMatches": false + }, + "upsert": { + "$$unsetOrMatches": false + } + } + ], + "writeConcern": { + "w": "majority" + } + } + } + } + ] + } + ] + }, + { + "description": "rewrap with new Azure KMS provider", + "operations": [ + { + "name": "rewrapManyDataKey", + "object": "clientEncryption0", + "arguments": { + "filter": { + "keyAltNames": { + "$ne": "azure_key" + } + }, + "opts": { + "provider": "azure", + "masterKey": { + "keyVaultEndpoint": "key-vault-csfle.vault.azure.net", + "keyName": "key-name-csfle" + } + } + }, + "expectResult": { + "bulkWriteResult": { + "insertedCount": 0, + "matchedCount": 4, + "modifiedCount": 4, + "deletedCount": 0, + "upsertedCount": 0, + "upsertedIds": {} + } + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "find": "datakeys", + "filter": { + "keyAltNames": { + "$ne": "azure_key" + } + }, + "readConcern": { + "level": "majority" + } + } + } + }, + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "update": "datakeys", + "ordered": true, + "updates": [ + { + "q": { + "_id": { + "$$type": "binData" + } + }, + "u": { + "$set": { + "masterKey": { + "provider": "azure", + "keyVaultEndpoint": "key-vault-csfle.vault.azure.net", + "keyName": "key-name-csfle" + }, + "keyMaterial": { + "$$type": "binData" + } + }, + "$currentDate": { + "updateDate": true + } + }, + "multi": { + "$$unsetOrMatches": false + }, + "upsert": { + "$$unsetOrMatches": false + } + }, + { + "q": { + "_id": { + "$$type": "binData" + } + }, + "u": { + "$set": { + "masterKey": { + "provider": "azure", + "keyVaultEndpoint": "key-vault-csfle.vault.azure.net", + "keyName": "key-name-csfle" + }, + "keyMaterial": { + "$$type": "binData" + } + }, + "$currentDate": { + "updateDate": true + } + }, + "multi": { + "$$unsetOrMatches": false + }, + "upsert": { + "$$unsetOrMatches": false + } + }, + { + "q": { + "_id": { + "$$type": "binData" + } + }, + "u": { + "$set": { + "masterKey": { + "provider": "azure", + "keyVaultEndpoint": "key-vault-csfle.vault.azure.net", + "keyName": "key-name-csfle" + }, + "keyMaterial": { + "$$type": "binData" + } + }, + "$currentDate": { + "updateDate": true + } + }, + "multi": { + "$$unsetOrMatches": false + }, + "upsert": { + "$$unsetOrMatches": false + } + }, + { + "q": { + "_id": { + "$$type": "binData" + } + }, + "u": { + "$set": { + "masterKey": { + "provider": "azure", + "keyVaultEndpoint": "key-vault-csfle.vault.azure.net", + "keyName": "key-name-csfle" + }, + "keyMaterial": { + "$$type": "binData" + } + }, + "$currentDate": { + "updateDate": true + } + }, + "multi": { + "$$unsetOrMatches": false + }, + "upsert": { + "$$unsetOrMatches": false + } + } + ], + "writeConcern": { + "w": "majority" + } + } + } + } + ] + } + ] + }, + { + "description": "rewrap with new GCP KMS provider", + "operations": [ + { + "name": "rewrapManyDataKey", + "object": "clientEncryption0", + "arguments": { + "filter": { + "keyAltNames": { + "$ne": "gcp_key" + } + }, + "opts": { + "provider": "gcp", + "masterKey": { + "projectId": "devprod-drivers", + "location": "global", + "keyRing": "key-ring-csfle", + "keyName": "key-name-csfle" + } + } + }, + "expectResult": { + "bulkWriteResult": { + "insertedCount": 0, + "matchedCount": 4, + "modifiedCount": 4, + "deletedCount": 0, + "upsertedCount": 0, + "upsertedIds": {} + } + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "find": "datakeys", + "filter": { + "keyAltNames": { + "$ne": "gcp_key" + } + }, + "readConcern": { + "level": "majority" + } + } + } + }, + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "update": "datakeys", + "ordered": true, + "updates": [ + { + "q": { + "_id": { + "$$type": "binData" + } + }, + "u": { + "$set": { + "masterKey": { + "provider": "gcp", + "projectId": "devprod-drivers", + "location": "global", + "keyRing": "key-ring-csfle", + "keyName": "key-name-csfle" + }, + "keyMaterial": { + "$$type": "binData" + } + }, + "$currentDate": { + "updateDate": true + } + }, + "multi": { + "$$unsetOrMatches": false + }, + "upsert": { + "$$unsetOrMatches": false + } + }, + { + "q": { + "_id": { + "$$type": "binData" + } + }, + "u": { + "$set": { + "masterKey": { + "provider": "gcp", + "projectId": "devprod-drivers", + "location": "global", + "keyRing": "key-ring-csfle", + "keyName": "key-name-csfle" + }, + "keyMaterial": { + "$$type": "binData" + } + }, + "$currentDate": { + "updateDate": true + } + }, + "multi": { + "$$unsetOrMatches": false + }, + "upsert": { + "$$unsetOrMatches": false + } + }, + { + "q": { + "_id": { + "$$type": "binData" + } + }, + "u": { + "$set": { + "masterKey": { + "provider": "gcp", + "projectId": "devprod-drivers", + "location": "global", + "keyRing": "key-ring-csfle", + "keyName": "key-name-csfle" + }, + "keyMaterial": { + "$$type": "binData" + } + }, + "$currentDate": { + "updateDate": true + } + }, + "multi": { + "$$unsetOrMatches": false + }, + "upsert": { + "$$unsetOrMatches": false + } + }, + { + "q": { + "_id": { + "$$type": "binData" + } + }, + "u": { + "$set": { + "masterKey": { + "provider": "gcp", + "projectId": "devprod-drivers", + "location": "global", + "keyRing": "key-ring-csfle", + "keyName": "key-name-csfle" + }, + "keyMaterial": { + "$$type": "binData" + } + }, + "$currentDate": { + "updateDate": true + } + }, + "multi": { + "$$unsetOrMatches": false + }, + "upsert": { + "$$unsetOrMatches": false + } + } + ], + "writeConcern": { + "w": "majority" + } + } + } + } + ] + } + ] + }, + { + "description": "rewrap with new KMIP KMS provider", + "operations": [ + { + "name": "rewrapManyDataKey", + "object": "clientEncryption0", + "arguments": { + "filter": { + "keyAltNames": { + "$ne": "kmip_key" + } + }, + "opts": { + "provider": "kmip" + } + }, + "expectResult": { + "bulkWriteResult": { + "insertedCount": 0, + "matchedCount": 4, + "modifiedCount": 4, + "deletedCount": 0, + "upsertedCount": 0, + "upsertedIds": {} + } + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "find": "datakeys", + "filter": { + "keyAltNames": { + "$ne": "kmip_key" + } + }, + "readConcern": { + "level": "majority" + } + } + } + }, + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "update": "datakeys", + "ordered": true, + "updates": [ + { + "q": { + "_id": { + "$$type": "binData" + } + }, + "u": { + "$set": { + "masterKey": { + "provider": "kmip", + "keyId": { + "$$type": "string" + } + }, + "keyMaterial": { + "$$type": "binData" + } + }, + "$currentDate": { + "updateDate": true + } + }, + "multi": { + "$$unsetOrMatches": false + }, + "upsert": { + "$$unsetOrMatches": false + } + }, + { + "q": { + "_id": { + "$$type": "binData" + } + }, + "u": { + "$set": { + "masterKey": { + "provider": "kmip", + "keyId": { + "$$type": "string" + } + }, + "keyMaterial": { + "$$type": "binData" + } + }, + "$currentDate": { + "updateDate": true + } + }, + "multi": { + "$$unsetOrMatches": false + }, + "upsert": { + "$$unsetOrMatches": false + } + }, + { + "q": { + "_id": { + "$$type": "binData" + } + }, + "u": { + "$set": { + "masterKey": { + "provider": "kmip", + "keyId": { + "$$type": "string" + } + }, + "keyMaterial": { + "$$type": "binData" + } + }, + "$currentDate": { + "updateDate": true + } + }, + "multi": { + "$$unsetOrMatches": false + }, + "upsert": { + "$$unsetOrMatches": false + } + }, + { + "q": { + "_id": { + "$$type": "binData" + } + }, + "u": { + "$set": { + "masterKey": { + "provider": "kmip", + "keyId": { + "$$type": "string" + } + }, + "keyMaterial": { + "$$type": "binData" + } + }, + "$currentDate": { + "updateDate": true + } + }, + "multi": { + "$$unsetOrMatches": false + }, + "upsert": { + "$$unsetOrMatches": false + } + } + ], + "writeConcern": { + "w": "majority" + } + } + } + } + ] + } + ] + }, + { + "description": "rewrap with new local KMS provider", + "operations": [ + { + "name": "rewrapManyDataKey", + "object": "clientEncryption0", + "arguments": { + "filter": { + "keyAltNames": { + "$ne": "local_key" + } + }, + "opts": { + "provider": "local" + } + }, + "expectResult": { + "bulkWriteResult": { + "insertedCount": 0, + "matchedCount": 4, + "modifiedCount": 4, + "deletedCount": 0, + "upsertedCount": 0, + "upsertedIds": {} + } + } + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "find": "datakeys", + "filter": { + "keyAltNames": { + "$ne": "local_key" + } + }, + "readConcern": { + "level": "majority" + } + } + } + }, + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "update": "datakeys", + "ordered": true, + "updates": [ + { + "q": { + "_id": { + "$$type": "binData" + } + }, + "u": { + "$set": { + "masterKey": { + "provider": "local" + }, + "keyMaterial": { + "$$type": "binData" + } + }, + "$currentDate": { + "updateDate": true + } + }, + "multi": { + "$$unsetOrMatches": false + }, + "upsert": { + "$$unsetOrMatches": false + } + }, + { + "q": { + "_id": { + "$$type": "binData" + } + }, + "u": { + "$set": { + "masterKey": { + "provider": "local" + }, + "keyMaterial": { + "$$type": "binData" + } + }, + "$currentDate": { + "updateDate": true + } + }, + "multi": { + "$$unsetOrMatches": false + }, + "upsert": { + "$$unsetOrMatches": false + } + }, + { + "q": { + "_id": { + "$$type": "binData" + } + }, + "u": { + "$set": { + "masterKey": { + "provider": "local" + }, + "keyMaterial": { + "$$type": "binData" + } + }, + "$currentDate": { + "updateDate": true + } + }, + "multi": { + "$$unsetOrMatches": false + }, + "upsert": { + "$$unsetOrMatches": false + } + }, + { + "q": { + "_id": { + "$$type": "binData" + } + }, + "u": { + "$set": { + "masterKey": { + "provider": "local" + }, + "keyMaterial": { + "$$type": "binData" + } + }, + "$currentDate": { + "updateDate": true + } + }, + "multi": { + "$$unsetOrMatches": false + }, + "upsert": { + "$$unsetOrMatches": false + } + } + ], + "writeConcern": { + "w": "majority" + } + } + } + } + ] + } + ] + }, + { + "description": "rewrap with current KMS provider", + "operations": [ + { + "name": "rewrapManyDataKey", + "object": "clientEncryption0", + "arguments": { + "filter": {} + }, + "expectResult": { + "bulkWriteResult": { + "insertedCount": 0, + "matchedCount": 5, + "modifiedCount": 5, + "deletedCount": 0, + "upsertedCount": 0, + "upsertedIds": {} + } + } + }, + { + "name": "find", + "object": "collection0", + "arguments": { + "filter": {}, + "projection": { + "masterKey": 1 + }, + "sort": { + "keyAltNames": 1 + } + }, + "expectResult": [ + { + "_id": { + "$binary": { + "base64": "YXdzYXdzYXdzYXdzYXdzYQ==", + "subType": "04" + } + }, + "masterKey": { + "provider": "aws", + "key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0", + "region": "us-east-1" + } + }, + { + "_id": { + "$binary": { + "base64": "YXp1cmVhenVyZWF6dXJlYQ==", + "subType": "04" + } + }, + "masterKey": { + "provider": "azure", + "keyVaultEndpoint": "key-vault-csfle.vault.azure.net", + "keyName": "key-name-csfle" + } + }, + { + "_id": { + "$binary": { + "base64": "Z2NwZ2NwZ2NwZ2NwZ2NwZw==", + "subType": "04" + } + }, + "masterKey": { + "provider": "gcp", + "projectId": "devprod-drivers", + "location": "global", + "keyRing": "key-ring-csfle", + "keyName": "key-name-csfle" + } + }, + { + "_id": { + "$binary": { + "base64": "a21pcGttaXBrbWlwa21pcA==", + "subType": "04" + } + }, + "masterKey": { + "provider": "kmip", + "keyId": "1" + } + }, + { + "_id": { + "$binary": { + "base64": "bG9jYWxrZXlsb2NhbGtleQ==", + "subType": "04" + } + }, + "masterKey": { + "provider": "local" + } + } + ] + } + ], + "expectEvents": [ + { + "client": "client0", + "events": [ + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "find": "datakeys", + "filter": {}, + "readConcern": { + "level": "majority" + } + } + } + }, + { + "commandStartedEvent": { + "databaseName": "keyvault", + "command": { + "update": "datakeys", + "ordered": true, + "updates": [ + { + "q": { + "_id": { + "$$type": "binData" + } + }, + "u": { + "$set": { + "masterKey": { + "$$type": "object" + }, + "keyMaterial": { + "$$type": "binData" + } + }, + "$currentDate": { + "updateDate": true + } + }, + "multi": { + "$$unsetOrMatches": false + }, + "upsert": { + "$$unsetOrMatches": false + } + }, + { + "q": { + "_id": { + "$$type": "binData" + } + }, + "u": { + "$set": { + "masterKey": { + "$$type": "object" + }, + "keyMaterial": { + "$$type": "binData" + } + }, + "$currentDate": { + "updateDate": true + } + }, + "multi": { + "$$unsetOrMatches": false + }, + "upsert": { + "$$unsetOrMatches": false + } + }, + { + "q": { + "_id": { + "$$type": "binData" + } + }, + "u": { + "$set": { + "masterKey": { + "$$type": "object" + }, + "keyMaterial": { + "$$type": "binData" + } + }, + "$currentDate": { + "updateDate": true + } + }, + "multi": { + "$$unsetOrMatches": false + }, + "upsert": { + "$$unsetOrMatches": false + } + }, + { + "q": { + "_id": { + "$$type": "binData" + } + }, + "u": { + "$set": { + "masterKey": { + "$$type": "object" + }, + "keyMaterial": { + "$$type": "binData" + } + }, + "$currentDate": { + "updateDate": true + } + }, + "multi": { + "$$unsetOrMatches": false + }, + "upsert": { + "$$unsetOrMatches": false + } + }, + { + "q": { + "_id": { + "$$type": "binData" + } + }, + "u": { + "$set": { + "masterKey": { + "$$type": "object" + }, + "keyMaterial": { + "$$type": "binData" + } + }, + "$currentDate": { + "updateDate": true + } + }, + "multi": { + "$$unsetOrMatches": false + }, + "upsert": { + "$$unsetOrMatches": false + } + } + ], + "writeConcern": { + "w": "majority" + } + } + } + }, + { + "commandStartedEvent": { + "commandName": "find" + } + } + ] + } + ] + } + ] +} diff --git a/src/test/spec/json/client-side-encryption/unified/rewrapManyDataKey.yml b/src/test/spec/json/client-side-encryption/unified/rewrapManyDataKey.yml new file mode 100644 index 000000000..514155868 --- /dev/null +++ b/src/test/spec/json/client-side-encryption/unified/rewrapManyDataKey.yml @@ -0,0 +1,432 @@ +# To ensure consistent ordering for expectResult matching purposes, find +# commands sort the resulting documents in ascending order by the single-element +# keyAltNames array to ensure alphabetic order by original KMS provider as +# defined in initialData. +description: rewrapManyDataKey + +schemaVersion: "1.8" + +runOnRequirements: + - csfle: true + +createEntities: + - client: + id: &client0 client0 + observeEvents: + - commandStartedEvent + - clientEncryption: + id: &clientEncryption0 clientEncryption0 + clientEncryptionOpts: + keyVaultClient: *client0 + keyVaultNamespace: keyvault.datakeys + kmsProviders: + aws: { accessKeyId: { $$placeholder: 1 }, secretAccessKey: { $$placeholder: 1 } } + azure: { tenantId: { $$placeholder: 1 }, clientId: { $$placeholder: 1 }, clientSecret: { $$placeholder: 1 } } + gcp: { email: { $$placeholder: 1 }, privateKey: { $$placeholder: 1 } } + kmip: { endpoint: { $$placeholder: 1 } } + local: { key: { $$placeholder: 1 } } + - database: + id: &database0 database0 + client: *client0 + databaseName: &database0Name keyvault + - collection: + id: &collection0 collection0 + database: *database0 + collectionName: &collection0Name datakeys + +initialData: + - databaseName: *database0Name + collectionName: *collection0Name + documents: + - _id: &aws_key_id { $binary: { base64: YXdzYXdzYXdzYXdzYXdzYQ==, subType: "04" } } + keyAltNames: ["aws_key"] + keyMaterial: { $binary: { base64: AQICAHhQNmWG2CzOm1dq3kWLM+iDUZhEqnhJwH9wZVpuZ94A8gFXJqbF0Fy872MD7xl56D/2AAAAwjCBvwYJKoZIhvcNAQcGoIGxMIGuAgEAMIGoBgkqhkiG9w0BBwEwHgYJYIZIAWUDBAEuMBEEDO7HPisPUlGzaio9vgIBEIB7/Qow46PMh/8JbEUbdXgTGhLfXPE+KIVW7T8s6YEMlGiRvMu7TV0QCIUJlSHPKZxzlJ2iwuz5yXeOag+EdY+eIQ0RKrsJ3b8UTisZYzGjfzZnxUKLzLoeXremtRCm3x47wCuHKd1dhh6FBbYt5TL2tDaj+vL2GBrKat2L, subType: "00" } } + creationDate: { $date: { $numberLong: "1641024000000" } } + updateDate: { $date: { $numberLong: "1641024000000" } } + status: 1 + masterKey: &aws_masterkey + provider: aws + key: arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0 + region: us-east-1 + - _id: &azure_key_id { $binary: { base64: YXp1cmVhenVyZWF6dXJlYQ==, subType: "04" } } + keyAltNames: ["azure_key"] + keyMaterial: { $binary: { base64: pr01l7qDygUkFE/0peFwpnNlv3iIy8zrQK38Q9i12UCN2jwZHDmfyx8wokiIKMb9kAleeY+vnt3Cf1MKu9kcDmI+KxbNDd+V3ytAAGzOVLDJr77CiWjF9f8ntkXRHrAY9WwnVDANYkDwXlyU0Y2GQFTiW65jiQhUtYLYH63Tk48SsJuQvnWw1Q+PzY8ga+QeVec8wbcThwtm+r2IHsCFnc72Gv73qq7weISw+O4mN08z3wOp5FOS2ZM3MK7tBGmPdBcktW7F8ODGsOQ1FU53OrWUnyX2aTi2ftFFFMWVHqQo7EYuBZHru8RRODNKMyQk0BFfKovAeTAVRv9WH9QU7g==, subType: "00" } } + creationDate: { $date: { $numberLong: "1641024000000" } } + updateDate: { $date: { $numberLong: "1641024000000" } } + status: 1 + masterKey: &azure_masterkey + provider: azure + keyVaultEndpoint: key-vault-csfle.vault.azure.net + keyName: key-name-csfle + - _id: &gcp_key_id { $binary: { base64: Z2NwZ2NwZ2NwZ2NwZ2NwZw==, subType: "04" } } + keyAltNames: ["gcp_key"] + keyMaterial: { $binary: { base64: CiQAIgLj0USbQtof/pYRLQO96yg/JEtZbD1UxKueaC37yzT5tTkSiQEAhClWB5ZCSgzHgxv8raWjNB4r7e8ePGdsmSuYTYmLC5oHHS/BdQisConzNKFaobEQZHamTCjyhy5NotKF8MWoo+dyfQApwI29+vAGyrUIQCXzKwRnNdNQ+lb3vJtS5bqvLTvSxKHpVca2kqyC9nhonV+u4qru5Q2bAqUgVFc8fL4pBuvlowZFTQ==, subType: "00" } } + creationDate: { $date: { $numberLong: "1641024000000" } } + updateDate: { $date: { $numberLong: "1641024000000" } } + status: 1 + masterKey: &gcp_masterkey + provider: gcp + projectId: devprod-drivers + location: global + keyRing: key-ring-csfle + keyName: key-name-csfle + - _id: &kmip_key_id { $binary: { base64: a21pcGttaXBrbWlwa21pcA==, subType: "04" } } + keyAltNames: ["kmip_key"] + keyMaterial: { $binary: { base64: CklVctHzke4mcytd0TxGqvepkdkQN8NUF4+jV7aZQITAKdz6WjdDpq3lMt9nSzWGG2vAEfvRb3mFEVjV57qqGqxjq2751gmiMRHXz0btStbIK3mQ5xbY9kdye4tsixlCryEwQONr96gwlwKKI9Nubl9/8+uRF6tgYjje7Q7OjauEf1SrJwKcoQ3WwnjZmEqAug0kImCpJ/irhdqPzivRiA==, subType: "00" } } + creationDate: { $date: { $numberLong: "1641024000000" } } + updateDate: { $date: { $numberLong: "1641024000000" } } + status: 1 + masterKey: &kmip_masterkey + provider: kmip + keyId: "1" + - _id: &local_key_id { $binary: { base64: bG9jYWxrZXlsb2NhbGtleQ==, subType: "04" } } + keyAltNames: ["local_key"] + keyMaterial: { $binary: { base64: ABKBldDEoDW323yejOnIRk6YQmlD9d3eQthd16scKL75nz2LjNL9fgPDZWrFFOlqlhMCFaSrNJfGrFUjYk5JFDO7soG5Syb50k1niJoKg4ilsj0L4mpimFUtTpOr2nzZOeQtvAksEXc7gsFgq8gV7t/U3lsaXPY7I0t42DfSE8EGlPdxRjFdHnxh+OR8h7U9b8Qs5K5UuhgyeyxaBZ1Hgw==, subType: "00" } } + creationDate: { $date: { $numberLong: "1641024000000" } } + updateDate: { $date: { $numberLong: "1641024000000" } } + status: 1 + masterKey: &local_masterkey + provider: local + +tests: + - description: "no keys to rewrap due to no filter matches" + operations: + - name: rewrapManyDataKey + object: *clientEncryption0 + arguments: + filter: { keyAltNames: no_matching_keys } + opts: + provider: local + expectResult: + # If no bulk write operation, then no bulk write result. + bulkWriteResult: { $$exists: false } + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + databaseName: *database0Name + command: + find: *collection0Name + filter: { keyAltNames: no_matching_keys } + readConcern: { level: majority } + + - description: "rewrap with new AWS KMS provider" + operations: + - name: rewrapManyDataKey + object: *clientEncryption0 + arguments: + filter: { keyAltNames: { $ne: aws_key } } + opts: + provider: aws + # Different key: 89fcc2c4-08b0-4bd9-9f25-e30687b580d0 -> 061334ae-07a8-4ceb-a813-8135540e837d. + masterKey: &new_aws_masterkey + key: arn:aws:kms:us-east-1:579766882180:key/061334ae-07a8-4ceb-a813-8135540e837d + region: us-east-1 + expectResult: + bulkWriteResult: + insertedCount: 0 + matchedCount: 4 + modifiedCount: 4 + deletedCount: 0 + upsertedCount: 0 + upsertedIds: {} + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + databaseName: *database0Name + command: + find: *collection0Name + filter: { keyAltNames: { $ne: aws_key } } + readConcern: { level: majority } + - commandStartedEvent: + databaseName: *database0Name + command: + update: *collection0Name + ordered: true + updates: + - q: { _id: { $$type: binData } } + u: { $set: { masterKey: { provider: aws, <<: *new_aws_masterkey }, keyMaterial: { $$type: binData } }, $currentDate: { updateDate: true } } + multi: { $$unsetOrMatches: false } + upsert: { $$unsetOrMatches: false } + - q: { _id: { $$type: binData } } + u: { $set: { masterKey: { provider: aws, <<: *new_aws_masterkey }, keyMaterial: { $$type: binData } }, $currentDate: { updateDate: true } } + multi: { $$unsetOrMatches: false } + upsert: { $$unsetOrMatches: false } + - q: { _id: { $$type: binData } } + u: { $set: { masterKey: { provider: aws, <<: *new_aws_masterkey }, keyMaterial: { $$type: binData } }, $currentDate: { updateDate: true } } + multi: { $$unsetOrMatches: false } + upsert: { $$unsetOrMatches: false } + - q: { _id: { $$type: binData } } + u: { $set: { masterKey: { provider: aws, <<: *new_aws_masterkey }, keyMaterial: { $$type: binData } }, $currentDate: { updateDate: true } } + multi: { $$unsetOrMatches: false } + upsert: { $$unsetOrMatches: false } + writeConcern: { w: majority } + + - description: "rewrap with new Azure KMS provider" + operations: + - name: rewrapManyDataKey + object: *clientEncryption0 + arguments: + filter: { keyAltNames: { $ne: azure_key } } + opts: + provider: azure + masterKey: &new_azure_masterkey + keyVaultEndpoint: key-vault-csfle.vault.azure.net + keyName: key-name-csfle + expectResult: + bulkWriteResult: + insertedCount: 0 + matchedCount: 4 + modifiedCount: 4 + deletedCount: 0 + upsertedCount: 0 + upsertedIds: {} + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + databaseName: *database0Name + command: + find: *collection0Name + filter: { keyAltNames: { $ne: azure_key } } + readConcern: { level: majority } + - commandStartedEvent: + databaseName: *database0Name + command: + update: *collection0Name + ordered: true + updates: + - q: { _id: { $$type: binData } } + u: { $set: { masterKey: { provider: azure, <<: *new_azure_masterkey }, keyMaterial: { $$type: binData } }, $currentDate: { updateDate: true } } + multi: { $$unsetOrMatches: false } + upsert: { $$unsetOrMatches: false } + - q: { _id: { $$type: binData } } + u: { $set: { masterKey: { provider: azure, <<: *new_azure_masterkey }, keyMaterial: { $$type: binData } }, $currentDate: { updateDate: true } } + multi: { $$unsetOrMatches: false } + upsert: { $$unsetOrMatches: false } + - q: { _id: { $$type: binData } } + u: { $set: { masterKey: { provider: azure, <<: *new_azure_masterkey }, keyMaterial: { $$type: binData } }, $currentDate: { updateDate: true } } + multi: { $$unsetOrMatches: false } + upsert: { $$unsetOrMatches: false } + - q: { _id: { $$type: binData } } + u: { $set: { masterKey: { provider: azure, <<: *new_azure_masterkey }, keyMaterial: { $$type: binData } }, $currentDate: { updateDate: true } } + multi: { $$unsetOrMatches: false } + upsert: { $$unsetOrMatches: false } + writeConcern: { w: majority } + + - description: "rewrap with new GCP KMS provider" + operations: + - name: rewrapManyDataKey + object: *clientEncryption0 + arguments: + filter: { keyAltNames: { $ne: gcp_key } } + opts: + provider: gcp + masterKey: &new_gcp_masterkey + projectId: devprod-drivers + location: global + keyRing: key-ring-csfle + keyName: key-name-csfle + expectResult: + bulkWriteResult: + insertedCount: 0 + matchedCount: 4 + modifiedCount: 4 + deletedCount: 0 + upsertedCount: 0 + upsertedIds: {} + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + databaseName: *database0Name + command: + find: *collection0Name + filter: { keyAltNames: { $ne: gcp_key } } + readConcern: { level: majority } + - commandStartedEvent: + databaseName: *database0Name + command: + update: *collection0Name + ordered: true + updates: + - q: { _id: { $$type: binData } } + u: { $set: { masterKey: { provider: gcp, <<: *new_gcp_masterkey }, keyMaterial: { $$type: binData } }, $currentDate: { updateDate: true } } + multi: { $$unsetOrMatches: false } + upsert: { $$unsetOrMatches: false } + - q: { _id: { $$type: binData } } + u: { $set: { masterKey: { provider: gcp, <<: *new_gcp_masterkey }, keyMaterial: { $$type: binData } }, $currentDate: { updateDate: true } } + multi: { $$unsetOrMatches: false } + upsert: { $$unsetOrMatches: false } + - q: { _id: { $$type: binData } } + u: { $set: { masterKey: { provider: gcp, <<: *new_gcp_masterkey }, keyMaterial: { $$type: binData } }, $currentDate: { updateDate: true } } + multi: { $$unsetOrMatches: false } + upsert: { $$unsetOrMatches: false } + - q: { _id: { $$type: binData } } + u: { $set: { masterKey: { provider: gcp, <<: *new_gcp_masterkey }, keyMaterial: { $$type: binData } }, $currentDate: { updateDate: true } } + multi: { $$unsetOrMatches: false } + upsert: { $$unsetOrMatches: false } + writeConcern: { w: majority } + + - description: "rewrap with new KMIP KMS provider" + operations: + - name: rewrapManyDataKey + object: *clientEncryption0 + arguments: + filter: { keyAltNames: { $ne: kmip_key } } + opts: + provider: kmip + expectResult: + bulkWriteResult: + insertedCount: 0 + matchedCount: 4 + modifiedCount: 4 + deletedCount: 0 + upsertedCount: 0 + upsertedIds: {} + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + databaseName: *database0Name + command: + find: *collection0Name + filter: { keyAltNames: { $ne: kmip_key } } + readConcern: { level: majority } + - commandStartedEvent: + databaseName: *database0Name + command: + update: *collection0Name + ordered: true + updates: + - q: { _id: { $$type: binData } } + u: { $set: { masterKey: { provider: kmip, keyId: { $$type: string } }, keyMaterial: { $$type: binData } }, $currentDate: { updateDate: true } } + multi: { $$unsetOrMatches: false } + upsert: { $$unsetOrMatches: false } + - q: { _id: { $$type: binData } } + u: { $set: { masterKey: { provider: kmip, keyId: { $$type: string } }, keyMaterial: { $$type: binData } }, $currentDate: { updateDate: true } } + multi: { $$unsetOrMatches: false } + upsert: { $$unsetOrMatches: false } + - q: { _id: { $$type: binData } } + u: { $set: { masterKey: { provider: kmip, keyId: { $$type: string } }, keyMaterial: { $$type: binData } }, $currentDate: { updateDate: true } } + multi: { $$unsetOrMatches: false } + upsert: { $$unsetOrMatches: false } + - q: { _id: { $$type: binData } } + u: { $set: { masterKey: { provider: kmip, keyId: { $$type: string } }, keyMaterial: { $$type: binData } }, $currentDate: { updateDate: true } } + multi: { $$unsetOrMatches: false } + upsert: { $$unsetOrMatches: false } + writeConcern: { w: majority } + + - description: "rewrap with new local KMS provider" + operations: + - name: rewrapManyDataKey + object: *clientEncryption0 + arguments: + filter: { keyAltNames: { $ne: local_key } } + opts: + provider: local + expectResult: + bulkWriteResult: + insertedCount: 0 + matchedCount: 4 + modifiedCount: 4 + deletedCount: 0 + upsertedCount: 0 + upsertedIds: {} + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + databaseName: *database0Name + command: + find: *collection0Name + filter: { keyAltNames: { $ne: local_key } } + readConcern: { level: majority } + - commandStartedEvent: + databaseName: *database0Name + command: + update: *collection0Name + ordered: true + updates: + - q: { _id: { $$type: binData } } + u: { $set: { masterKey: { provider: local }, keyMaterial: { $$type: binData } }, $currentDate: { updateDate: true } } + multi: { $$unsetOrMatches: false } + upsert: { $$unsetOrMatches: false } + - q: { _id: { $$type: binData } } + u: { $set: { masterKey: { provider: local }, keyMaterial: { $$type: binData } }, $currentDate: { updateDate: true } } + multi: { $$unsetOrMatches: false } + upsert: { $$unsetOrMatches: false } + - q: { _id: { $$type: binData } } + u: { $set: { masterKey: { provider: local }, keyMaterial: { $$type: binData } }, $currentDate: { updateDate: true } } + multi: { $$unsetOrMatches: false } + upsert: { $$unsetOrMatches: false } + - q: { _id: { $$type: binData } } + u: { $set: { masterKey: { provider: local }, keyMaterial: { $$type: binData } }, $currentDate: { updateDate: true } } + multi: { $$unsetOrMatches: false } + upsert: { $$unsetOrMatches: false } + writeConcern: { w: majority } + + - description: "rewrap with current KMS provider" + operations: + - name: rewrapManyDataKey + object: *clientEncryption0 + arguments: + filter: {} + expectResult: + bulkWriteResult: + insertedCount: 0 + matchedCount: 5 + modifiedCount: 5 + deletedCount: 0 + upsertedCount: 0 + upsertedIds: {} + - name: find + object: *collection0 + arguments: + filter: {} + projection: { masterKey: 1 } + sort: { keyAltNames: 1 } + expectResult: + - { _id: *aws_key_id, masterKey: *aws_masterkey } + - { _id: *azure_key_id, masterKey: *azure_masterkey } + - { _id: *gcp_key_id, masterKey: *gcp_masterkey } + - { _id: *kmip_key_id, masterKey: *kmip_masterkey } + - { _id: *local_key_id, masterKey: *local_masterkey } + expectEvents: + - client: *client0 + events: + - commandStartedEvent: + databaseName: *database0Name + command: + find: *collection0Name + filter: {} + readConcern: { level: majority } + - commandStartedEvent: + databaseName: *database0Name + command: + update: *collection0Name + ordered: true + updates: + - q: { _id: { $$type: binData } } + u: { $set: { masterKey: { $$type: object }, keyMaterial: { $$type: binData } }, $currentDate: { updateDate: true } } + multi: { $$unsetOrMatches: false } + upsert: { $$unsetOrMatches: false } + - q: { _id: { $$type: binData } } + u: { $set: { masterKey: { $$type: object }, keyMaterial: { $$type: binData } }, $currentDate: { updateDate: true } } + multi: { $$unsetOrMatches: false } + upsert: { $$unsetOrMatches: false } + - q: { _id: { $$type: binData } } + u: { $set: { masterKey: { $$type: object }, keyMaterial: { $$type: binData } }, $currentDate: { updateDate: true } } + multi: { $$unsetOrMatches: false } + upsert: { $$unsetOrMatches: false } + - q: { _id: { $$type: binData } } + u: { $set: { masterKey: { $$type: object }, keyMaterial: { $$type: binData } }, $currentDate: { updateDate: true } } + multi: { $$unsetOrMatches: false } + upsert: { $$unsetOrMatches: false } + - q: { _id: { $$type: binData } } + u: { $set: { masterKey: { $$type: object }, keyMaterial: { $$type: binData } }, $currentDate: { updateDate: true } } + multi: { $$unsetOrMatches: false } + upsert: { $$unsetOrMatches: false } + writeConcern: { w: majority } + - commandStartedEvent: { commandName: find } diff --git a/src/test/spec/json/client-side-encryption/testdata/corpus/corpus-encrypted.json b/src/test/spec/json/testdata/client-side-encryption/corpus/corpus-encrypted.json similarity index 100% rename from src/test/spec/json/client-side-encryption/testdata/corpus/corpus-encrypted.json rename to src/test/spec/json/testdata/client-side-encryption/corpus/corpus-encrypted.json diff --git a/src/test/spec/json/client-side-encryption/testdata/corpus/corpus-key-aws.json b/src/test/spec/json/testdata/client-side-encryption/corpus/corpus-key-aws.json similarity index 100% rename from src/test/spec/json/client-side-encryption/testdata/corpus/corpus-key-aws.json rename to src/test/spec/json/testdata/client-side-encryption/corpus/corpus-key-aws.json diff --git a/src/test/spec/json/client-side-encryption/testdata/corpus/corpus-key-azure.json b/src/test/spec/json/testdata/client-side-encryption/corpus/corpus-key-azure.json similarity index 100% rename from src/test/spec/json/client-side-encryption/testdata/corpus/corpus-key-azure.json rename to src/test/spec/json/testdata/client-side-encryption/corpus/corpus-key-azure.json diff --git a/src/test/spec/json/client-side-encryption/testdata/corpus/corpus-key-gcp.json b/src/test/spec/json/testdata/client-side-encryption/corpus/corpus-key-gcp.json similarity index 100% rename from src/test/spec/json/client-side-encryption/testdata/corpus/corpus-key-gcp.json rename to src/test/spec/json/testdata/client-side-encryption/corpus/corpus-key-gcp.json diff --git a/src/test/spec/json/client-side-encryption/testdata/corpus/corpus-key-kmip.json b/src/test/spec/json/testdata/client-side-encryption/corpus/corpus-key-kmip.json similarity index 100% rename from src/test/spec/json/client-side-encryption/testdata/corpus/corpus-key-kmip.json rename to src/test/spec/json/testdata/client-side-encryption/corpus/corpus-key-kmip.json diff --git a/src/test/spec/json/client-side-encryption/testdata/corpus/corpus-key-local.json b/src/test/spec/json/testdata/client-side-encryption/corpus/corpus-key-local.json similarity index 100% rename from src/test/spec/json/client-side-encryption/testdata/corpus/corpus-key-local.json rename to src/test/spec/json/testdata/client-side-encryption/corpus/corpus-key-local.json diff --git a/src/test/spec/json/client-side-encryption/testdata/corpus/corpus-schema.json b/src/test/spec/json/testdata/client-side-encryption/corpus/corpus-schema.json similarity index 100% rename from src/test/spec/json/client-side-encryption/testdata/corpus/corpus-schema.json rename to src/test/spec/json/testdata/client-side-encryption/corpus/corpus-schema.json diff --git a/src/test/spec/json/client-side-encryption/testdata/corpus/corpus.json b/src/test/spec/json/testdata/client-side-encryption/corpus/corpus.json similarity index 100% rename from src/test/spec/json/client-side-encryption/testdata/corpus/corpus.json rename to src/test/spec/json/testdata/client-side-encryption/corpus/corpus.json diff --git a/src/test/spec/json/client-side-encryption/testdata/external-key.json b/src/test/spec/json/testdata/client-side-encryption/external-key.json similarity index 100% rename from src/test/spec/json/client-side-encryption/testdata/external-key.json rename to src/test/spec/json/testdata/client-side-encryption/external-key.json diff --git a/src/test/spec/json/client-side-encryption/testdata/external-schema.json b/src/test/spec/json/testdata/client-side-encryption/external-schema.json similarity index 100% rename from src/test/spec/json/client-side-encryption/testdata/external-schema.json rename to src/test/spec/json/testdata/client-side-encryption/external-schema.json diff --git a/src/test/spec/json/client-side-encryption/testdata/limits-doc.json b/src/test/spec/json/testdata/client-side-encryption/limits-doc.json similarity index 100% rename from src/test/spec/json/client-side-encryption/testdata/limits-doc.json rename to src/test/spec/json/testdata/client-side-encryption/limits-doc.json diff --git a/src/test/spec/json/client-side-encryption/testdata/limits-key.json b/src/test/spec/json/testdata/client-side-encryption/limits-key.json similarity index 100% rename from src/test/spec/json/client-side-encryption/testdata/limits-key.json rename to src/test/spec/json/testdata/client-side-encryption/limits-key.json diff --git a/src/test/spec/json/client-side-encryption/testdata/limits-schema.json b/src/test/spec/json/testdata/client-side-encryption/limits-schema.json similarity index 100% rename from src/test/spec/json/client-side-encryption/testdata/limits-schema.json rename to src/test/spec/json/testdata/client-side-encryption/limits-schema.json From 9049c0294d75836b43e30e1247c876c74c4ed839 Mon Sep 17 00:00:00 2001 From: Abraham Egnor Date: Wed, 26 Oct 2022 13:03:28 -0400 Subject: [PATCH 02/10] client encryption entity --- src/client/csfle/client_encryption.rs | 6 +++++ src/test/spec/client_side_encryption.rs | 30 +++++++++++++++++++++ src/test/spec/mod.rs | 2 ++ src/test/spec/unified_runner/entity.rs | 6 +++++ src/test/spec/unified_runner/test_file.rs | 19 +++++++++++++ src/test/spec/unified_runner/test_runner.rs | 19 +++++++++++++ 6 files changed, 82 insertions(+) create mode 100644 src/test/spec/client_side_encryption.rs diff --git a/src/client/csfle/client_encryption.rs b/src/client/csfle/client_encryption.rs index a8ea7aaf6..85ecf872a 100644 --- a/src/client/csfle/client_encryption.rs +++ b/src/client/csfle/client_encryption.rs @@ -32,6 +32,12 @@ pub struct ClientEncryption { key_vault: Collection, } +impl std::fmt::Debug for ClientEncryption { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("ClientEncryption").finish() + } +} + impl ClientEncryption { /// Create a new key vault handle with the given options. pub fn new(options: ClientEncryptionOptions) -> Result { diff --git a/src/test/spec/client_side_encryption.rs b/src/test/spec/client_side_encryption.rs new file mode 100644 index 000000000..a25f0cdb3 --- /dev/null +++ b/src/test/spec/client_side_encryption.rs @@ -0,0 +1,30 @@ +use tokio::sync::RwLockWriteGuard; + +use crate::test::LOCK; + +use super::{run_spec_test_with_path, run_unified_format_test_filtered, unified_runner::TestCase}; + +#[cfg_attr(feature = "tokio-runtime", tokio::test(flavor = "multi_thread"))] +#[cfg_attr(feature = "async-std-runtime", async_std::test)] +async fn run() { + let _guard: RwLockWriteGuard<()> = LOCK.run_exclusively().await; + run_spec_test_with_path(&["client_side_encryption", "unified"], |path, file| { + run_unified_format_test_filtered(path, file, test_predicate) + }) + .await; +} + +fn test_predicate(_test: &TestCase) -> bool { + true + /* + // The Rust driver doesn't support unacknowledged writes. + let lower = test.description.to_lowercase(); + + !lower.contains("unacknowledged") + // TODO: RUST-663: unskip aggregate $out and $merge tests + && !(lower.contains("aggregate with $out includes read preference for 5.0+ server")) + && !(lower.contains("aggregate with $out omits read preference for pre-5.0 server")) + && !(lower.contains("aggregate with $merge includes read preference for 5.0+ server")) + && !(lower.contains("aggregate with $merge omits read preference for pre-5.0 server")) + */ +} diff --git a/src/test/spec/mod.rs b/src/test/spec/mod.rs index 431d8a07c..648e185eb 100644 --- a/src/test/spec/mod.rs +++ b/src/test/spec/mod.rs @@ -1,6 +1,8 @@ #[cfg(all(not(feature = "sync"), not(feature = "tokio-sync")))] mod auth; mod change_streams; +#[cfg(feature = "csfle")] +mod client_side_encryption; mod collection_management; mod command_monitoring; mod connection_stepdown; diff --git a/src/test/spec/unified_runner/entity.rs b/src/test/spec/unified_runner/entity.rs index 7e4f3481b..1a66d8c33 100644 --- a/src/test/spec/unified_runner/entity.rs +++ b/src/test/spec/unified_runner/entity.rs @@ -45,6 +45,8 @@ pub(crate) enum Entity { EventList(EventList), Thread(ThreadEntity), TopologyDescription(TopologyDescription), + #[cfg(feature = "csfle")] + ClientEncryption(crate::client_encryption::ClientEncryption), None, } #[derive(Clone, Debug)] @@ -207,6 +209,10 @@ impl ClientEntity { client.sync_workers().await; } } + + pub(crate) fn client(&self) -> &Client { + &self.client + } } #[derive(Clone, Debug)] diff --git a/src/test/spec/unified_runner/test_file.rs b/src/test/spec/unified_runner/test_file.rs index 3f108f6a1..b00ef424a 100644 --- a/src/test/spec/unified_runner/test_file.rs +++ b/src/test/spec/unified_runner/test_file.rs @@ -146,6 +146,8 @@ pub(crate) enum TestFileEntity { Session(Session), Bucket(Bucket), Thread(Thread), + #[cfg(feature = "csfle")] + ClientEncryption(ClientEncryption), } #[derive(Debug, Deserialize)] @@ -309,6 +311,23 @@ pub(crate) struct Thread { pub(crate) id: String, } +#[cfg(feature = "csfle")] +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +pub(crate) struct ClientEncryption { + pub(crate) id: String, + pub(crate) client_encryption_opts: ClientEncryptionOpts, +} + +#[cfg(feature = "csfle")] +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +pub(crate) struct ClientEncryptionOpts { + pub(crate) key_vault_client: String, + pub(crate) key_vault_namespace: String, + pub(crate) kms_providers: Document, +} + /// Messages used for communicating with test runner "threads". #[derive(Debug)] pub(crate) enum ThreadMessage { diff --git a/src/test/spec/unified_runner/test_runner.rs b/src/test/spec/unified_runner/test_runner.rs index 19c4a1f32..f281e03a1 100644 --- a/src/test/spec/unified_runner/test_runner.rs +++ b/src/test/spec/unified_runner/test_runner.rs @@ -537,6 +537,25 @@ impl TestRunner { }); (thread.id.clone(), Entity::Thread(ThreadEntity { sender })) } + #[cfg(feature = "csfle")] + TestFileEntity::ClientEncryption(client_enc) => { + let id = client_enc.id.clone(); + let opts = &client_enc.client_encryption_opts; + let kv_client = self.get_client(&opts.key_vault_client).await.client().clone(); + let kv_namespace = crate::Namespace::from_str(&opts.key_vault_namespace).unwrap(); + let kms_providers: crate::client::csfle::options::KmsProviders = bson::from_document(opts.kms_providers.clone()).unwrap(); + let client_enc = crate::client_encryption::ClientEncryption::new( + crate::client_encryption::ClientEncryptionOptions::builder() + .key_vault_client(kv_client) + .key_vault_namespace(kv_namespace) + .kms_providers(kms_providers) + .build() + ).unwrap(); + ( + id, + Entity::ClientEncryption(client_enc), + ) + } }; self.insert_entity(&id, entity).await; } From 899815b40c3c57957104f25e309ba3ce9dd3a128 Mon Sep 17 00:00:00 2001 From: Abraham Egnor Date: Thu, 27 Oct 2022 12:07:06 -0400 Subject: [PATCH 03/10] fill placeholders --- Cargo.toml | 3 +++ src/test/csfle.rs | 3 +-- src/test/mod.rs | 2 ++ src/test/spec/unified_runner/entity.rs | 4 +-- src/test/spec/unified_runner/test_runner.rs | 28 +++++++++++++++++++-- 5 files changed, 34 insertions(+), 6 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 2995440d3..b3fdd13fa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -75,6 +75,9 @@ csfle = ["mongocrypt", "rayon", "num_cpus"] # TODO: pending https://github.com/tokio-rs/tracing/issues/2036 stop depending directly on log. tracing-unstable = ["tracing", "log"] +[patch."https://github.com/mongodb/bson-rust"] +bson = { path = "../../bson-rust/minor_iter_mut" } + [dependencies] async-trait = "0.1.42" base64 = "0.13.0" diff --git a/src/test/csfle.rs b/src/test/csfle.rs index 939e101e3..49ef785d2 100644 --- a/src/test/csfle.rs +++ b/src/test/csfle.rs @@ -46,7 +46,7 @@ use crate::{ CommandSucceededEvent, }, options::{IndexOptions, ReadConcern, WriteConcern}, - test::{Event, EventHandler, SdamEvent}, + test::{Event, EventHandler, SdamEvent, KMS_PROVIDERS}, Client, Collection, IndexModel, @@ -87,7 +87,6 @@ async fn init_client() -> Result<(EventClient, Collection)> { } lazy_static! { - static ref KMS_PROVIDERS: KmsProviders = serde_json::from_str(&std::env::var("KMS_PROVIDERS").unwrap()).unwrap(); static ref LOCAL_KMS: KmsProviders = { let mut out = KMS_PROVIDERS.clone(); out.retain(|k, _| *k == KmsProvider::Local); diff --git a/src/test/mod.rs b/src/test/mod.rs index 2734b6ac8..7e91574cb 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -87,6 +87,8 @@ lazy_static! { std::env::var("SERVERLESS_ATLAS_USER").ok(); pub(crate) static ref SERVERLESS_ATLAS_PASSWORD: Option = std::env::var("SERVERLESS_ATLAS_PASSWORD").ok(); + #[cfg(feature = "csfle")] + pub(crate) static ref KMS_PROVIDERS: crate::client::csfle::options::KmsProviders = serde_json::from_str(&std::env::var("KMS_PROVIDERS").unwrap()).unwrap(); } // conditional definitions do not work within the lazy_static! macro, so this diff --git a/src/test/spec/unified_runner/entity.rs b/src/test/spec/unified_runner/entity.rs index 1a66d8c33..3279f3f08 100644 --- a/src/test/spec/unified_runner/entity.rs +++ b/src/test/spec/unified_runner/entity.rs @@ -210,8 +210,8 @@ impl ClientEntity { } } - pub(crate) fn client(&self) -> &Client { - &self.client + pub(crate) fn client(&self) -> Option<&Client> { + self.client.as_ref() } } diff --git a/src/test/spec/unified_runner/test_runner.rs b/src/test/spec/unified_runner/test_runner.rs index f281e03a1..e2e04dc8d 100644 --- a/src/test/spec/unified_runner/test_runner.rs +++ b/src/test/spec/unified_runner/test_runner.rs @@ -54,6 +54,9 @@ use super::{ TestFileEntity, }; +#[cfg(feature = "csfle")] +use crate::client::csfle::options::KmsProviders; + #[cfg(feature = "tracing-unstable")] use crate::test::{ spec::unified_runner::matcher::tracing_events_match, @@ -541,9 +544,10 @@ impl TestRunner { TestFileEntity::ClientEncryption(client_enc) => { let id = client_enc.id.clone(); let opts = &client_enc.client_encryption_opts; - let kv_client = self.get_client(&opts.key_vault_client).await.client().clone(); + let kv_client = self.get_client(&opts.key_vault_client).await.client().unwrap().clone(); let kv_namespace = crate::Namespace::from_str(&opts.key_vault_namespace).unwrap(); - let kms_providers: crate::client::csfle::options::KmsProviders = bson::from_document(opts.kms_providers.clone()).unwrap(); + let mut kms_providers: KmsProviders = bson::from_document(opts.kms_providers.clone()).unwrap(); + fill_kms_placeholders(&mut kms_providers); let client_enc = crate::client_encryption::ClientEncryption::new( crate::client_encryption::ClientEncryptionOptions::builder() .key_vault_client(kv_client) @@ -649,3 +653,23 @@ impl TestRunner { .clone() } } + +#[cfg(feature = "csfle")] +fn fill_kms_placeholders(kms_providers: &mut KmsProviders) { + use crate::test::KMS_PROVIDERS; + + let placeholder = bson::Bson::Document(doc! { "$$placeholder": 1 }); + + for (provider, config) in kms_providers.iter_mut() { + for (key, value) in config.iter_mut() { + if *value == placeholder { + *value = KMS_PROVIDERS + .get(provider) + .expect(&format!("missing config for {:?}", provider)) + .get(key) + .expect(&format!("provider config {:?} missing key {:?}", provider, key)) + .clone(); + } + } + } +} \ No newline at end of file From 46554cb0dbae1a8d39d85730d608a5178856b6ae Mon Sep 17 00:00:00 2001 From: Abraham Egnor Date: Thu, 27 Oct 2022 13:47:04 -0400 Subject: [PATCH 04/10] progress --- src/test/mod.rs | 5 +- src/test/spec/client_side_encryption.rs | 2 +- src/test/spec/mod.rs | 2 +- src/test/spec/unified_runner/entity.rs | 10 ++- src/test/spec/unified_runner/operation.rs | 73 +++++++++++++++------ src/test/spec/unified_runner/test_file.rs | 6 ++ src/test/spec/unified_runner/test_runner.rs | 23 ++++++- 7 files changed, 95 insertions(+), 26 deletions(-) diff --git a/src/test/mod.rs b/src/test/mod.rs index 7e91574cb..416fec292 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -87,7 +87,10 @@ lazy_static! { std::env::var("SERVERLESS_ATLAS_USER").ok(); pub(crate) static ref SERVERLESS_ATLAS_PASSWORD: Option = std::env::var("SERVERLESS_ATLAS_PASSWORD").ok(); - #[cfg(feature = "csfle")] +} + +#[cfg(feature = "csfle")] +lazy_static! { pub(crate) static ref KMS_PROVIDERS: crate::client::csfle::options::KmsProviders = serde_json::from_str(&std::env::var("KMS_PROVIDERS").unwrap()).unwrap(); } diff --git a/src/test/spec/client_side_encryption.rs b/src/test/spec/client_side_encryption.rs index a25f0cdb3..35441ed59 100644 --- a/src/test/spec/client_side_encryption.rs +++ b/src/test/spec/client_side_encryption.rs @@ -8,7 +8,7 @@ use super::{run_spec_test_with_path, run_unified_format_test_filtered, unified_r #[cfg_attr(feature = "async-std-runtime", async_std::test)] async fn run() { let _guard: RwLockWriteGuard<()> = LOCK.run_exclusively().await; - run_spec_test_with_path(&["client_side_encryption", "unified"], |path, file| { + run_spec_test_with_path(&["client-side-encryption", "unified"], |path, file| { run_unified_format_test_filtered(path, file, test_predicate) }) .await; diff --git a/src/test/spec/mod.rs b/src/test/spec/mod.rs index 648e185eb..8cc196167 100644 --- a/src/test/spec/mod.rs +++ b/src/test/spec/mod.rs @@ -71,7 +71,7 @@ where .chain(spec.iter()) .collect(); - for entry in fs::read_dir(&base_path).unwrap() { + for entry in fs::read_dir(&base_path).expect(&format!("reading {:?}", base_path)) { let test_file = entry.unwrap(); if !test_file.file_type().unwrap().is_file() { diff --git a/src/test/spec/unified_runner/entity.rs b/src/test/spec/unified_runner/entity.rs index 3279f3f08..ac8e3b407 100644 --- a/src/test/spec/unified_runner/entity.rs +++ b/src/test/spec/unified_runner/entity.rs @@ -46,7 +46,7 @@ pub(crate) enum Entity { Thread(ThreadEntity), TopologyDescription(TopologyDescription), #[cfg(feature = "csfle")] - ClientEncryption(crate::client_encryption::ClientEncryption), + ClientEncryption(Arc), None, } #[derive(Clone, Debug)] @@ -424,4 +424,12 @@ impl Entity { _ => None, } } + + #[cfg(feature = "csfle")] + pub fn as_client_encryption(&self) -> &Arc { + match self { + Self::ClientEncryption(ce) => ce, + _ => panic!("Expected ClientEncryption, got {:?}", &self), + } + } } diff --git a/src/test/spec/unified_runner/operation.rs b/src/test/spec/unified_runner/operation.rs index 760cf947e..a3d60a874 100644 --- a/src/test/spec/unified_runner/operation.rs +++ b/src/test/spec/unified_runner/operation.rs @@ -80,7 +80,7 @@ pub(crate) trait TestOperation: Debug + Send + Sync { &'a self, _test_runner: &'a TestRunner, ) -> BoxFuture<'a, ()> { - todo!() + panic!("execute_test_runner_operation called on unsupported operation {:?}", self) } fn execute_entity_operation<'a>( @@ -90,7 +90,7 @@ pub(crate) trait TestOperation: Debug + Send + Sync { ) -> BoxFuture<'a, Result>> { async move { Err(ErrorKind::InvalidArgument { - message: "execute_entity_operation called on unsupported operation".into(), + message: format!("execute_entity_operation called on unsupported operation {:?}", self), } .into()) } @@ -171,24 +171,25 @@ impl Operation { panic!("[{}] {} did not return an entity", description, self.name) }); if let Some(expected_bson) = expected_value { - if let Entity::Bson(actual) = &entity { - if let Err(e) = results_match( - Some(actual), - expected_bson, - self.returns_root_documents(), - Some(&*test_runner.entities.read().await), - ) { - panic!( - "[{}] result mismatch, expected = {:#?} actual = \ - {:#?}\nmismatch detail: {}", - description, expected_bson, actual, e - ); - } - } else { - panic!( + let actual = match &entity { + Entity::Bson(bs) => Some(bs), + Entity::None => None, + _ => panic!( "[{}] Incorrect entity type returned from {}, expected \ BSON", description, self.name + ), + }; + if let Err(e) = results_match( + actual, + expected_bson, + self.returns_root_documents(), + Some(&*test_runner.entities.read().await), + ) { + panic!( + "[{}] result mismatch, expected = {:#?} actual = \ + {:#?}\nmismatch detail: {}", + description, expected_bson, actual, e ); } } @@ -350,7 +351,8 @@ impl<'de> Deserialize<'de> for Operation { "downloadByName" => deserialize_op::(definition.arguments), "delete" => deserialize_op::(definition.arguments), "upload" => deserialize_op::(definition.arguments), - _ => Ok(Box::new(UnimplementedOperation) as Box), + "getKeyByAltName" => deserialize_op::(definition.arguments), + s => Ok(Box::new(UnimplementedOperation { _name: s.to_string() }) as Box), } .map_err(|e| serde::de::Error::custom(format!("{}", e)))?; @@ -2832,7 +2834,40 @@ impl TestOperation for Upload { } } +#[cfg(feature = "csfle")] #[derive(Debug, Deserialize)] -pub(super) struct UnimplementedOperation; +#[serde(rename_all = "camelCase", deny_unknown_fields)] +pub(super) struct GetKeyByAltName { + key_alt_name: String, +} + +#[cfg(feature = "csfle")] +impl TestOperation for GetKeyByAltName { + fn execute_entity_operation<'a>( + &'a self, + id: &'a str, + test_runner: &'a TestRunner, + ) -> BoxFuture<'a, Result>> { + async move { + let ce = test_runner.get_client_encryption(id).await; + let key = ce.get_key_by_alt_name(&self.key_alt_name).await?; + let ent = match key { + Some(rd) => Entity::Bson(Bson::Document(rd.to_document()?)), + None => Entity::None, + }; + Ok(Some(ent)) + } + .boxed() + } + + fn returns_root_documents(&self) -> bool { + true + } +} + +#[derive(Debug, Deserialize)] +pub(super) struct UnimplementedOperation { + _name: String, +} impl TestOperation for UnimplementedOperation {} diff --git a/src/test/spec/unified_runner/test_file.rs b/src/test/spec/unified_runner/test_file.rs index b00ef424a..939db8e49 100644 --- a/src/test/spec/unified_runner/test_file.rs +++ b/src/test/spec/unified_runner/test_file.rs @@ -72,6 +72,7 @@ pub(crate) struct RunOnRequirement { server_parameters: Option, serverless: Option, auth: Option, + csfle: Option, } #[derive(Clone, Copy, Debug, Deserialize, PartialEq)] @@ -133,6 +134,11 @@ impl RunOnRequirement { return false; } } + if let Some(csfle) = &self.csfle { + if *csfle && std::env::var("KMS_PROVIDERS").is_err() { + return false; + } + } true } } diff --git a/src/test/spec/unified_runner/test_runner.rs b/src/test/spec/unified_runner/test_runner.rs index e2e04dc8d..f9b6c217c 100644 --- a/src/test/spec/unified_runner/test_runner.rs +++ b/src/test/spec/unified_runner/test_runner.rs @@ -71,6 +71,7 @@ const SKIPPED_OPERATIONS: &[&str] = &[ "listDatabaseObjects", "mapReduce", "watch", + "rewrapManyDataKey", ]; pub(crate) type EntityMap = HashMap; @@ -244,7 +245,8 @@ impl TestRunner { if expected.ignore_extra_events.unwrap_or(false) { assert!( actual_events.len() >= expected_events.len(), - "actual:\n{:#?}\nexpected:\n{:#?}", + "[{}] actual:\n{:#?}\nexpected:\n{:#?}", + test_case.description, actual_events, expected_events ) @@ -252,7 +254,8 @@ impl TestRunner { assert_eq!( actual_events.len(), expected_events.len(), - "actual:\n{:#?}\nexpected:\n{:#?}", + "[{}] actual:\n{:#?}\nexpected:\n{:#?}", + test_case.description, actual_events, expected_events ) @@ -557,7 +560,7 @@ impl TestRunner { ).unwrap(); ( id, - Entity::ClientEncryption(client_enc), + Entity::ClientEncryption(Arc::new(client_enc)), ) } }; @@ -652,6 +655,20 @@ impl TestRunner { .as_topology_description() .clone() } + + #[cfg(feature = "csfle")] + pub(crate) async fn get_client_encryption( + &self, + id: impl AsRef, + ) -> Arc { + self.entities + .read() + .await + .get(id.as_ref()) + .unwrap() + .as_client_encryption() + .clone() + } } #[cfg(feature = "csfle")] From 36921617dd31f35b813fbaed28fc3c9890aa3212 Mon Sep 17 00:00:00 2001 From: Abraham Egnor Date: Thu, 27 Oct 2022 14:59:45 -0400 Subject: [PATCH 05/10] test passing --- src/client/csfle/client_encryption.rs | 25 ++- src/test/csfle.rs | 16 +- src/test/mod.rs | 8 + src/test/spec/unified_runner/operation.rs | 159 +++++++++++++++++++- src/test/spec/unified_runner/test_runner.rs | 4 +- 5 files changed, 192 insertions(+), 20 deletions(-) diff --git a/src/client/csfle/client_encryption.rs b/src/client/csfle/client_encryption.rs index 85ecf872a..2f734b098 100644 --- a/src/client/csfle/client_encryption.rs +++ b/src/client/csfle/client_encryption.rs @@ -16,7 +16,7 @@ use mongocrypt::{ ctx::{Algorithm, Ctx, KmsProvider}, Crypt, }; -use serde::Serialize; +use serde::{Serialize, Deserialize}; use typed_builder::TypedBuilder; use super::{ @@ -277,9 +277,30 @@ pub struct DataKeyOptions { pub key_material: Option>, } +impl<'de> Deserialize<'de> for DataKeyOptions { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + #[serde(rename_all = "camelCase")] + struct Helper { + master_key: Option, + key_alt_names: Option>, + key_material: Option, + } + let h = Helper::deserialize(deserializer)?; + Ok(DataKeyOptions { + master_key: h.master_key.unwrap_or(MasterKey::Local), + key_alt_names: h.key_alt_names, + key_material: h.key_material.map(|bin| bin.bytes), + }) + } +} + /// A KMS-specific key used to encrypt data keys. #[serde_with::skip_serializing_none] -#[derive(Debug, Clone, Serialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] #[non_exhaustive] #[allow(missing_docs)] diff --git a/src/test/csfle.rs b/src/test/csfle.rs index 49ef785d2..37ec8bdba 100644 --- a/src/test/csfle.rs +++ b/src/test/csfle.rs @@ -46,7 +46,7 @@ use crate::{ CommandSucceededEvent, }, options::{IndexOptions, ReadConcern, WriteConcern}, - test::{Event, EventHandler, SdamEvent, KMS_PROVIDERS}, + test::{Event, EventHandler, SdamEvent, KMS_PROVIDERS, KMIP_TLS_OPTIONS}, Client, Collection, IndexModel, @@ -94,20 +94,6 @@ lazy_static! { }; static ref EXTRA_OPTIONS: Document = doc! { "cryptSharedLibPath": std::env::var("CSFLE_SHARED_LIB_PATH").unwrap() }; static ref KV_NAMESPACE: Namespace = Namespace::from_str("keyvault.datakeys").unwrap(); - static ref KMIP_TLS_OPTIONS: KmsProvidersTlsOptions = { - /* If these options are used, the test will need a running KMIP server: - pip3 install pykmip - # in drivers-evergreen-tools/.evergreen - python3 ./csfle/kms_kmip_server.py - */ - let cert_dir = PathBuf::from(std::env::var("CSFLE_TLS_CERT_DIR").unwrap()); - let kmip_opts = TlsOptions::builder() - .ca_file_path(cert_dir.join("ca.pem")) - .cert_key_file_path(cert_dir.join("client.pem")) - .build(); - let tls_options: KmsProvidersTlsOptions = [(KmsProvider::Kmip, kmip_opts)].into_iter().collect(); - tls_options - }; static ref DISABLE_CRYPT_SHARED: bool = std::env::var("DISABLE_CRYPT_SHARED") .map_or(false, |s| s == "true"); } diff --git a/src/test/mod.rs b/src/test/mod.rs index 416fec292..b717584a5 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -92,6 +92,14 @@ lazy_static! { #[cfg(feature = "csfle")] lazy_static! { pub(crate) static ref KMS_PROVIDERS: crate::client::csfle::options::KmsProviders = serde_json::from_str(&std::env::var("KMS_PROVIDERS").unwrap()).unwrap(); + pub(crate) static ref KMIP_TLS_OPTIONS: crate::client::csfle::options::KmsProvidersTlsOptions = { + let cert_dir = std::path::PathBuf::from(std::env::var("CSFLE_TLS_CERT_DIR").unwrap()); + let kmip_opts = crate::client::options::TlsOptions::builder() + .ca_file_path(cert_dir.join("ca.pem")) + .cert_key_file_path(cert_dir.join("client.pem")) + .build(); + [(mongocrypt::ctx::KmsProvider::Kmip, kmip_opts)].into_iter().collect() + }; } // conditional definitions do not work within the lazy_static! macro, so this diff --git a/src/test/spec/unified_runner/operation.rs b/src/test/spec/unified_runner/operation.rs index a3d60a874..1735942e7 100644 --- a/src/test/spec/unified_runner/operation.rs +++ b/src/test/spec/unified_runner/operation.rs @@ -352,6 +352,12 @@ impl<'de> Deserialize<'de> for Operation { "delete" => deserialize_op::(definition.arguments), "upload" => deserialize_op::(definition.arguments), "getKeyByAltName" => deserialize_op::(definition.arguments), + "deleteKey" => deserialize_op::(definition.arguments), + "getKey" => deserialize_op::(definition.arguments), + "addKeyAltName" => deserialize_op::(definition.arguments), + "createDataKey" => deserialize_op::(definition.arguments), + "getKeys" => deserialize_op::(definition.arguments), + "removeKeyAltName" => deserialize_op::(definition.arguments), s => Ok(Box::new(UnimplementedOperation { _name: s.to_string() }) as Box), } .map_err(|e| serde::de::Error::custom(format!("{}", e)))?; @@ -2859,9 +2865,158 @@ impl TestOperation for GetKeyByAltName { } .boxed() } +} - fn returns_root_documents(&self) -> bool { - true +#[cfg(feature = "csfle")] +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +pub(super) struct DeleteKey { + id: bson::Binary, +} + +#[cfg(feature = "csfle")] +impl TestOperation for DeleteKey { + fn execute_entity_operation<'a>( + &'a self, + id: &'a str, + test_runner: &'a TestRunner, + ) -> BoxFuture<'a, Result>> { + async move { + let ce = test_runner.get_client_encryption(id).await; + let result = ce.delete_key(&self.id).await?; + Ok(Some(Entity::Bson(Bson::Document(bson::to_document(&result)?)))) + } + .boxed() + } +} + +#[cfg(feature = "csfle")] +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +pub(super) struct GetKey { + id: bson::Binary, +} + +#[cfg(feature = "csfle")] +impl TestOperation for GetKey { + fn execute_entity_operation<'a>( + &'a self, + id: &'a str, + test_runner: &'a TestRunner, + ) -> BoxFuture<'a, Result>> { + async move { + let ce = test_runner.get_client_encryption(id).await; + let entity = match ce.get_key(&self.id).await? { + Some(key) => Entity::Bson(Bson::Document(key.to_document()?)), + None => Entity::None, + }; + Ok(Some(entity)) + } + .boxed() + } +} + +#[cfg(feature = "csfle")] +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +pub(super) struct AddKeyAltName { + id: bson::Binary, + key_alt_name: String, +} + +#[cfg(feature = "csfle")] +impl TestOperation for AddKeyAltName { + fn execute_entity_operation<'a>( + &'a self, + id: &'a str, + test_runner: &'a TestRunner, + ) -> BoxFuture<'a, Result>> { + async move { + let ce = test_runner.get_client_encryption(id).await; + let entity = match ce.add_key_alt_name(&self.id, &self.key_alt_name).await? { + Some(key) => Entity::Bson(Bson::Document(key.to_document()?)), + None => Entity::None, + }; + Ok(Some(entity)) + } + .boxed() + } +} + +#[cfg(feature = "csfle")] +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +pub(super) struct CreateDataKey { + kms_provider: mongocrypt::ctx::KmsProvider, + opts: Option, +} + +#[cfg(feature = "csfle")] +impl TestOperation for CreateDataKey { + fn execute_entity_operation<'a>( + &'a self, + id: &'a str, + test_runner: &'a TestRunner, + ) -> BoxFuture<'a, Result>> { + async move { + let ce = test_runner.get_client_encryption(id).await; + let key = ce.create_data_key(&self.kms_provider, self.opts.clone()).await?; + Ok(Some(Entity::Bson(Bson::Binary(key)))) + } + .boxed() + } +} + +#[cfg(feature = "csfle")] +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +pub(super) struct GetKeys { +} + +#[cfg(feature = "csfle")] +impl TestOperation for GetKeys { + fn execute_entity_operation<'a>( + &'a self, + id: &'a str, + test_runner: &'a TestRunner, + ) -> BoxFuture<'a, Result>> { + async move { + let ce = test_runner.get_client_encryption(id).await; + let mut cursor = ce.get_keys().await?; + let mut keys = vec![]; + while let Some(key) = cursor.try_next().await? { + keys.push(Bson::Document(key.to_document()?)); + } + Ok(Some(Entity::Bson(Bson::Array(keys)))) + } + .boxed() + } +} + +#[cfg(feature = "csfle")] +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +pub(super) struct RemoveKeyAltName { + id: bson::Binary, + key_alt_name: String, +} + +#[cfg(feature = "csfle")] +impl TestOperation for RemoveKeyAltName { + fn execute_entity_operation<'a>( + &'a self, + id: &'a str, + test_runner: &'a TestRunner, + ) -> BoxFuture<'a, Result>> { + async move { + let ce = test_runner.get_client_encryption(id).await; + let entity = match ce.remove_key_alt_name(&self.id, &self.key_alt_name).await? { + Some(key) => Entity::Bson(Bson::Document(key.to_document()?)), + None => Entity::None, + }; + Ok(Some(entity)) + } + .boxed() } } diff --git a/src/test/spec/unified_runner/test_runner.rs b/src/test/spec/unified_runner/test_runner.rs index f9b6c217c..ae84ca73c 100644 --- a/src/test/spec/unified_runner/test_runner.rs +++ b/src/test/spec/unified_runner/test_runner.rs @@ -556,6 +556,7 @@ impl TestRunner { .key_vault_client(kv_client) .key_vault_namespace(kv_namespace) .kms_providers(kms_providers) + .tls_options(crate::test::KMIP_TLS_OPTIONS.clone()) .build() ).unwrap(); ( @@ -680,12 +681,13 @@ fn fill_kms_placeholders(kms_providers: &mut KmsProviders) { for (provider, config) in kms_providers.iter_mut() { for (key, value) in config.iter_mut() { if *value == placeholder { - *value = KMS_PROVIDERS + let new_value = KMS_PROVIDERS .get(provider) .expect(&format!("missing config for {:?}", provider)) .get(key) .expect(&format!("provider config {:?} missing key {:?}", provider, key)) .clone(); + *value = new_value; } } } From c2c43195891dad8e70db10ab3bb7e97797c4cdec Mon Sep 17 00:00:00 2001 From: Abraham Egnor Date: Wed, 2 Nov 2022 12:14:04 -0400 Subject: [PATCH 06/10] tidy --- .evergreen/run-csfle-tests.sh | 5 ++- src/client/csfle/client_encryption.rs | 2 +- src/test/csfle.rs | 3 +- src/test/mod.rs | 7 +++-- src/test/spec/client_side_encryption.rs | 24 +++------------ src/test/spec/mod.rs | 2 +- src/test/spec/unified_runner/entity.rs | 1 + src/test/spec/unified_runner/operation.rs | 34 ++++++++++++++++----- src/test/spec/unified_runner/test_runner.rs | 29 +++++++++++------- 9 files changed, 63 insertions(+), 44 deletions(-) diff --git a/.evergreen/run-csfle-tests.sh b/.evergreen/run-csfle-tests.sh index 5f064d568..c2a9bcf87 100755 --- a/.evergreen/run-csfle-tests.sh +++ b/.evergreen/run-csfle-tests.sh @@ -32,6 +32,9 @@ cargo_test() { set +o errexit -cargo_test test::csfle > results.xml +cargo_test test::csfle > prose.xml +cargo_test test::spec::client_side_encryption > spec.xml + +junit-report-merger results.xml prose.xml spec.xml exit ${CARGO_RESULT} diff --git a/src/client/csfle/client_encryption.rs b/src/client/csfle/client_encryption.rs index 2f734b098..73d1e0c91 100644 --- a/src/client/csfle/client_encryption.rs +++ b/src/client/csfle/client_encryption.rs @@ -16,7 +16,7 @@ use mongocrypt::{ ctx::{Algorithm, Ctx, KmsProvider}, Crypt, }; -use serde::{Serialize, Deserialize}; +use serde::{Deserialize, Serialize}; use typed_builder::TypedBuilder; use super::{ diff --git a/src/test/csfle.rs b/src/test/csfle.rs index 37ec8bdba..f90084740 100644 --- a/src/test/csfle.rs +++ b/src/test/csfle.rs @@ -92,7 +92,8 @@ lazy_static! { out.retain(|k, _| *k == KmsProvider::Local); out }; - static ref EXTRA_OPTIONS: Document = doc! { "cryptSharedLibPath": std::env::var("CSFLE_SHARED_LIB_PATH").unwrap() }; + static ref EXTRA_OPTIONS: Document = + doc! { "cryptSharedLibPath": std::env::var("CSFLE_SHARED_LIB_PATH").unwrap() }; static ref KV_NAMESPACE: Namespace = Namespace::from_str("keyvault.datakeys").unwrap(); static ref DISABLE_CRYPT_SHARED: bool = std::env::var("DISABLE_CRYPT_SHARED") .map_or(false, |s| s == "true"); diff --git a/src/test/mod.rs b/src/test/mod.rs index b717584a5..8939bb713 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -91,14 +91,17 @@ lazy_static! { #[cfg(feature = "csfle")] lazy_static! { - pub(crate) static ref KMS_PROVIDERS: crate::client::csfle::options::KmsProviders = serde_json::from_str(&std::env::var("KMS_PROVIDERS").unwrap()).unwrap(); + pub(crate) static ref KMS_PROVIDERS: crate::client::csfle::options::KmsProviders = + serde_json::from_str(&std::env::var("KMS_PROVIDERS").unwrap()).unwrap(); pub(crate) static ref KMIP_TLS_OPTIONS: crate::client::csfle::options::KmsProvidersTlsOptions = { let cert_dir = std::path::PathBuf::from(std::env::var("CSFLE_TLS_CERT_DIR").unwrap()); let kmip_opts = crate::client::options::TlsOptions::builder() .ca_file_path(cert_dir.join("ca.pem")) .cert_key_file_path(cert_dir.join("client.pem")) .build(); - [(mongocrypt::ctx::KmsProvider::Kmip, kmip_opts)].into_iter().collect() + [(mongocrypt::ctx::KmsProvider::Kmip, kmip_opts)] + .into_iter() + .collect() }; } diff --git a/src/test/spec/client_side_encryption.rs b/src/test/spec/client_side_encryption.rs index 35441ed59..09c63a8ab 100644 --- a/src/test/spec/client_side_encryption.rs +++ b/src/test/spec/client_side_encryption.rs @@ -2,29 +2,15 @@ use tokio::sync::RwLockWriteGuard; use crate::test::LOCK; -use super::{run_spec_test_with_path, run_unified_format_test_filtered, unified_runner::TestCase}; +use super::{run_spec_test_with_path, run_unified_format_test}; #[cfg_attr(feature = "tokio-runtime", tokio::test(flavor = "multi_thread"))] #[cfg_attr(feature = "async-std-runtime", async_std::test)] async fn run() { let _guard: RwLockWriteGuard<()> = LOCK.run_exclusively().await; - run_spec_test_with_path(&["client-side-encryption", "unified"], |path, file| { - run_unified_format_test_filtered(path, file, test_predicate) - }) + run_spec_test_with_path( + &["client-side-encryption", "unified"], + run_unified_format_test, + ) .await; } - -fn test_predicate(_test: &TestCase) -> bool { - true - /* - // The Rust driver doesn't support unacknowledged writes. - let lower = test.description.to_lowercase(); - - !lower.contains("unacknowledged") - // TODO: RUST-663: unskip aggregate $out and $merge tests - && !(lower.contains("aggregate with $out includes read preference for 5.0+ server")) - && !(lower.contains("aggregate with $out omits read preference for pre-5.0 server")) - && !(lower.contains("aggregate with $merge includes read preference for 5.0+ server")) - && !(lower.contains("aggregate with $merge omits read preference for pre-5.0 server")) - */ -} diff --git a/src/test/spec/mod.rs b/src/test/spec/mod.rs index 8cc196167..a753e60df 100644 --- a/src/test/spec/mod.rs +++ b/src/test/spec/mod.rs @@ -71,7 +71,7 @@ where .chain(spec.iter()) .collect(); - for entry in fs::read_dir(&base_path).expect(&format!("reading {:?}", base_path)) { + for entry in fs::read_dir(&base_path).unwrap_or_else(|_| panic!("reading {:?}", base_path)) { let test_file = entry.unwrap(); if !test_file.file_type().unwrap().is_file() { diff --git a/src/test/spec/unified_runner/entity.rs b/src/test/spec/unified_runner/entity.rs index ac8e3b407..a1372b539 100644 --- a/src/test/spec/unified_runner/entity.rs +++ b/src/test/spec/unified_runner/entity.rs @@ -210,6 +210,7 @@ impl ClientEntity { } } + #[allow(dead_code)] pub(crate) fn client(&self) -> Option<&Client> { self.client.as_ref() } diff --git a/src/test/spec/unified_runner/operation.rs b/src/test/spec/unified_runner/operation.rs index 1735942e7..285394369 100644 --- a/src/test/spec/unified_runner/operation.rs +++ b/src/test/spec/unified_runner/operation.rs @@ -80,7 +80,10 @@ pub(crate) trait TestOperation: Debug + Send + Sync { &'a self, _test_runner: &'a TestRunner, ) -> BoxFuture<'a, ()> { - panic!("execute_test_runner_operation called on unsupported operation {:?}", self) + panic!( + "execute_test_runner_operation called on unsupported operation {:?}", + self + ) } fn execute_entity_operation<'a>( @@ -90,7 +93,10 @@ pub(crate) trait TestOperation: Debug + Send + Sync { ) -> BoxFuture<'a, Result>> { async move { Err(ErrorKind::InvalidArgument { - message: format!("execute_entity_operation called on unsupported operation {:?}", self), + message: format!( + "execute_entity_operation called on unsupported operation {:?}", + self + ), } .into()) } @@ -188,7 +194,7 @@ impl Operation { ) { panic!( "[{}] result mismatch, expected = {:#?} actual = \ - {:#?}\nmismatch detail: {}", + {:#?}\nmismatch detail: {}", description, expected_bson, actual, e ); } @@ -351,14 +357,23 @@ impl<'de> Deserialize<'de> for Operation { "downloadByName" => deserialize_op::(definition.arguments), "delete" => deserialize_op::(definition.arguments), "upload" => deserialize_op::(definition.arguments), + #[cfg(feature = "csfle")] "getKeyByAltName" => deserialize_op::(definition.arguments), + #[cfg(feature = "csfle")] "deleteKey" => deserialize_op::(definition.arguments), + #[cfg(feature = "csfle")] "getKey" => deserialize_op::(definition.arguments), + #[cfg(feature = "csfle")] "addKeyAltName" => deserialize_op::(definition.arguments), + #[cfg(feature = "csfle")] "createDataKey" => deserialize_op::(definition.arguments), + #[cfg(feature = "csfle")] "getKeys" => deserialize_op::(definition.arguments), + #[cfg(feature = "csfle")] "removeKeyAltName" => deserialize_op::(definition.arguments), - s => Ok(Box::new(UnimplementedOperation { _name: s.to_string() }) as Box), + s => Ok(Box::new(UnimplementedOperation { + _name: s.to_string(), + }) as Box), } .map_err(|e| serde::de::Error::custom(format!("{}", e)))?; @@ -2884,7 +2899,9 @@ impl TestOperation for DeleteKey { async move { let ce = test_runner.get_client_encryption(id).await; let result = ce.delete_key(&self.id).await?; - Ok(Some(Entity::Bson(Bson::Document(bson::to_document(&result)?)))) + Ok(Some(Entity::Bson(Bson::Document(bson::to_document( + &result, + )?)))) } .boxed() } @@ -2960,7 +2977,9 @@ impl TestOperation for CreateDataKey { ) -> BoxFuture<'a, Result>> { async move { let ce = test_runner.get_client_encryption(id).await; - let key = ce.create_data_key(&self.kms_provider, self.opts.clone()).await?; + let key = ce + .create_data_key(&self.kms_provider, self.opts.clone()) + .await?; Ok(Some(Entity::Bson(Bson::Binary(key)))) } .boxed() @@ -2970,8 +2989,7 @@ impl TestOperation for CreateDataKey { #[cfg(feature = "csfle")] #[derive(Debug, Deserialize)] #[serde(rename_all = "camelCase", deny_unknown_fields)] -pub(super) struct GetKeys { -} +pub(super) struct GetKeys {} #[cfg(feature = "csfle")] impl TestOperation for GetKeys { diff --git a/src/test/spec/unified_runner/test_runner.rs b/src/test/spec/unified_runner/test_runner.rs index ae84ca73c..e52c99cfd 100644 --- a/src/test/spec/unified_runner/test_runner.rs +++ b/src/test/spec/unified_runner/test_runner.rs @@ -547,9 +547,16 @@ impl TestRunner { TestFileEntity::ClientEncryption(client_enc) => { let id = client_enc.id.clone(); let opts = &client_enc.client_encryption_opts; - let kv_client = self.get_client(&opts.key_vault_client).await.client().unwrap().clone(); - let kv_namespace = crate::Namespace::from_str(&opts.key_vault_namespace).unwrap(); - let mut kms_providers: KmsProviders = bson::from_document(opts.kms_providers.clone()).unwrap(); + let kv_client = self + .get_client(&opts.key_vault_client) + .await + .client() + .unwrap() + .clone(); + let kv_namespace = + crate::Namespace::from_str(&opts.key_vault_namespace).unwrap(); + let mut kms_providers: KmsProviders = + bson::from_document(opts.kms_providers.clone()).unwrap(); fill_kms_placeholders(&mut kms_providers); let client_enc = crate::client_encryption::ClientEncryption::new( crate::client_encryption::ClientEncryptionOptions::builder() @@ -557,12 +564,10 @@ impl TestRunner { .key_vault_namespace(kv_namespace) .kms_providers(kms_providers) .tls_options(crate::test::KMIP_TLS_OPTIONS.clone()) - .build() - ).unwrap(); - ( - id, - Entity::ClientEncryption(Arc::new(client_enc)), + .build(), ) + .unwrap(); + (id, Entity::ClientEncryption(Arc::new(client_enc))) } }; self.insert_entity(&id, entity).await; @@ -683,12 +688,14 @@ fn fill_kms_placeholders(kms_providers: &mut KmsProviders) { if *value == placeholder { let new_value = KMS_PROVIDERS .get(provider) - .expect(&format!("missing config for {:?}", provider)) + .unwrap_or_else(|| panic!("missing config for {:?}", provider)) .get(key) - .expect(&format!("provider config {:?} missing key {:?}", provider, key)) + .unwrap_or_else(|| { + panic!("provider config {:?} missing key {:?}", provider, key) + }) .clone(); *value = new_value; } } } -} \ No newline at end of file +} From 035dbe684b95e857bc910a1df237b727214ddf0b Mon Sep 17 00:00:00 2001 From: Abraham Egnor Date: Wed, 2 Nov 2022 12:26:42 -0400 Subject: [PATCH 07/10] update patch --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index b3fdd13fa..0fc617c4a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -76,7 +76,7 @@ csfle = ["mongocrypt", "rayon", "num_cpus"] tracing-unstable = ["tracing", "log"] [patch."https://github.com/mongodb/bson-rust"] -bson = { path = "../../bson-rust/minor_iter_mut" } +bson = { git = "https://github.com/abr-egn/bson-rust", branch = "minor/iter_mut" } [dependencies] async-trait = "0.1.42" From b78ed21bd169fef9b8bf5768859b80e1647a2147 Mon Sep 17 00:00:00 2001 From: Abraham Egnor Date: Fri, 4 Nov 2022 10:37:01 -0400 Subject: [PATCH 08/10] review updates --- Cargo.toml | 3 --- src/test/spec/unified_runner/test_file.rs | 2 +- src/test/spec/unified_runner/test_runner.rs | 4 +--- 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 0fc617c4a..2995440d3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -75,9 +75,6 @@ csfle = ["mongocrypt", "rayon", "num_cpus"] # TODO: pending https://github.com/tokio-rs/tracing/issues/2036 stop depending directly on log. tracing-unstable = ["tracing", "log"] -[patch."https://github.com/mongodb/bson-rust"] -bson = { git = "https://github.com/abr-egn/bson-rust", branch = "minor/iter_mut" } - [dependencies] async-trait = "0.1.42" base64 = "0.13.0" diff --git a/src/test/spec/unified_runner/test_file.rs b/src/test/spec/unified_runner/test_file.rs index 939db8e49..976eaad07 100644 --- a/src/test/spec/unified_runner/test_file.rs +++ b/src/test/spec/unified_runner/test_file.rs @@ -330,7 +330,7 @@ pub(crate) struct ClientEncryption { #[serde(rename_all = "camelCase", deny_unknown_fields)] pub(crate) struct ClientEncryptionOpts { pub(crate) key_vault_client: String, - pub(crate) key_vault_namespace: String, + pub(crate) key_vault_namespace: crate::Namespace, pub(crate) kms_providers: Document, } diff --git a/src/test/spec/unified_runner/test_runner.rs b/src/test/spec/unified_runner/test_runner.rs index e52c99cfd..3dcc2984a 100644 --- a/src/test/spec/unified_runner/test_runner.rs +++ b/src/test/spec/unified_runner/test_runner.rs @@ -553,15 +553,13 @@ impl TestRunner { .client() .unwrap() .clone(); - let kv_namespace = - crate::Namespace::from_str(&opts.key_vault_namespace).unwrap(); let mut kms_providers: KmsProviders = bson::from_document(opts.kms_providers.clone()).unwrap(); fill_kms_placeholders(&mut kms_providers); let client_enc = crate::client_encryption::ClientEncryption::new( crate::client_encryption::ClientEncryptionOptions::builder() .key_vault_client(kv_client) - .key_vault_namespace(kv_namespace) + .key_vault_namespace(opts.key_vault_namespace.clone()) .kms_providers(kms_providers) .tls_options(crate::test::KMIP_TLS_OPTIONS.clone()) .build(), From c82ae156d5d7c879c58c8eada71eef7e94424727 Mon Sep 17 00:00:00 2001 From: Abraham Egnor Date: Wed, 9 Nov 2022 12:25:06 -0500 Subject: [PATCH 09/10] review updates --- src/client/csfle/client_encryption.rs | 27 --- src/test/spec/unified_runner/entity.rs | 10 +- src/test/spec/unified_runner/operation.rs | 188 +--------------- .../spec/unified_runner/operation/csfle.rs | 202 ++++++++++++++++++ src/test/spec/unified_runner/test_file.rs | 30 ++- src/test/spec/unified_runner/test_runner.rs | 22 +- 6 files changed, 251 insertions(+), 228 deletions(-) create mode 100644 src/test/spec/unified_runner/operation/csfle.rs diff --git a/src/client/csfle/client_encryption.rs b/src/client/csfle/client_encryption.rs index 73d1e0c91..eac879c4e 100644 --- a/src/client/csfle/client_encryption.rs +++ b/src/client/csfle/client_encryption.rs @@ -32,12 +32,6 @@ pub struct ClientEncryption { key_vault: Collection, } -impl std::fmt::Debug for ClientEncryption { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("ClientEncryption").finish() - } -} - impl ClientEncryption { /// Create a new key vault handle with the given options. pub fn new(options: ClientEncryptionOptions) -> Result { @@ -277,27 +271,6 @@ pub struct DataKeyOptions { pub key_material: Option>, } -impl<'de> Deserialize<'de> for DataKeyOptions { - fn deserialize(deserializer: D) -> std::result::Result - where - D: serde::Deserializer<'de>, - { - #[derive(Deserialize)] - #[serde(rename_all = "camelCase")] - struct Helper { - master_key: Option, - key_alt_names: Option>, - key_material: Option, - } - let h = Helper::deserialize(deserializer)?; - Ok(DataKeyOptions { - master_key: h.master_key.unwrap_or(MasterKey::Local), - key_alt_names: h.key_alt_names, - key_material: h.key_material.map(|bin| bin.bytes), - }) - } -} - /// A KMS-specific key used to encrypt data keys. #[serde_with::skip_serializing_none] #[derive(Debug, Clone, Serialize, Deserialize)] diff --git a/src/test/spec/unified_runner/entity.rs b/src/test/spec/unified_runner/entity.rs index a1372b539..446225b7f 100644 --- a/src/test/spec/unified_runner/entity.rs +++ b/src/test/spec/unified_runner/entity.rs @@ -49,6 +49,14 @@ pub(crate) enum Entity { ClientEncryption(Arc), None, } + +#[cfg(feature = "csfle")] +impl std::fmt::Debug for crate::client_encryption::ClientEncryption { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("ClientEncryption").finish() + } +} + #[derive(Clone, Debug)] pub(crate) struct ClientEntity { /// This is None if a `close` operation has been executed for this entity. @@ -210,7 +218,7 @@ impl ClientEntity { } } - #[allow(dead_code)] + #[cfg(feature = "csfle")] pub(crate) fn client(&self) -> Option<&Client> { self.client.as_ref() } diff --git a/src/test/spec/unified_runner/operation.rs b/src/test/spec/unified_runner/operation.rs index 285394369..0fc02e069 100644 --- a/src/test/spec/unified_runner/operation.rs +++ b/src/test/spec/unified_runner/operation.rs @@ -1,3 +1,8 @@ +#[cfg(feature = "csfle")] +mod csfle; +#[cfg(feature = "csfle")] +use self::csfle::*; + use std::{ collections::HashMap, convert::TryInto, @@ -2855,189 +2860,6 @@ impl TestOperation for Upload { } } -#[cfg(feature = "csfle")] -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase", deny_unknown_fields)] -pub(super) struct GetKeyByAltName { - key_alt_name: String, -} - -#[cfg(feature = "csfle")] -impl TestOperation for GetKeyByAltName { - fn execute_entity_operation<'a>( - &'a self, - id: &'a str, - test_runner: &'a TestRunner, - ) -> BoxFuture<'a, Result>> { - async move { - let ce = test_runner.get_client_encryption(id).await; - let key = ce.get_key_by_alt_name(&self.key_alt_name).await?; - let ent = match key { - Some(rd) => Entity::Bson(Bson::Document(rd.to_document()?)), - None => Entity::None, - }; - Ok(Some(ent)) - } - .boxed() - } -} - -#[cfg(feature = "csfle")] -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase", deny_unknown_fields)] -pub(super) struct DeleteKey { - id: bson::Binary, -} - -#[cfg(feature = "csfle")] -impl TestOperation for DeleteKey { - fn execute_entity_operation<'a>( - &'a self, - id: &'a str, - test_runner: &'a TestRunner, - ) -> BoxFuture<'a, Result>> { - async move { - let ce = test_runner.get_client_encryption(id).await; - let result = ce.delete_key(&self.id).await?; - Ok(Some(Entity::Bson(Bson::Document(bson::to_document( - &result, - )?)))) - } - .boxed() - } -} - -#[cfg(feature = "csfle")] -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase", deny_unknown_fields)] -pub(super) struct GetKey { - id: bson::Binary, -} - -#[cfg(feature = "csfle")] -impl TestOperation for GetKey { - fn execute_entity_operation<'a>( - &'a self, - id: &'a str, - test_runner: &'a TestRunner, - ) -> BoxFuture<'a, Result>> { - async move { - let ce = test_runner.get_client_encryption(id).await; - let entity = match ce.get_key(&self.id).await? { - Some(key) => Entity::Bson(Bson::Document(key.to_document()?)), - None => Entity::None, - }; - Ok(Some(entity)) - } - .boxed() - } -} - -#[cfg(feature = "csfle")] -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase", deny_unknown_fields)] -pub(super) struct AddKeyAltName { - id: bson::Binary, - key_alt_name: String, -} - -#[cfg(feature = "csfle")] -impl TestOperation for AddKeyAltName { - fn execute_entity_operation<'a>( - &'a self, - id: &'a str, - test_runner: &'a TestRunner, - ) -> BoxFuture<'a, Result>> { - async move { - let ce = test_runner.get_client_encryption(id).await; - let entity = match ce.add_key_alt_name(&self.id, &self.key_alt_name).await? { - Some(key) => Entity::Bson(Bson::Document(key.to_document()?)), - None => Entity::None, - }; - Ok(Some(entity)) - } - .boxed() - } -} - -#[cfg(feature = "csfle")] -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase", deny_unknown_fields)] -pub(super) struct CreateDataKey { - kms_provider: mongocrypt::ctx::KmsProvider, - opts: Option, -} - -#[cfg(feature = "csfle")] -impl TestOperation for CreateDataKey { - fn execute_entity_operation<'a>( - &'a self, - id: &'a str, - test_runner: &'a TestRunner, - ) -> BoxFuture<'a, Result>> { - async move { - let ce = test_runner.get_client_encryption(id).await; - let key = ce - .create_data_key(&self.kms_provider, self.opts.clone()) - .await?; - Ok(Some(Entity::Bson(Bson::Binary(key)))) - } - .boxed() - } -} - -#[cfg(feature = "csfle")] -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase", deny_unknown_fields)] -pub(super) struct GetKeys {} - -#[cfg(feature = "csfle")] -impl TestOperation for GetKeys { - fn execute_entity_operation<'a>( - &'a self, - id: &'a str, - test_runner: &'a TestRunner, - ) -> BoxFuture<'a, Result>> { - async move { - let ce = test_runner.get_client_encryption(id).await; - let mut cursor = ce.get_keys().await?; - let mut keys = vec![]; - while let Some(key) = cursor.try_next().await? { - keys.push(Bson::Document(key.to_document()?)); - } - Ok(Some(Entity::Bson(Bson::Array(keys)))) - } - .boxed() - } -} - -#[cfg(feature = "csfle")] -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase", deny_unknown_fields)] -pub(super) struct RemoveKeyAltName { - id: bson::Binary, - key_alt_name: String, -} - -#[cfg(feature = "csfle")] -impl TestOperation for RemoveKeyAltName { - fn execute_entity_operation<'a>( - &'a self, - id: &'a str, - test_runner: &'a TestRunner, - ) -> BoxFuture<'a, Result>> { - async move { - let ce = test_runner.get_client_encryption(id).await; - let entity = match ce.remove_key_alt_name(&self.id, &self.key_alt_name).await? { - Some(key) => Entity::Bson(Bson::Document(key.to_document()?)), - None => Entity::None, - }; - Ok(Some(entity)) - } - .boxed() - } -} - #[derive(Debug, Deserialize)] pub(super) struct UnimplementedOperation { _name: String, diff --git a/src/test/spec/unified_runner/operation/csfle.rs b/src/test/spec/unified_runner/operation/csfle.rs new file mode 100644 index 000000000..93acf0e7d --- /dev/null +++ b/src/test/spec/unified_runner/operation/csfle.rs @@ -0,0 +1,202 @@ +use std::fmt::Debug; + +use futures::{future::BoxFuture, stream::TryStreamExt, FutureExt}; +use serde::Deserialize; + +use super::{Entity, TestOperation, TestRunner}; + +use crate::{ + bson::{doc, Bson}, + client_encryption::{DataKeyOptions, MasterKey}, + error::Result, +}; + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +pub(super) struct GetKeyByAltName { + key_alt_name: String, +} + +impl TestOperation for GetKeyByAltName { + fn execute_entity_operation<'a>( + &'a self, + id: &'a str, + test_runner: &'a TestRunner, + ) -> BoxFuture<'a, Result>> { + async move { + let ce = test_runner.get_client_encryption(id).await; + let key = ce.get_key_by_alt_name(&self.key_alt_name).await?; + let ent = match key { + Some(rd) => Entity::Bson(Bson::Document(rd.to_document()?)), + None => Entity::None, + }; + Ok(Some(ent)) + } + .boxed() + } +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +pub(super) struct DeleteKey { + id: bson::Binary, +} + +impl TestOperation for DeleteKey { + fn execute_entity_operation<'a>( + &'a self, + id: &'a str, + test_runner: &'a TestRunner, + ) -> BoxFuture<'a, Result>> { + async move { + let ce = test_runner.get_client_encryption(id).await; + let result = ce.delete_key(&self.id).await?; + Ok(Some(Entity::Bson(Bson::Document(bson::to_document( + &result, + )?)))) + } + .boxed() + } +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +pub(super) struct GetKey { + id: bson::Binary, +} + +impl TestOperation for GetKey { + fn execute_entity_operation<'a>( + &'a self, + id: &'a str, + test_runner: &'a TestRunner, + ) -> BoxFuture<'a, Result>> { + async move { + let ce = test_runner.get_client_encryption(id).await; + let entity = match ce.get_key(&self.id).await? { + Some(key) => Entity::Bson(Bson::Document(key.to_document()?)), + None => Entity::None, + }; + Ok(Some(entity)) + } + .boxed() + } +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +pub(super) struct AddKeyAltName { + id: bson::Binary, + key_alt_name: String, +} + +impl TestOperation for AddKeyAltName { + fn execute_entity_operation<'a>( + &'a self, + id: &'a str, + test_runner: &'a TestRunner, + ) -> BoxFuture<'a, Result>> { + async move { + let ce = test_runner.get_client_encryption(id).await; + let entity = match ce.add_key_alt_name(&self.id, &self.key_alt_name).await? { + Some(key) => Entity::Bson(Bson::Document(key.to_document()?)), + None => Entity::None, + }; + Ok(Some(entity)) + } + .boxed() + } +} + +impl<'de> Deserialize<'de> for DataKeyOptions { + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + #[serde(rename_all = "camelCase")] + struct Helper { + master_key: Option, + key_alt_names: Option>, + key_material: Option, + } + let h = Helper::deserialize(deserializer)?; + Ok(DataKeyOptions { + master_key: h.master_key.unwrap_or(MasterKey::Local), + key_alt_names: h.key_alt_names, + key_material: h.key_material.map(|bin| bin.bytes), + }) + } +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +pub(super) struct CreateDataKey { + kms_provider: mongocrypt::ctx::KmsProvider, + opts: Option, +} + +impl TestOperation for CreateDataKey { + fn execute_entity_operation<'a>( + &'a self, + id: &'a str, + test_runner: &'a TestRunner, + ) -> BoxFuture<'a, Result>> { + async move { + let ce = test_runner.get_client_encryption(id).await; + let key = ce + .create_data_key(&self.kms_provider, self.opts.clone()) + .await?; + Ok(Some(Entity::Bson(Bson::Binary(key)))) + } + .boxed() + } +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +pub(super) struct GetKeys {} + +impl TestOperation for GetKeys { + fn execute_entity_operation<'a>( + &'a self, + id: &'a str, + test_runner: &'a TestRunner, + ) -> BoxFuture<'a, Result>> { + async move { + let ce = test_runner.get_client_encryption(id).await; + let mut cursor = ce.get_keys().await?; + let mut keys = vec![]; + while let Some(key) = cursor.try_next().await? { + keys.push(Bson::Document(key.to_document()?)); + } + Ok(Some(Entity::Bson(Bson::Array(keys)))) + } + .boxed() + } +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +pub(super) struct RemoveKeyAltName { + id: bson::Binary, + key_alt_name: String, +} + +impl TestOperation for RemoveKeyAltName { + fn execute_entity_operation<'a>( + &'a self, + id: &'a str, + test_runner: &'a TestRunner, + ) -> BoxFuture<'a, Result>> { + async move { + let ce = test_runner.get_client_encryption(id).await; + let entity = match ce.remove_key_alt_name(&self.id, &self.key_alt_name).await? { + Some(key) => Entity::Bson(Bson::Document(key.to_document()?)), + None => Entity::None, + }; + Ok(Some(entity)) + } + .boxed() + } +} diff --git a/src/test/spec/unified_runner/test_file.rs b/src/test/spec/unified_runner/test_file.rs index 976eaad07..0f8558a02 100644 --- a/src/test/spec/unified_runner/test_file.rs +++ b/src/test/spec/unified_runner/test_file.rs @@ -88,17 +88,23 @@ pub(crate) enum Topology { } impl RunOnRequirement { - pub(crate) async fn can_run_on(&self, client: &TestClient) -> bool { + pub(crate) async fn can_run_on(&self, client: &TestClient) -> Result<(), String> { if let Some(ref min_version) = self.min_server_version { let req = VersionReq::parse(&format!(">= {}", &min_version)).unwrap(); if !req.matches(&client.server_version) { - return false; + return Err(format!( + "min server version {:?}, actual {:?}", + min_version, client.server_version + )); } } if let Some(ref max_version) = self.max_server_version { let req = VersionReq::parse(&format!("<= {}", &max_version)).unwrap(); if !req.matches(&client.server_version) { - return false; + return Err(format!( + "max server version {:?}, actual {:?}", + max_version, client.server_version + )); } } if let Some(ref topologies) = self.topologies { @@ -109,7 +115,10 @@ impl RunOnRequirement { _ => expected_topology == &client_topology, } }) { - return false; + return Err(format!( + "allowed topologies {:?}, actual {:?}", + topologies, client_topology + )); } } if let Some(ref actual_server_parameters) = self.server_parameters { @@ -121,25 +130,28 @@ impl RunOnRequirement { ) .is_err() { - return false; + return Err(format!( + "required server parameters {:?}, actual {:?}", + actual_server_parameters, client.server_parameters + )); } } if let Some(ref serverless) = self.serverless { if !serverless.can_run() { - return false; + return Err("requires serverless".to_string()); } } if let Some(ref auth) = self.auth { if *auth != client.auth_enabled() { - return false; + return Err("requires auth".to_string()); } } if let Some(csfle) = &self.csfle { if *csfle && std::env::var("KMS_PROVIDERS").is_err() { - return false; + return Err("requires csfle env".to_string()); } } - true + Ok(()) } } diff --git a/src/test/spec/unified_runner/test_runner.rs b/src/test/spec/unified_runner/test_runner.rs index 3dcc2984a..2ae15eac7 100644 --- a/src/test/spec/unified_runner/test_runner.rs +++ b/src/test/spec/unified_runner/test_runner.rs @@ -118,15 +118,18 @@ impl TestRunner { if let Some(ref requirements) = test_file.run_on_requirements { let mut can_run_on = false; + let mut run_on_errors = vec![]; for requirement in requirements { - if requirement.can_run_on(&self.internal_client).await { - can_run_on = true; + match requirement.can_run_on(&self.internal_client).await { + Ok(()) => can_run_on = true, + Err(e) => run_on_errors.push(e), } } if !can_run_on { file_level_log(format!( - "Skipping file {}: client topology not compatible with test", - file_title + "Skipping file {}: client topology not compatible with test ({})", + file_title, + run_on_errors.join(","), )); return; } @@ -179,15 +182,18 @@ impl TestRunner { if let Some(ref requirements) = test_case.run_on_requirements { let mut can_run_on = false; + let mut run_on_errors = vec![]; for requirement in requirements { - if requirement.can_run_on(&self.internal_client).await { - can_run_on = true; + match requirement.can_run_on(&self.internal_client).await { + Ok(()) => can_run_on = true, + Err(e) => run_on_errors.push(e), } } if !can_run_on { log_uncaptured(format!( - "Skipping test case {:?}: client topology not compatible with test", - &test_case.description + "Skipping test case {:?}: client topology not compatible with test ({})", + &test_case.description, + run_on_errors.join(","), )); continue; } From 62bf8d999a42c85fedae6ee82ae9e82a7047db5a Mon Sep 17 00:00:00 2001 From: Abraham Egnor Date: Thu, 10 Nov 2022 10:25:31 -0500 Subject: [PATCH 10/10] post-merge rustfmt --- src/test/csfle.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/csfle.rs b/src/test/csfle.rs index f90084740..889b715b8 100644 --- a/src/test/csfle.rs +++ b/src/test/csfle.rs @@ -46,7 +46,7 @@ use crate::{ CommandSucceededEvent, }, options::{IndexOptions, ReadConcern, WriteConcern}, - test::{Event, EventHandler, SdamEvent, KMS_PROVIDERS, KMIP_TLS_OPTIONS}, + test::{Event, EventHandler, SdamEvent, KMIP_TLS_OPTIONS, KMS_PROVIDERS}, Client, Collection, IndexModel, @@ -95,8 +95,8 @@ lazy_static! { static ref EXTRA_OPTIONS: Document = doc! { "cryptSharedLibPath": std::env::var("CSFLE_SHARED_LIB_PATH").unwrap() }; static ref KV_NAMESPACE: Namespace = Namespace::from_str("keyvault.datakeys").unwrap(); - static ref DISABLE_CRYPT_SHARED: bool = std::env::var("DISABLE_CRYPT_SHARED") - .map_or(false, |s| s == "true"); + static ref DISABLE_CRYPT_SHARED: bool = + std::env::var("DISABLE_CRYPT_SHARED").map_or(false, |s| s == "true"); } fn check_env(name: &str, kmip: bool) -> bool {