Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PYTHON-4206 - Enable QE Range Protocol V2 #829

Merged
merged 3 commits into from
Jun 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 60 additions & 16 deletions bindings/python/pymongocrypt/binding.py
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,17 @@ def _parse_version(version):
*/
void mongocrypt_setopt_use_need_kms_credentials_state(mongocrypt_t *crypt);

/**
* @brief Opt-into handling the MONGOCRYPT_CTX_NEED_MONGO_COLLINFO_WITH_DB state.
*
* A context enters the MONGOCRYPT_CTX_NEED_MONGO_COLLINFO_WITH_DB state when
* processing a `bulkWrite` command. The target database of the `bulkWrite` may differ from the command database
* ("admin").
*
* @param[in] crypt The @ref mongocrypt_t object to update
*/
void mongocrypt_setopt_use_need_mongo_collinfo_with_db_state(mongocrypt_t *crypt);

/**
* Initialize new @ref mongocrypt_t object.
*
Expand Down Expand Up @@ -524,7 +535,7 @@ def _parse_version(version):
* @brief Obtain a 64-bit constant encoding the version of the loaded
* crypt_shared library, if available.
*
* @param[in] crypt The mongocrypt_t object after a successful call to
* @param[in] crypt The mongocrypt_t object after a successul call to
* mongocrypt_init.
*
* @return A 64-bit encoded version number, with the version encoded as four
Expand Down Expand Up @@ -653,7 +664,9 @@ def _parse_version(version):
/// String constant for setopt_algorithm "Random" encryption
/// String constant for setopt_algorithm "Indexed" explicit encryption
/// String constant for setopt_algorithm "Unindexed" explicit encryption
/// String constant for setopt_algorithm "Range" explicit encryption
/// String constant for setopt_algorithm "rangePreview" explicit encryption (deprecated in favor of "range")
/// NOTE: "rangePreview" is experimental only and is not intended for public use.
/// API for "rangePreview" may be removed in a future release.

/**
* Identify the AWS KMS master key to use for creating a data key.
Expand Down Expand Up @@ -835,7 +848,10 @@ def _parse_version(version):
/**
* Explicit helper method to encrypt a Match Expression or Aggregate Expression.
* Contexts created for explicit encryption will not go through mongocryptd.
* Requires query_type to be "range".
* Requires query_type to be "range" or "rangePreview".
*
* NOTE: "rangePreview" is experimental only and is not intended for public use.
* API for "rangePreview" may be removed in a future release.
*
* This method expects the passed-in BSON to be of the form:
* { "v" : FLE2RangeFindDriverSpec }
Expand Down Expand Up @@ -928,9 +944,10 @@ def _parse_version(version):
*/
typedef enum {
MONGOCRYPT_CTX_ERROR = 0,
MONGOCRYPT_CTX_NEED_MONGO_COLLINFO = 1, /* run on main MongoClient */
MONGOCRYPT_CTX_NEED_MONGO_MARKINGS = 2, /* run on mongocryptd. */
MONGOCRYPT_CTX_NEED_MONGO_KEYS = 3, /* run on key vault */
MONGOCRYPT_CTX_NEED_MONGO_COLLINFO = 1, /* run on main MongoClient */
MONGOCRYPT_CTX_NEED_MONGO_COLLINFO_WITH_DB = 8, /* run on main MongoClient */
MONGOCRYPT_CTX_NEED_MONGO_MARKINGS = 2, /* run on mongocryptd. */
MONGOCRYPT_CTX_NEED_MONGO_KEYS = 3, /* run on key vault */
MONGOCRYPT_CTX_NEED_KMS = 4,
MONGOCRYPT_CTX_NEED_KMS_CREDENTIALS = 7, /* fetch/renew KMS credentials */
MONGOCRYPT_CTX_READY = 5, /* ready for encryption/decryption */
Expand All @@ -950,7 +967,7 @@ def _parse_version(version):
* is in MONGOCRYPT_CTX_NEED_MONGO_* states.
*
* @p op_bson is a BSON document to be used for the operation.
* - For MONGOCRYPT_CTX_NEED_MONGO_COLLINFO it is a listCollections filter.
* - For MONGOCRYPT_CTX_NEED_MONGO_COLLINFO(_WITH_DB) it is a listCollections filter.
* - For MONGOCRYPT_CTX_NEED_MONGO_KEYS it is a find filter.
* - For MONGOCRYPT_CTX_NEED_MONGO_MARKINGS it is a command to send to
* mongocryptd.
Expand All @@ -967,13 +984,28 @@ def _parse_version(version):
*/
bool mongocrypt_ctx_mongo_op(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *op_bson);

/**
* Get the database to run the mongo operation.
*
* Only applies when mongocrypt_ctx_t is in the state:
* MONGOCRYPT_CTX_NEED_MONGO_COLLINFO_WITH_DB.
*
* The lifetime of the returned string is tied to the lifetime of @p ctx. It is
* valid until @ref mongocrypt_ctx_destroy is called.
*
* @param[in] ctx The @ref mongocrypt_ctx_t object.
* @returns A string or NULL. If NULL, an error status is set. Retrieve it with
* @ref mongocrypt_ctx_status
*/
const char *mongocrypt_ctx_mongo_db(mongocrypt_ctx_t *ctx);

/**
* Feed a BSON reply or result when mongocrypt_ctx_t is in
* MONGOCRYPT_CTX_NEED_MONGO_* states. This may be called multiple times
* depending on the operation.
*
* reply is a BSON document result being fed back for this operation.
* - For MONGOCRYPT_CTX_NEED_MONGO_COLLINFO it is a doc from a listCollections
* - For MONGOCRYPT_CTX_NEED_MONGO_COLLINFO(_WITH_DB) it is a doc from a listCollections
* cursor. (Note, if listCollections returned no result, do not call this
* function.)
* - For MONGOCRYPT_CTX_NEED_MONGO_KEYS it is a doc from a find cursor.
Expand Down Expand Up @@ -1186,7 +1218,7 @@ def _parse_version(version):
* @param[out] status An optional status to pass error messages. See @ref
* mongocrypt_status_set.
* @returns A boolean indicating success. If returning false, set @p status
* with a message indicating the error using @ref mongocrypt_status_set.
* with a message indiciating the error using @ref mongocrypt_status_set.
*/
typedef bool (*mongocrypt_crypto_fn)(void *ctx,
mongocrypt_binary_t *key,
Expand All @@ -1211,7 +1243,7 @@ def _parse_version(version):
* @param[out] status An optional status to pass error messages. See @ref
* mongocrypt_status_set.
* @returns A boolean indicating success. If returning false, set @p status
* with a message indicating the error using @ref mongocrypt_status_set.
* with a message indiciating the error using @ref mongocrypt_status_set.
*/
typedef bool (*mongocrypt_hmac_fn)(void *ctx,
mongocrypt_binary_t *key,
Expand All @@ -1230,7 +1262,7 @@ def _parse_version(version):
* @param[out] status An optional status to pass error messages. See @ref
* mongocrypt_status_set.
* @returns A boolean indicating success. If returning false, set @p status
* with a message indicating the error using @ref mongocrypt_status_set.
* with a message indiciating the error using @ref mongocrypt_status_set.
*/
typedef bool (*mongocrypt_hash_fn)(void *ctx,
mongocrypt_binary_t *in,
Expand All @@ -1248,7 +1280,7 @@ def _parse_version(version):
* @param[out] status An optional status to pass error messages. See @ref
* mongocrypt_status_set.
* @returns A boolean indicating success. If returning false, set @p status
* with a message indicating the error using @ref mongocrypt_status_set.
* with a message indiciating the error using @ref mongocrypt_status_set.
*/
typedef bool (*mongocrypt_random_fn)(void *ctx, mongocrypt_binary_t *out, uint32_t count, mongocrypt_status_t *status);

Expand All @@ -1269,8 +1301,7 @@ def _parse_version(version):
* operation.
* @param[in] aes_256_ctr_decrypt The crypto callback function for decrypt
* operation.
* @param[in] ctx A context passed as an argument to the crypto callback
* every invocation.
* @param[in] ctx Unused.
* @pre @ref mongocrypt_init has not been called on @p crypt.
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_status
Expand All @@ -1289,8 +1320,7 @@ def _parse_version(version):
* @param[in] crypt The @ref mongocrypt_t object.
* @param[in] aes_256_ecb_encrypt The crypto callback function for encrypt
* operation.
* @param[in] ctx A context passed as an argument to the crypto callback
* every invocation.
* @param[in] ctx Unused.
* @pre @ref mongocrypt_init has not been called on @p crypt.
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_status
Expand Down Expand Up @@ -1330,6 +1360,16 @@ def _parse_version(version):
*/
void mongocrypt_setopt_bypass_query_analysis(mongocrypt_t *crypt);

/**
* @brief Opt-into use of Queryable Encryption Range V2 protocol.
*
* @param[in] crypt The @ref mongocrypt_t object.
*
* @returns A boolean indicating success. If false, an error status is set.
* Retrieve it with @ref mongocrypt_status
*/
bool mongocrypt_setopt_use_range_v2(mongocrypt_t *crypt);

/**
* Set the contention factor used for explicit encryption.
* The contention factor is only used for indexed Queryable Encryption.
Expand Down Expand Up @@ -1392,6 +1432,10 @@ def _parse_version(version):
bool mongocrypt_ctx_setopt_algorithm_range(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *opts);

/// String constants for setopt_query_type
// 'rangePreview' is deprecated in favor of range.
/// NOTE: "rangePreview" is experimental only and is not intended for public use.
/// API for "rangePreview" may be removed in a future release.

"""
)

Expand Down
2 changes: 2 additions & 0 deletions bindings/python/pymongocrypt/mongocrypt.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ def __init__(self, options, callback):
self.__crypt = lib.mongocrypt_new()
if self.__crypt == ffi.NULL:
raise MongoCryptError("unable to create new mongocrypt object")
if not lib.mongocrypt_setopt_use_range_v2(self.__crypt):
raise MongoCryptError("unable to enable QE Range Protocol V2")

try:
self.__init()
Expand Down
92 changes: 71 additions & 21 deletions bindings/python/test/data/compact/success/encrypted-payload.json
Original file line number Diff line number Diff line change
@@ -1,23 +1,73 @@
{
"compactStructuredEncryptionData": "test",
"compactionTokens": {
"nested.notindexed": {
"$binary": {
"base64": "27J6DZqcjkRzZ3lWEsxH7CsQHr4CZirrGmuPS8ZkRO0=",
"subType": "00"
}
},
"nested.encrypted": {
"$binary": {
"base64": "SWO8WEoZ2r2Kx/muQKb7+COizy85nIIUFiHh4K9kcvA=",
"subType": "00"
}
},
"encrypted": {
"$binary": {
"base64": "noN+05JsuO1oDg59yypIGj45i+eFH6HOTXOPpeZ//Mk=",
"subType": "00"
}
"compactStructuredEncryptionData": "test",
"encryptionInformation": {
"type": 1,
"schema": {
"db.test": {
"escCollection": "esc",
"eccCollection": "ecc",
"ecocCollection": "ecoc",
"fields": [
{
"keyId": {
"$binary": {
"base64": "EjRWeBI0mHYSNBI0VniQEg==",
"subType": "04"
}
},
"path": "encrypted",
"bsonType": "string",
"queries": {
"queryType": "equality",
"contention": 0
}
},
{
"keyId": {
"$binary": {
"base64": "q83vqxI0mHYSNBI0VniQEg==",
"subType": "04"
}
},
"path": "nested.encrypted",
"bsonType": "string",
"queries": {
"queryType": "equality",
"contention": 0
}
},
{
"keyId": {
"$binary": {
"base64": "EjRWeBI0mHYSNBI0VniQEw==",
"subType": "04"
}
},
"path": "nested.notindexed",
"bsonType": "string"
}
]
}
}
}
}
},
"compactionTokens": {
"nested.notindexed": {
"$binary": {
"base64": "27J6DZqcjkRzZ3lWEsxH7CsQHr4CZirrGmuPS8ZkRO0=",
"subType": "00"
}
},
"nested.encrypted": {
"$binary": {
"base64": "SWO8WEoZ2r2Kx/muQKb7+COizy85nIIUFiHh4K9kcvA=",
"subType": "00"
}
},
"encrypted": {
"$binary": {
"base64": "noN+05JsuO1oDg59yypIGj45i+eFH6HOTXOPpeZ//Mk=",
"subType": "00"
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,8 @@
},
"sparsity": {
"$numberLong": "1"
},
"trimFactor": {
"$numberInt": "0"
}
}
Loading