PYTHON-4112 Support named KMS providers (#1487)
Requires pymongocrypt >= 1.9.0 and libmongocrypt >= 1.9.0.
This commit is contained in:
parent
68d22b20bd
commit
0615df47b5
@ -14,6 +14,12 @@ PyMongo 4.7 brings a number of improvements including:
|
||||
- Replaced usage of :class:`bson.son.SON` on all internal classes and commands to dict,
|
||||
:attr:`options.pool_options.metadata` is now of type ``dict`` as opposed to :class:`bson.son.SON`.
|
||||
- Significantly improved the performance of encoding BSON documents to JSON.
|
||||
- Support for named KMS providers for client side field level encryption.
|
||||
Previously supported KMS providers were only: aws, azure, gcp, kmip, and local.
|
||||
The KMS provider is now expanded to support name suffixes (e.g. local:myname).
|
||||
Named KMS providers enables more than one of each KMS provider type to be configured.
|
||||
See the docstring for :class:`~pymongo.encryption_options.AutoEncryptionOpts`.
|
||||
Note that named KMS providers requires pymongocrypt >=1.9 and libmongocrypt >=1.9.
|
||||
- Fixed a bug where :class:`~bson.int64.Int64` instances could not always be encoded by `orjson`_. The following now
|
||||
works::
|
||||
|
||||
|
||||
@ -125,8 +125,8 @@ examples show how to setup automatic client-side field level encryption
|
||||
using :class:`~pymongo.encryption.ClientEncryption` to create a new
|
||||
encryption data key.
|
||||
|
||||
.. note:: Automatic client-side field level encryption requires MongoDB 4.2
|
||||
enterprise or a MongoDB 4.2 Atlas cluster. The community version of the
|
||||
.. note:: Automatic client-side field level encryption requires MongoDB >=4.2
|
||||
enterprise or a MongoDB >=4.2 Atlas cluster. The community version of the
|
||||
server supports automatic decryption as well as
|
||||
:ref:`explicit-client-side-encryption`.
|
||||
|
||||
@ -255,7 +255,7 @@ will result in an error.
|
||||
Server-Side Field Level Encryption Enforcement
|
||||
``````````````````````````````````````````````
|
||||
|
||||
The MongoDB 4.2 server supports using schema validation to enforce encryption
|
||||
MongoDB >=4.2 servers supports using schema validation to enforce encryption
|
||||
of specific fields in a collection. This schema validation will prevent an
|
||||
application from inserting unencrypted values for any fields marked with the
|
||||
``"encrypt"`` JSON schema keyword.
|
||||
@ -457,8 +457,8 @@ Explicit encryption is a MongoDB community feature and does not use the
|
||||
Explicit Encryption with Automatic Decryption
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Although automatic encryption requires MongoDB 4.2 enterprise or a
|
||||
MongoDB 4.2 Atlas cluster, automatic *decryption* is supported for all users.
|
||||
Although automatic encryption requires MongoDB >=4.2 enterprise or a
|
||||
MongoDB >=4.2 Atlas cluster, automatic *decryption* is supported for all users.
|
||||
To configure automatic *decryption* without automatic *encryption* set
|
||||
``bypass_auto_encryption=True`` in
|
||||
:class:`~pymongo.encryption_options.AutoEncryptionOpts`:
|
||||
|
||||
@ -101,7 +101,7 @@ def _wrap_encryption_errors() -> Iterator[None]:
|
||||
# we should propagate them unchanged.
|
||||
raise
|
||||
except Exception as exc:
|
||||
raise EncryptionError(exc) from None
|
||||
raise EncryptionError(exc) from exc
|
||||
|
||||
|
||||
class _EncryptionIO(MongoCryptCallback): # type: ignore[misc]
|
||||
@ -520,6 +520,9 @@ class ClientEncryption(Generic[_DocumentType]):
|
||||
data keys. This key should be generated and stored as securely
|
||||
as possible.
|
||||
|
||||
KMS providers may be specified with an optional name suffix
|
||||
separated by a colon, for example "kmip:name" or "aws:name".
|
||||
Named KMS providers do not support :ref:`CSFLE on-demand credentials`.
|
||||
:param key_vault_namespace: The namespace for the key vault collection.
|
||||
The key vault collection contains all data keys used for encryption
|
||||
and decryption. Data keys are stored as documents in this MongoDB
|
||||
@ -674,12 +677,13 @@ class ClientEncryption(Generic[_DocumentType]):
|
||||
"""Create and insert a new data key into the key vault collection.
|
||||
|
||||
:param kms_provider: The KMS provider to use. Supported values are
|
||||
"aws", "azure", "gcp", "kmip", and "local".
|
||||
"aws", "azure", "gcp", "kmip", "local", or a named provider like
|
||||
"kmip:name".
|
||||
:param master_key: Identifies a KMS-specific key used to encrypt the
|
||||
new data key. If the kmsProvider is "local" the `master_key` is
|
||||
not applicable and may be omitted.
|
||||
|
||||
If the `kms_provider` is "aws" it is required and has the
|
||||
If the `kms_provider` type is "aws" it is required and has the
|
||||
following fields::
|
||||
|
||||
- `region` (string): Required. The AWS region, e.g. "us-east-1".
|
||||
@ -689,7 +693,7 @@ class ClientEncryption(Generic[_DocumentType]):
|
||||
requests to. May include port number, e.g.
|
||||
"kms.us-east-1.amazonaws.com:443".
|
||||
|
||||
If the `kms_provider` is "azure" it is required and has the
|
||||
If the `kms_provider` type is "azure" it is required and has the
|
||||
following fields::
|
||||
|
||||
- `keyVaultEndpoint` (string): Required. Host with optional
|
||||
@ -697,7 +701,7 @@ class ClientEncryption(Generic[_DocumentType]):
|
||||
- `keyName` (string): Required. Key name in the key vault.
|
||||
- `keyVersion` (string): Optional. Version of the key to use.
|
||||
|
||||
If the `kms_provider` is "gcp" it is required and has the
|
||||
If the `kms_provider` type is "gcp" it is required and has the
|
||||
following fields::
|
||||
|
||||
- `projectId` (string): Required. The Google cloud project ID.
|
||||
@ -709,7 +713,7 @@ class ClientEncryption(Generic[_DocumentType]):
|
||||
- `endpoint` (string): Optional. Host with optional port.
|
||||
Defaults to "cloudkms.googleapis.com".
|
||||
|
||||
If the `kms_provider` is "kmip" it is optional and has the
|
||||
If the `kms_provider` type is "kmip" it is optional and has the
|
||||
following fields::
|
||||
|
||||
- `keyId` (string): Optional. `keyId` is the KMIP Unique
|
||||
|
||||
@ -55,13 +55,13 @@ class AutoEncryptionOpts:
|
||||
) -> None:
|
||||
"""Options to configure automatic client-side field level encryption.
|
||||
|
||||
Automatic client-side field level encryption requires MongoDB 4.2
|
||||
enterprise or a MongoDB 4.2 Atlas cluster. Automatic encryption is not
|
||||
Automatic client-side field level encryption requires MongoDB >=4.2
|
||||
enterprise or a MongoDB >=4.2 Atlas cluster. Automatic encryption is not
|
||||
supported for operations on a database or view and will result in
|
||||
error.
|
||||
|
||||
Although automatic encryption requires MongoDB 4.2 enterprise or a
|
||||
MongoDB 4.2 Atlas cluster, automatic *decryption* is supported for all
|
||||
Although automatic encryption requires MongoDB >=4.2 enterprise or a
|
||||
MongoDB >=4.2 Atlas cluster, automatic *decryption* is supported for all
|
||||
users. To configure automatic *decryption* without automatic
|
||||
*encryption* set ``bypass_auto_encryption=True``. Explicit
|
||||
encryption and explicit decryption is also supported for all users
|
||||
@ -94,12 +94,23 @@ class AutoEncryptionOpts:
|
||||
data keys. This key should be generated and stored as securely
|
||||
as possible.
|
||||
|
||||
KMS providers may be specified with an optional name suffix
|
||||
separated by a colon, for example "kmip:name" or "aws:name".
|
||||
Named KMS providers do not support :ref:`CSFLE on-demand credentials`.
|
||||
Named KMS providers enables more than one of each KMS provider type to be configured.
|
||||
For example, to configure multiple local KMS providers::
|
||||
|
||||
kms_providers = {
|
||||
"local": {"key": local_kek1}, # Unnamed KMS provider.
|
||||
"local:myname": {"key": local_kek2}, # Named KMS provider with name "myname".
|
||||
}
|
||||
|
||||
:param key_vault_namespace: The namespace for the key vault collection.
|
||||
The key vault collection contains all data keys used for encryption
|
||||
and decryption. Data keys are stored as documents in this MongoDB
|
||||
collection. Data keys are protected with encryption by a KMS
|
||||
provider.
|
||||
:param key_vault_client: By default the key vault collection
|
||||
:param key_vault_client: By default, the key vault collection
|
||||
is assumed to reside in the same MongoDB cluster as the encrypted
|
||||
MongoClient. Use this option to route data key queries to a
|
||||
separate MongoDB cluster.
|
||||
|
||||
@ -113,6 +113,10 @@ AWS_CREDS = {
|
||||
"accessKeyId": os.environ.get("FLE_AWS_KEY", ""),
|
||||
"secretAccessKey": os.environ.get("FLE_AWS_SECRET", ""),
|
||||
}
|
||||
AWS_CREDS_2 = {
|
||||
"accessKeyId": os.environ.get("FLE_AWS_KEY2", ""),
|
||||
"secretAccessKey": os.environ.get("FLE_AWS_SECRET2", ""),
|
||||
}
|
||||
AZURE_CREDS = {
|
||||
"tenantId": os.environ.get("FLE_AZURE_TENANTID", ""),
|
||||
"clientId": os.environ.get("FLE_AZURE_CLIENTID", ""),
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -55,6 +55,38 @@
|
||||
"result": {
|
||||
"errorContains": "Driver support of Queryable Encryption is incompatible with server. Upgrade server to use Queryable Encryption."
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "assertCollectionNotExists",
|
||||
"object": "testRunner",
|
||||
"arguments": {
|
||||
"database": "default",
|
||||
"collection": "enxcol_.encryptedCollection.esc"
|
||||
}
|
||||
},
|
||||
{
|
||||
"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"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset"
|
||||
]
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset"
|
||||
]
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset"
|
||||
]
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset"
|
||||
]
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset"
|
||||
]
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset"
|
||||
]
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "7.0.0",
|
||||
"serverless": "forbid",
|
||||
"topology": [
|
||||
"replicaset",
|
||||
"sharded",
|
||||
|
||||
@ -216,7 +216,10 @@
|
||||
"command_started_event": {
|
||||
"command": {
|
||||
"getMore": {
|
||||
"$$type": "long"
|
||||
"$$type": [
|
||||
"int",
|
||||
"long"
|
||||
]
|
||||
},
|
||||
"collection": "default",
|
||||
"batchSize": 2
|
||||
|
||||
197
test/client-side-encryption/spec/legacy/namedKMS.json
Normal file
197
test/client-side-encryption/spec/legacy/namedKMS.json
Normal file
@ -0,0 +1,197 @@
|
||||
{
|
||||
"runOn": [
|
||||
{
|
||||
"minServerVersion": "4.1.10"
|
||||
}
|
||||
],
|
||||
"database_name": "default",
|
||||
"collection_name": "default",
|
||||
"data": [],
|
||||
"json_schema": {
|
||||
"properties": {
|
||||
"encrypted_string": {
|
||||
"encrypt": {
|
||||
"keyId": [
|
||||
{
|
||||
"$binary": {
|
||||
"base64": "local+name2+AAAAAAAAAA==",
|
||||
"subType": "04"
|
||||
}
|
||||
}
|
||||
],
|
||||
"bsonType": "string",
|
||||
"algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
|
||||
}
|
||||
}
|
||||
},
|
||||
"bsonType": "object"
|
||||
},
|
||||
"key_vault_data": [
|
||||
{
|
||||
"_id": {
|
||||
"$binary": {
|
||||
"base64": "local+name2+AAAAAAAAAA==",
|
||||
"subType": "04"
|
||||
}
|
||||
},
|
||||
"keyMaterial": {
|
||||
"$binary": {
|
||||
"base64": "DX3iUuOlBsx6wBX9UZ3v/qXk1HNeBace2J+h/JwsDdF/vmSXLZ1l1VmZYIcpVFy6ODhdbzLjd4pNgg9wcm4etYig62KNkmtZ0/s1tAL5VsuW/s7/3PYnYGznZTFhLjIVcOH/RNoRj2eQb/sRTyivL85wePEpAU/JzuBj6qO9Y5txQgs1k0J3aNy10R9aQ8kC1NuSSpLAIXwE6DlNDDJXhw==",
|
||||
"subType": "00"
|
||||
}
|
||||
},
|
||||
"creationDate": {
|
||||
"$date": {
|
||||
"$numberLong": "1552949630483"
|
||||
}
|
||||
},
|
||||
"updateDate": {
|
||||
"$date": {
|
||||
"$numberLong": "1552949630483"
|
||||
}
|
||||
},
|
||||
"status": {
|
||||
"$numberInt": "0"
|
||||
},
|
||||
"masterKey": {
|
||||
"provider": "local:name2"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "Automatically encrypt and decrypt with a named KMS provider",
|
||||
"clientOptions": {
|
||||
"autoEncryptOpts": {
|
||||
"kmsProviders": {
|
||||
"local:name2": {
|
||||
"key": {
|
||||
"$binary": {
|
||||
"base64": "local+name2+YUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk",
|
||||
"subType": "00"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"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": "local+name2+AAAAAAAAAA==",
|
||||
"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": "AZaHGpfp2pntvgAAAAAAAAAC07sFvTQ0I4O2U49hpr4HezaK44Ivluzv5ntQBTYHDlAJMLyRMyB6Dl+UGHBgqhHe/Xw+pcT9XdiUoOJYAx9g+w==",
|
||||
"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": "AZaHGpfp2pntvgAAAAAAAAAC07sFvTQ0I4O2U49hpr4HezaK44Ivluzv5ntQBTYHDlAJMLyRMyB6Dl+UGHBgqhHe/Xw+pcT9XdiUoOJYAx9g+w==",
|
||||
"subType": "06"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,396 @@
|
||||
{
|
||||
"description": "namedKMS-createDataKey",
|
||||
"schemaVersion": "1.18",
|
||||
"runOnRequirements": [
|
||||
{
|
||||
"csfle": true
|
||||
}
|
||||
],
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"observeEvents": [
|
||||
"commandStartedEvent"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"clientEncryption": {
|
||||
"id": "clientEncryption0",
|
||||
"clientEncryptionOpts": {
|
||||
"keyVaultClient": "client0",
|
||||
"keyVaultNamespace": "keyvault.datakeys",
|
||||
"kmsProviders": {
|
||||
"aws:name1": {
|
||||
"accessKeyId": {
|
||||
"$$placeholder": 1
|
||||
},
|
||||
"secretAccessKey": {
|
||||
"$$placeholder": 1
|
||||
}
|
||||
},
|
||||
"azure:name1": {
|
||||
"tenantId": {
|
||||
"$$placeholder": 1
|
||||
},
|
||||
"clientId": {
|
||||
"$$placeholder": 1
|
||||
},
|
||||
"clientSecret": {
|
||||
"$$placeholder": 1
|
||||
}
|
||||
},
|
||||
"gcp:name1": {
|
||||
"email": {
|
||||
"$$placeholder": 1
|
||||
},
|
||||
"privateKey": {
|
||||
"$$placeholder": 1
|
||||
}
|
||||
},
|
||||
"kmip:name1": {
|
||||
"endpoint": {
|
||||
"$$placeholder": 1
|
||||
}
|
||||
},
|
||||
"local:name1": {
|
||||
"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 named AWS KMS provider",
|
||||
"operations": [
|
||||
{
|
||||
"name": "createDataKey",
|
||||
"object": "clientEncryption0",
|
||||
"arguments": {
|
||||
"kmsProvider": "aws:name1",
|
||||
"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:name1",
|
||||
"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 named Azure KMS provider",
|
||||
"operations": [
|
||||
{
|
||||
"name": "createDataKey",
|
||||
"object": "clientEncryption0",
|
||||
"arguments": {
|
||||
"kmsProvider": "azure:name1",
|
||||
"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:name1",
|
||||
"keyVaultEndpoint": "key-vault-csfle.vault.azure.net",
|
||||
"keyName": "key-name-csfle"
|
||||
}
|
||||
}
|
||||
],
|
||||
"writeConcern": {
|
||||
"w": "majority"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "create datakey with named GCP KMS provider",
|
||||
"operations": [
|
||||
{
|
||||
"name": "createDataKey",
|
||||
"object": "clientEncryption0",
|
||||
"arguments": {
|
||||
"kmsProvider": "gcp:name1",
|
||||
"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:name1",
|
||||
"projectId": "devprod-drivers",
|
||||
"location": "global",
|
||||
"keyRing": "key-ring-csfle",
|
||||
"keyName": "key-name-csfle"
|
||||
}
|
||||
}
|
||||
],
|
||||
"writeConcern": {
|
||||
"w": "majority"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "create datakey with named KMIP KMS provider",
|
||||
"operations": [
|
||||
{
|
||||
"name": "createDataKey",
|
||||
"object": "clientEncryption0",
|
||||
"arguments": {
|
||||
"kmsProvider": "kmip:name1"
|
||||
},
|
||||
"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:name1",
|
||||
"keyId": {
|
||||
"$$type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"writeConcern": {
|
||||
"w": "majority"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "create datakey with named local KMS provider",
|
||||
"operations": [
|
||||
{
|
||||
"name": "createDataKey",
|
||||
"object": "clientEncryption0",
|
||||
"arguments": {
|
||||
"kmsProvider": "local:name1"
|
||||
},
|
||||
"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:name1"
|
||||
}
|
||||
}
|
||||
],
|
||||
"writeConcern": {
|
||||
"w": "majority"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
130
test/client-side-encryption/spec/unified/namedKMS-explicit.json
Normal file
130
test/client-side-encryption/spec/unified/namedKMS-explicit.json
Normal file
@ -0,0 +1,130 @@
|
||||
{
|
||||
"description": "namedKMS-explicit",
|
||||
"schemaVersion": "1.18",
|
||||
"runOnRequirements": [
|
||||
{
|
||||
"csfle": true
|
||||
}
|
||||
],
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0",
|
||||
"observeEvents": [
|
||||
"commandStartedEvent"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"clientEncryption": {
|
||||
"id": "clientEncryption0",
|
||||
"clientEncryptionOpts": {
|
||||
"keyVaultClient": "client0",
|
||||
"keyVaultNamespace": "keyvault.datakeys",
|
||||
"kmsProviders": {
|
||||
"local:name2": {
|
||||
"key": "local+name2+YUJCa1kxNkVyNUR1QURhZ2h2UzR2d2RrZzh0cFBwM3R6NmdWMDFBMUN3YkQ5aXRRMkhGRGdQV09wOGVNYUMxT2k3NjZKelhaQmRCZGJkTXVyZG9uSjFk"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"database": {
|
||||
"id": "database0",
|
||||
"client": "client0",
|
||||
"databaseName": "keyvault"
|
||||
}
|
||||
},
|
||||
{
|
||||
"collection": {
|
||||
"id": "collection0",
|
||||
"database": "database0",
|
||||
"collectionName": "datakeys"
|
||||
}
|
||||
}
|
||||
],
|
||||
"initialData": [
|
||||
{
|
||||
"databaseName": "keyvault",
|
||||
"collectionName": "datakeys",
|
||||
"documents": [
|
||||
{
|
||||
"_id": {
|
||||
"$binary": {
|
||||
"base64": "local+name2+AAAAAAAAAA==",
|
||||
"subType": "04"
|
||||
}
|
||||
},
|
||||
"keyAltNames": [
|
||||
"local:name2"
|
||||
],
|
||||
"keyMaterial": {
|
||||
"$binary": {
|
||||
"base64": "DX3iUuOlBsx6wBX9UZ3v/qXk1HNeBace2J+h/JwsDdF/vmSXLZ1l1VmZYIcpVFy6ODhdbzLjd4pNgg9wcm4etYig62KNkmtZ0/s1tAL5VsuW/s7/3PYnYGznZTFhLjIVcOH/RNoRj2eQb/sRTyivL85wePEpAU/JzuBj6qO9Y5txQgs1k0J3aNy10R9aQ8kC1NuSSpLAIXwE6DlNDDJXhw==",
|
||||
"subType": "00"
|
||||
}
|
||||
},
|
||||
"creationDate": {
|
||||
"$date": {
|
||||
"$numberLong": "1552949630483"
|
||||
}
|
||||
},
|
||||
"updateDate": {
|
||||
"$date": {
|
||||
"$numberLong": "1552949630483"
|
||||
}
|
||||
},
|
||||
"status": {
|
||||
"$numberInt": "0"
|
||||
},
|
||||
"masterKey": {
|
||||
"provider": "local:name2"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "can explicitly encrypt with a named KMS provider",
|
||||
"operations": [
|
||||
{
|
||||
"name": "encrypt",
|
||||
"object": "clientEncryption0",
|
||||
"arguments": {
|
||||
"value": "foobar",
|
||||
"opts": {
|
||||
"keyAltName": "local:name2",
|
||||
"algorithm": "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
|
||||
}
|
||||
},
|
||||
"expectResult": {
|
||||
"$binary": {
|
||||
"base64": "AZaHGpfp2pntvgAAAAAAAAAC4yX2LTAuN253GAkEO2ZXp4GpCyM7yoVNJMQQl+6uzxMs03IprLC7DL2vr18x9LwOimjTS9YbMJhrnFkEPuNhbg==",
|
||||
"subType": "06"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "can explicitly decrypt with a named KMS provider",
|
||||
"operations": [
|
||||
{
|
||||
"name": "decrypt",
|
||||
"object": "clientEncryption0",
|
||||
"arguments": {
|
||||
"value": {
|
||||
"$binary": {
|
||||
"base64": "AZaHGpfp2pntvgAAAAAAAAAC4yX2LTAuN253GAkEO2ZXp4GpCyM7yoVNJMQQl+6uzxMs03IprLC7DL2vr18x9LwOimjTS9YbMJhrnFkEPuNhbg==",
|
||||
"subType": "06"
|
||||
}
|
||||
}
|
||||
},
|
||||
"expectResult": "foobar"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -2090,6 +2090,32 @@ class TestKmsTLSOptions(EncryptionIntegrationTest):
|
||||
# [WinError 10054] An existing connection was forcibly closed by the remote host
|
||||
if sys.platform == "win32":
|
||||
self.cert_error += "|forcibly closed"
|
||||
# 4, Test named KMS providers.
|
||||
providers = {
|
||||
"aws:no_client_cert": AWS_CREDS,
|
||||
"azure:no_client_cert": {"identityPlatformEndpoint": "127.0.0.1:8002", **AZURE_CREDS},
|
||||
"gcp:no_client_cert": {"endpoint": "127.0.0.1:8002", **GCP_CREDS},
|
||||
"kmip:no_client_cert": KMIP_CREDS,
|
||||
"aws:with_tls": AWS_CREDS,
|
||||
"azure:with_tls": {"identityPlatformEndpoint": "127.0.0.1:8002", **AZURE_CREDS},
|
||||
"gcp:with_tls": {"endpoint": "127.0.0.1:8002", **GCP_CREDS},
|
||||
"kmip:with_tls": KMIP_CREDS,
|
||||
}
|
||||
no_cert = {"tlsCAFile": CA_PEM}
|
||||
with_cert = {"tlsCAFile": CA_PEM, "tlsCertificateKeyFile": CLIENT_PEM}
|
||||
kms_tls_opts_4 = {
|
||||
"aws:no_client_cert": no_cert,
|
||||
"azure:no_client_cert": no_cert,
|
||||
"gcp:no_client_cert": no_cert,
|
||||
"kmip:no_client_cert": no_cert,
|
||||
"aws:with_tls": with_cert,
|
||||
"azure:with_tls": with_cert,
|
||||
"gcp:with_tls": with_cert,
|
||||
"kmip:with_tls": with_cert,
|
||||
}
|
||||
self.client_encryption_with_names = ClientEncryption(
|
||||
providers, "keyvault.datakeys", self.client, OPTS, kms_tls_options=kms_tls_opts_4
|
||||
)
|
||||
|
||||
def test_01_aws(self):
|
||||
key = {
|
||||
@ -2178,6 +2204,43 @@ class TestKmsTLSOptions(EncryptionIntegrationTest):
|
||||
raise self.skipTest("OCSP not enabled")
|
||||
self.assertFalse(ctx.check_ocsp_endpoint)
|
||||
|
||||
def test_06_named_kms_providers_apply_tls_options_aws(self):
|
||||
key = {
|
||||
"region": "us-east-1",
|
||||
"key": "arn:aws:kms:us-east-1:579766882180:key/89fcc2c4-08b0-4bd9-9f25-e30687b580d0",
|
||||
"endpoint": "127.0.0.1:8002",
|
||||
}
|
||||
# Missing client cert error.
|
||||
with self.assertRaisesRegex(EncryptionError, self.cert_error):
|
||||
self.client_encryption_with_names.create_data_key("aws:no_client_cert", key)
|
||||
# "parse error" here means that the TLS handshake succeeded.
|
||||
with self.assertRaisesRegex(EncryptionError, "parse error"):
|
||||
self.client_encryption_with_names.create_data_key("aws:with_tls", key)
|
||||
|
||||
def test_06_named_kms_providers_apply_tls_options_azure(self):
|
||||
key = {"keyVaultEndpoint": "doesnotexist.local", "keyName": "foo"}
|
||||
# Missing client cert error.
|
||||
with self.assertRaisesRegex(EncryptionError, self.cert_error):
|
||||
self.client_encryption_with_names.create_data_key("azure:no_client_cert", key)
|
||||
# "HTTP status=404" here means that the TLS handshake succeeded.
|
||||
with self.assertRaisesRegex(EncryptionError, "HTTP status=404"):
|
||||
self.client_encryption_with_names.create_data_key("azure:with_tls", key)
|
||||
|
||||
def test_06_named_kms_providers_apply_tls_options_gcp(self):
|
||||
key = {"projectId": "foo", "location": "bar", "keyRing": "baz", "keyName": "foo"}
|
||||
# Missing client cert error.
|
||||
with self.assertRaisesRegex(EncryptionError, self.cert_error):
|
||||
self.client_encryption_with_names.create_data_key("gcp:no_client_cert", key)
|
||||
# "HTTP status=404" here means that the TLS handshake succeeded.
|
||||
with self.assertRaisesRegex(EncryptionError, "HTTP status=404"):
|
||||
self.client_encryption_with_names.create_data_key("gcp:with_tls", key)
|
||||
|
||||
def test_06_named_kms_providers_apply_tls_options_kmip(self):
|
||||
# Missing client cert error.
|
||||
with self.assertRaisesRegex(EncryptionError, self.cert_error):
|
||||
self.client_encryption_with_names.create_data_key("kmip:no_client_cert")
|
||||
self.client_encryption_with_names.create_data_key("kmip:with_tls")
|
||||
|
||||
|
||||
# https://github.com/mongodb/specifications/blob/50e26fe/source/client-side-encryption/tests/README.rst#unique-index-on-keyaltnames
|
||||
class TestUniqueIndexOnKeyAltNamesProse(EncryptionIntegrationTest):
|
||||
|
||||
@ -0,0 +1,29 @@
|
||||
{
|
||||
"description": "clientEncryptionOpts-kmsProviders-invalidName",
|
||||
"schemaVersion": "1.18",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"clientEncryption": {
|
||||
"id": "clientEncryption0",
|
||||
"clientEncryptionOpts": {
|
||||
"keyVaultClient": "client0",
|
||||
"keyVaultNamespace": "keyvault.datakeys",
|
||||
"kmsProviders": {
|
||||
"aws:name_with_invalid_character*": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "",
|
||||
"operations": []
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
{
|
||||
"description": "expectedError-errorResponse-type",
|
||||
"schemaVersion": "1.12",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "foo",
|
||||
"operations": [
|
||||
{
|
||||
"name": "foo",
|
||||
"object": "client0",
|
||||
"expectError": {
|
||||
"errorResponse": 0
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
278
test/unified-test-format/valid-pass/entity-commandCursor.json
Normal file
278
test/unified-test-format/valid-pass/entity-commandCursor.json
Normal file
@ -0,0 +1,278 @@
|
||||
{
|
||||
"description": "entity-commandCursor",
|
||||
"schemaVersion": "1.3",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client",
|
||||
"useMultipleMongoses": false,
|
||||
"observeEvents": [
|
||||
"commandStartedEvent"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"database": {
|
||||
"id": "db",
|
||||
"client": "client",
|
||||
"databaseName": "db"
|
||||
}
|
||||
},
|
||||
{
|
||||
"collection": {
|
||||
"id": "collection",
|
||||
"database": "db",
|
||||
"collectionName": "collection"
|
||||
}
|
||||
}
|
||||
],
|
||||
"initialData": [
|
||||
{
|
||||
"collectionName": "collection",
|
||||
"databaseName": "db",
|
||||
"documents": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
},
|
||||
{
|
||||
"_id": 3,
|
||||
"x": 33
|
||||
},
|
||||
{
|
||||
"_id": 4,
|
||||
"x": 44
|
||||
},
|
||||
{
|
||||
"_id": 5,
|
||||
"x": 55
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "runCursorCommand creates and exhausts cursor by running getMores",
|
||||
"operations": [
|
||||
{
|
||||
"name": "runCursorCommand",
|
||||
"object": "db",
|
||||
"arguments": {
|
||||
"commandName": "find",
|
||||
"batchSize": 2,
|
||||
"command": {
|
||||
"find": "collection",
|
||||
"filter": {},
|
||||
"batchSize": 2
|
||||
}
|
||||
},
|
||||
"expectResult": [
|
||||
{
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
},
|
||||
{
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
},
|
||||
{
|
||||
"_id": 3,
|
||||
"x": 33
|
||||
},
|
||||
{
|
||||
"_id": 4,
|
||||
"x": 44
|
||||
},
|
||||
{
|
||||
"_id": 5,
|
||||
"x": 55
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"command": {
|
||||
"find": "collection",
|
||||
"filter": {},
|
||||
"batchSize": 2,
|
||||
"$db": "db",
|
||||
"lsid": {
|
||||
"$$exists": true
|
||||
}
|
||||
},
|
||||
"commandName": "find"
|
||||
}
|
||||
},
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"command": {
|
||||
"getMore": {
|
||||
"$$type": [
|
||||
"int",
|
||||
"long"
|
||||
]
|
||||
},
|
||||
"collection": "collection",
|
||||
"$db": "db",
|
||||
"lsid": {
|
||||
"$$exists": true
|
||||
}
|
||||
},
|
||||
"commandName": "getMore"
|
||||
}
|
||||
},
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"command": {
|
||||
"getMore": {
|
||||
"$$type": [
|
||||
"int",
|
||||
"long"
|
||||
]
|
||||
},
|
||||
"collection": "collection",
|
||||
"$db": "db",
|
||||
"lsid": {
|
||||
"$$exists": true
|
||||
}
|
||||
},
|
||||
"commandName": "getMore"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "createCommandCursor creates a cursor and stores it as an entity that can be iterated one document at a time",
|
||||
"operations": [
|
||||
{
|
||||
"name": "createCommandCursor",
|
||||
"object": "db",
|
||||
"arguments": {
|
||||
"commandName": "find",
|
||||
"batchSize": 2,
|
||||
"command": {
|
||||
"find": "collection",
|
||||
"filter": {},
|
||||
"batchSize": 2
|
||||
}
|
||||
},
|
||||
"saveResultAsEntity": "myRunCommandCursor"
|
||||
},
|
||||
{
|
||||
"name": "iterateUntilDocumentOrError",
|
||||
"object": "myRunCommandCursor",
|
||||
"expectResult": {
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "iterateUntilDocumentOrError",
|
||||
"object": "myRunCommandCursor",
|
||||
"expectResult": {
|
||||
"_id": 2,
|
||||
"x": 22
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "iterateUntilDocumentOrError",
|
||||
"object": "myRunCommandCursor",
|
||||
"expectResult": {
|
||||
"_id": 3,
|
||||
"x": 33
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "iterateUntilDocumentOrError",
|
||||
"object": "myRunCommandCursor",
|
||||
"expectResult": {
|
||||
"_id": 4,
|
||||
"x": 44
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "iterateUntilDocumentOrError",
|
||||
"object": "myRunCommandCursor",
|
||||
"expectResult": {
|
||||
"_id": 5,
|
||||
"x": 55
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "createCommandCursor's cursor can be closed and will perform a killCursors operation",
|
||||
"operations": [
|
||||
{
|
||||
"name": "createCommandCursor",
|
||||
"object": "db",
|
||||
"arguments": {
|
||||
"commandName": "find",
|
||||
"batchSize": 2,
|
||||
"command": {
|
||||
"find": "collection",
|
||||
"filter": {},
|
||||
"batchSize": 2
|
||||
}
|
||||
},
|
||||
"saveResultAsEntity": "myRunCommandCursor"
|
||||
},
|
||||
{
|
||||
"name": "iterateUntilDocumentOrError",
|
||||
"object": "myRunCommandCursor",
|
||||
"expectResult": {
|
||||
"_id": 1,
|
||||
"x": 11
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "close",
|
||||
"object": "myRunCommandCursor"
|
||||
}
|
||||
],
|
||||
"expectEvents": [
|
||||
{
|
||||
"client": "client",
|
||||
"events": [
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"command": {
|
||||
"find": "collection",
|
||||
"filter": {},
|
||||
"batchSize": 2,
|
||||
"$db": "db",
|
||||
"lsid": {
|
||||
"$$exists": true
|
||||
}
|
||||
},
|
||||
"commandName": "find"
|
||||
}
|
||||
},
|
||||
{
|
||||
"commandStartedEvent": {
|
||||
"command": {
|
||||
"killCursors": "collection",
|
||||
"cursors": {
|
||||
"$$type": "array"
|
||||
}
|
||||
},
|
||||
"commandName": "killCursors"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,70 @@
|
||||
{
|
||||
"description": "expectedError-errorResponse",
|
||||
"schemaVersion": "1.12",
|
||||
"createEntities": [
|
||||
{
|
||||
"client": {
|
||||
"id": "client0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"database": {
|
||||
"id": "database0",
|
||||
"client": "client0",
|
||||
"databaseName": "test"
|
||||
}
|
||||
},
|
||||
{
|
||||
"collection": {
|
||||
"id": "collection0",
|
||||
"database": "database0",
|
||||
"collectionName": "coll0"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tests": [
|
||||
{
|
||||
"description": "Unsupported command",
|
||||
"operations": [
|
||||
{
|
||||
"name": "runCommand",
|
||||
"object": "database0",
|
||||
"arguments": {
|
||||
"commandName": "unsupportedCommand",
|
||||
"command": {
|
||||
"unsupportedCommand": 1
|
||||
}
|
||||
},
|
||||
"expectError": {
|
||||
"errorResponse": {
|
||||
"errmsg": {
|
||||
"$$type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "Unsupported query operator",
|
||||
"operations": [
|
||||
{
|
||||
"name": "find",
|
||||
"object": "collection0",
|
||||
"arguments": {
|
||||
"filter": {
|
||||
"$unsupportedQueryOperator": 1
|
||||
}
|
||||
},
|
||||
"expectError": {
|
||||
"errorResponse": {
|
||||
"errmsg": {
|
||||
"$$type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -32,6 +32,7 @@ import types
|
||||
from collections import abc
|
||||
from test import (
|
||||
AWS_CREDS,
|
||||
AWS_CREDS_2,
|
||||
AZURE_CREDS,
|
||||
CA_PEM,
|
||||
CLIENT_PEM,
|
||||
@ -143,10 +144,16 @@ KMS_TLS_OPTS = {
|
||||
PLACEHOLDER_MAP = {}
|
||||
for provider_name, provider_data in [
|
||||
("local", {"key": LOCAL_MASTER_KEY}),
|
||||
("local:name1", {"key": LOCAL_MASTER_KEY}),
|
||||
("aws", AWS_CREDS),
|
||||
("aws:name1", AWS_CREDS),
|
||||
("aws:name2", AWS_CREDS_2),
|
||||
("azure", AZURE_CREDS),
|
||||
("azure:name1", AZURE_CREDS),
|
||||
("gcp", GCP_CREDS),
|
||||
("gcp:name1", GCP_CREDS),
|
||||
("kmip", KMIP_CREDS),
|
||||
("kmip:name1", KMIP_CREDS),
|
||||
]:
|
||||
for key, value in provider_data.items():
|
||||
placeholder = f"/clientEncryptionOpts/kmsProviders/{provider_name}/{key}"
|
||||
@ -532,12 +539,18 @@ class EntityMapUtil:
|
||||
opts = camel_to_snake_args(spec["clientEncryptionOpts"].copy())
|
||||
if isinstance(opts["key_vault_client"], str):
|
||||
opts["key_vault_client"] = self[opts["key_vault_client"]]
|
||||
# Set TLS options for providers like "kmip:name1".
|
||||
kms_tls_options = {}
|
||||
for provider in opts["kms_providers"]:
|
||||
provider_type = provider.split(":")[0]
|
||||
if provider_type in KMS_TLS_OPTS:
|
||||
kms_tls_options[provider] = KMS_TLS_OPTS[provider_type]
|
||||
self[spec["id"]] = ClientEncryption(
|
||||
opts["kms_providers"],
|
||||
opts["key_vault_namespace"],
|
||||
opts["key_vault_client"],
|
||||
DEFAULT_CODEC_OPTIONS,
|
||||
opts.get("kms_tls_options", KMS_TLS_OPTS),
|
||||
opts.get("kms_tls_options", kms_tls_options),
|
||||
)
|
||||
return
|
||||
elif entity_type == "thread":
|
||||
@ -920,7 +933,7 @@ class UnifiedSpecTestMixinV1(IntegrationTest):
|
||||
a class attribute ``TEST_SPEC``.
|
||||
"""
|
||||
|
||||
SCHEMA_VERSION = Version.from_string("1.17")
|
||||
SCHEMA_VERSION = Version.from_string("1.18")
|
||||
RUN_ON_LOAD_BALANCER = True
|
||||
RUN_ON_SERVERLESS = True
|
||||
TEST_SPEC: Any
|
||||
@ -1056,8 +1069,7 @@ class UnifiedSpecTestMixinV1(IntegrationTest):
|
||||
expect_result = spec.get("expectResult")
|
||||
error_response = spec.get("errorResponse")
|
||||
if error_response:
|
||||
for k in error_response.keys():
|
||||
self.assertEqual(error_response[k], exception.details[k])
|
||||
self.match_evaluator.match_result(error_response, exception.details)
|
||||
|
||||
if is_error:
|
||||
# already satisfied because exception was raised
|
||||
@ -1261,10 +1273,8 @@ class UnifiedSpecTestMixinV1(IntegrationTest):
|
||||
|
||||
def _clientEncryptionOperation_createDataKey(self, target, *args, **kwargs):
|
||||
if "opts" in kwargs:
|
||||
opts = kwargs.pop("opts")
|
||||
kwargs["master_key"] = opts.get("masterKey")
|
||||
kwargs["key_alt_names"] = opts.get("keyAltNames")
|
||||
kwargs["key_material"] = opts.get("keyMaterial")
|
||||
kwargs.update(camel_to_snake_args(kwargs.pop("opts")))
|
||||
|
||||
return target.create_data_key(*args, **kwargs)
|
||||
|
||||
def _clientEncryptionOperation_getKeys(self, target, *args, **kwargs):
|
||||
@ -1278,14 +1288,17 @@ class UnifiedSpecTestMixinV1(IntegrationTest):
|
||||
|
||||
def _clientEncryptionOperation_rewrapManyDataKey(self, target, *args, **kwargs):
|
||||
if "opts" in kwargs:
|
||||
opts = kwargs.pop("opts")
|
||||
kwargs["provider"] = opts.get("provider")
|
||||
kwargs["master_key"] = opts.get("masterKey")
|
||||
kwargs.update(camel_to_snake_args(kwargs.pop("opts")))
|
||||
data = target.rewrap_many_data_key(*args, **kwargs)
|
||||
if data.bulk_write_result:
|
||||
return {"bulkWriteResult": parse_bulk_write_result(data.bulk_write_result)}
|
||||
return {}
|
||||
|
||||
def _clientEncryptionOperation_encrypt(self, target, *args, **kwargs):
|
||||
if "opts" in kwargs:
|
||||
kwargs.update(camel_to_snake_args(kwargs.pop("opts")))
|
||||
return target.encrypt(*args, **kwargs)
|
||||
|
||||
def _bucketOperation_download(self, target: GridFSBucket, *args: Any, **kwargs: Any) -> bytes:
|
||||
with target.open_download_stream(*args, **kwargs) as gout:
|
||||
return gout.read()
|
||||
|
||||
Loading…
Reference in New Issue
Block a user