diff --git a/src/mc-efc-private.h b/src/mc-efc-private.h index 5c1979db8..bcf90f16e 100644 --- a/src/mc-efc-private.h +++ b/src/mc-efc-private.h @@ -46,6 +46,7 @@ typedef struct _mc_EncryptedField_t { * for the server IDL definition of EncryptedFieldConfig. */ typedef struct { mc_EncryptedField_t *fields; + uint8_t str_encode_version; } mc_EncryptedFieldConfig_t; /* mc_EncryptedFieldConfig_parse parses a subset of the fields from @efc_bson diff --git a/src/mc-efc.c b/src/mc-efc.c index 342fe9e98..205cd529e 100644 --- a/src/mc-efc.c +++ b/src/mc-efc.c @@ -19,6 +19,7 @@ #include "mlib/str.h" #include "mongocrypt-private.h" #include "mongocrypt-util-private.h" // mc_iter_document_as_bson +#include static bool _parse_query_type_string(const char *queryType, supported_query_type_flags *out) { BSON_ASSERT_PARAM(queryType); @@ -175,13 +176,14 @@ bool mc_EncryptedFieldConfig_parse(mc_EncryptedFieldConfig_t *efc, return false; } if (!BSON_ITER_HOLDS_ARRAY(&iter)) { - CLIENT_ERR("expected 'fields' to be type array, got: %d", bson_iter_type(&iter)); + CLIENT_ERR("expected 'fields' to be type array, got: %s", mc_bson_type_to_string(bson_iter_type(&iter))); return false; } if (!bson_iter_recurse(&iter, &iter)) { CLIENT_ERR("unable to recurse into encrypted_field_config 'fields'"); return false; } + supported_query_type_flags all_supported_queries = SUPPORTS_NO_QUERIES; while (bson_iter_next(&iter)) { bson_t field; if (!mc_iter_document_as_bson(&iter, &field, status)) { @@ -190,6 +192,32 @@ bool mc_EncryptedFieldConfig_parse(mc_EncryptedFieldConfig_t *efc, if (!_parse_field(efc, &field, status, use_range_v2)) { return false; } + // The first element of efc->fields contains the newly parsed field. + all_supported_queries |= efc->fields->supported_queries; + } + + if (!bson_iter_init_find(&iter, efc_bson, "strEncodeVersion")) { + if (all_supported_queries + & (SUPPORTS_SUBSTRING_PREVIEW_QUERIES | SUPPORTS_SUFFIX_PREVIEW_QUERIES + | SUPPORTS_PREFIX_PREVIEW_QUERIES)) { + // Has at least one text search query type, set to latest by default. + efc->str_encode_version = LATEST_STR_ENCODE_VERSION; + } else { + // Set to 0 to indicate no text search, and thus no strEncodeVersion needed. + efc->str_encode_version = 0; + } + } else { + if (!BSON_ITER_HOLDS_INT32(&iter)) { + CLIENT_ERR("expected 'strEncodeVersion' to be type int32, got: %s", + mc_bson_type_to_string(bson_iter_type(&iter))); + return false; + } + int32_t version = bson_iter_int32(&iter); + if (version > LATEST_STR_ENCODE_VERSION || version < MIN_STR_ENCODE_VERSION) { + CLIENT_ERR("'strEncodeVersion' of %" PRId32 " is not supported", version); + return false; + } + efc->str_encode_version = (uint8_t)version; } return true; } diff --git a/src/mongocrypt-ctx-encrypt.c b/src/mongocrypt-ctx-encrypt.c index 6d9e7ce05..95f750b65 100644 --- a/src/mongocrypt-ctx-encrypt.c +++ b/src/mongocrypt-ctx-encrypt.c @@ -22,12 +22,13 @@ #include "mongocrypt-ctx-private.h" #include "mongocrypt-key-broker-private.h" #include "mongocrypt-marking-private.h" +#include "mongocrypt-private.h" #include "mongocrypt-traverse-util-private.h" #include "mongocrypt-util-private.h" // mc_iter_document_as_bson #include "mongocrypt.h" /* _fle2_append_encryptedFieldConfig copies encryptedFieldConfig and applies - * default state collection names for escCollection, and ecocCollection if required. */ + * default state collection names for escCollection and ecocCollection, and default strEncodeVersion, if required. */ static bool _fle2_append_encryptedFieldConfig(const mongocrypt_ctx_t *ctx, bson_t *dst, bson_t *encryptedFieldConfig, @@ -36,7 +37,9 @@ static bool _fle2_append_encryptedFieldConfig(const mongocrypt_ctx_t *ctx, bson_iter_t iter; bool has_escCollection = false; bool has_ecocCollection = false; + bool has_strEncodeVersion = false; + BSON_ASSERT_PARAM(ctx); BSON_ASSERT_PARAM(dst); BSON_ASSERT_PARAM(encryptedFieldConfig); BSON_ASSERT_PARAM(target_coll); @@ -53,6 +56,9 @@ static bool _fle2_append_encryptedFieldConfig(const mongocrypt_ctx_t *ctx, if (strcmp(bson_iter_key(&iter), "ecocCollection") == 0) { has_ecocCollection = true; } + if (strcmp(bson_iter_key(&iter), "strEncodeVersion") == 0) { + has_strEncodeVersion = true; + } if (!BSON_APPEND_VALUE(dst, bson_iter_key(&iter), bson_iter_value(&iter))) { CLIENT_ERR("unable to append field: %s", bson_iter_key(&iter)); return false; @@ -77,6 +83,18 @@ static bool _fle2_append_encryptedFieldConfig(const mongocrypt_ctx_t *ctx, } bson_free(default_ecocCollection); } + if (!has_strEncodeVersion) { + _mongocrypt_ctx_encrypt_t *ectx = (_mongocrypt_ctx_encrypt_t *)ctx; + // Check str_encode_version on the EncryptedFieldConfig object to see whether we should append or not. 0 + // indicates that there was no text search query in the EFC and the strEncodeVersion was not set on the EFC; in + // this case, we should not append strEncodeVersion, as mongocryptd/mongod may not understand it. + if (ectx->efc.str_encode_version != 0) { + if (!BSON_APPEND_INT32(dst, "strEncodeVersion", (int32_t)ectx->efc.str_encode_version)) { + CLIENT_ERR("unable to append strEncodeVersion"); + return false; + } + } + } return true; } @@ -1433,6 +1451,100 @@ _fle2_strip_encryptionInformation(const char *cmd_name, bson_t *cmd /* in and ou return ok; } +/* + * Checks the "encryptedFields.strEncodeVersion" field for "create" commands for validity, and sets it to the default if + * it does not exist. + */ +static bool _fle2_fixup_encryptedFields_strEncodeVersion(const char *cmd_name, + bson_t *cmd /* in and out */, + const mc_EncryptedFieldConfig_t *efc, + mongocrypt_status_t *status) { + BSON_ASSERT_PARAM(cmd_name); + BSON_ASSERT_PARAM(cmd); + BSON_ASSERT_PARAM(efc); + + if (0 == strcmp(cmd_name, "create")) { + bson_iter_t ef_iter; + if (!bson_iter_init_find(&ef_iter, cmd, "encryptedFields")) { + // No encryptedFields, nothing to check or fix + return true; + } + if (!BSON_ITER_HOLDS_DOCUMENT(&ef_iter)) { + CLIENT_ERR("_fle2_fixup_encryptedFields_strEncodeVersion: Expected encryptedFields to be type obj, got: %s", + mc_bson_type_to_string(bson_iter_type(&ef_iter))); + return false; + } + bson_iter_t sev_iter; + if (!bson_iter_recurse(&ef_iter, &sev_iter)) { + CLIENT_ERR("_fle2_fixup_encryptedFields_strEncodeVersion: Failed to recurse bson_iter"); + return false; + } + if (!bson_iter_find(&sev_iter, "strEncodeVersion")) { + if (efc->str_encode_version == 0) { + // Unset StrEncodeVersion matches the EFC, nothing to fix. + return true; + } + + // No strEncodeVersion and the EFC has a nonzero strEncodeVersion, add it. + // Initialize the new cmd object from the old one, excluding encryptedFields. + bson_t fixed = BSON_INITIALIZER; + bson_copy_to_excluding_noinit(cmd, &fixed, "encryptedFields", NULL); + + // Recurse the original encryptedFields and copy everything over. + bson_iter_t copy_iter; + if (!bson_iter_recurse(&ef_iter, ©_iter)) { + CLIENT_ERR("_fle2_fixup_encryptedFields_strEncodeVersion: Failed to recurse bson_iter"); + goto fail; + } + bson_t fixed_ef; + if (!BSON_APPEND_DOCUMENT_BEGIN(&fixed, "encryptedFields", &fixed_ef)) { + CLIENT_ERR("_fle2_fixup_encryptedFields_strEncodeVersion: Failed to start appending encryptedFields"); + goto fail; + } + while (bson_iter_next(©_iter)) { + if (!bson_append_iter(&fixed_ef, NULL, 0, ©_iter)) { + CLIENT_ERR("_fle2_fixup_encryptedFields_strEncodeVersion: Failed to copy element"); + goto fail; + } + } + + // Add the EFC's strEncodeVersion to encryptedFields. + if (!BSON_APPEND_INT32(&fixed_ef, "strEncodeVersion", efc->str_encode_version)) { + CLIENT_ERR("_fle2_fixup_encryptedFields_strEncodeVersion: Failed to append strEncodeVersion"); + goto fail; + } + if (!bson_append_document_end(&fixed, &fixed_ef)) { + CLIENT_ERR("_fle2_fixup_encryptedFields_strEncodeVersion: Failed to finish appending encryptedFields"); + goto fail; + } + + bson_destroy(cmd); + if (!bson_steal(cmd, &fixed)) { + CLIENT_ERR("_fle2_fixup_encryptedFields_strEncodeVersion: Failed to steal BSON"); + goto fail; + } + return true; + fail: + bson_destroy(&fixed); + return false; + } else { + // Check strEncodeVersion for match against EFC + if (!BSON_ITER_HOLDS_INT32(&sev_iter)) { + CLIENT_ERR("expected 'strEncodeVersion' to be type int32, got: %d", bson_iter_type(&sev_iter)); + return false; + } + int32_t version = bson_iter_int32(&sev_iter); + if (version != efc->str_encode_version) { + CLIENT_ERR("'strEncodeVersion' of %d does not match efc->str_encode_version of %d", + version, + efc->str_encode_version); + return false; + } + } + } + return true; +} + /* Process a call to mongocrypt_ctx_finalize when an encryptedFieldConfig is * associated with the command. */ static bool _fle2_finalize(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *out) { @@ -1505,6 +1617,13 @@ static bool _fle2_finalize(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *out) { return _mongocrypt_ctx_fail(ctx); } + /* If this is a create command, append the encryptedFields.strEncodeVersion field if it's necessary. If the field + * already exists, check it against the EFC for correctness. */ + if (!_fle2_fixup_encryptedFields_strEncodeVersion(command_name, &converted, &ectx->efc, ctx->status)) { + bson_destroy(&converted); + return _mongocrypt_ctx_fail(ctx); + } + /* Append a new 'encryptionInformation'. */ if (!result.must_omit && !ectx->used_empty_encryptedFields) { if (!_fle2_insert_encryptionInformation(ctx, diff --git a/src/mongocrypt-private.h b/src/mongocrypt-private.h index 9ae0c5d32..45efac68d 100644 --- a/src/mongocrypt-private.h +++ b/src/mongocrypt-private.h @@ -49,6 +49,10 @@ #define MONGOCRYPT_DATA_AND_LEN(x) ((uint8_t *)x), (sizeof(x) / sizeof((x)[0]) - 1) +#define LATEST_STR_ENCODE_VERSION 1 + +#define MIN_STR_ENCODE_VERSION 1 + /* TODO: Move these to mongocrypt-log-private.h? */ const char *tmp_json(const bson_t *bson); diff --git a/test/data/efc/efc-oneField-badVersionSet.json b/test/data/efc/efc-oneField-badVersionSet.json new file mode 100644 index 000000000..c1abaad17 --- /dev/null +++ b/test/data/efc/efc-oneField-badVersionSet.json @@ -0,0 +1,23 @@ +{ + "escCollection": "fle2.basic.esc", + "ecocCollection": "fle2.basic.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "firstName", + "bsonType": "string", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + } + ], + "strEncodeVersion": 99 +} diff --git a/test/data/efc/efc-oneField-goodVersionSet.json b/test/data/efc/efc-oneField-goodVersionSet.json new file mode 100644 index 000000000..17b85fdbc --- /dev/null +++ b/test/data/efc/efc-oneField-goodVersionSet.json @@ -0,0 +1,23 @@ +{ + "escCollection": "fle2.basic.esc", + "ecocCollection": "fle2.basic.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "firstName", + "bsonType": "string", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + } + ], + "strEncodeVersion": 1 +} diff --git a/test/data/efc/efc-textSearchFields-badVersionSet.json b/test/data/efc/efc-textSearchFields-badVersionSet.json new file mode 100644 index 000000000..76992885f --- /dev/null +++ b/test/data/efc/efc-textSearchFields-badVersionSet.json @@ -0,0 +1,48 @@ +{ + "escCollection": "fle2.basic.esc", + "eccCollection": "fle2.basic.ecc", + "ecocCollection": "fle2.basic.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "firstName", + "bsonType": "string", + "queries": { + "queryType": "substringPreview", + "contention": { + "$numberLong": "0" + } + } + }, + { + "keyId": { + "$binary": { + "base64": "q83vqxI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "lastName", + "bsonType": "string", + "queries": [ + { + "queryType": "suffixPreview", + "contention": { + "$numberLong": "0" + } + }, + { + "queryType": "prefixPreview", + "contention": { + "$numberLong": "0" + } + } + ] + } + ], + "strEncodeVersion": 99 +} \ No newline at end of file diff --git a/test/data/efc/efc-textSearchFields-goodVersionSet.json b/test/data/efc/efc-textSearchFields-goodVersionSet.json new file mode 100644 index 000000000..87fccdec6 --- /dev/null +++ b/test/data/efc/efc-textSearchFields-goodVersionSet.json @@ -0,0 +1,48 @@ +{ + "escCollection": "fle2.basic.esc", + "eccCollection": "fle2.basic.ecc", + "ecocCollection": "fle2.basic.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "firstName", + "bsonType": "string", + "queries": { + "queryType": "substringPreview", + "contention": { + "$numberLong": "0" + } + } + }, + { + "keyId": { + "$binary": { + "base64": "q83vqxI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "lastName", + "bsonType": "string", + "queries": [ + { + "queryType": "suffixPreview", + "contention": { + "$numberLong": "0" + } + }, + { + "queryType": "prefixPreview", + "contention": { + "$numberLong": "0" + } + } + ] + } + ], + "strEncodeVersion": 1 +} \ No newline at end of file diff --git a/test/data/fle2-bad-str-encode-version/bad-collinfo.json b/test/data/fle2-bad-str-encode-version/bad-collinfo.json new file mode 100644 index 000000000..25424cee1 --- /dev/null +++ b/test/data/fle2-bad-str-encode-version/bad-collinfo.json @@ -0,0 +1,25 @@ +{ + "options": { + "encryptedFields": { + "escCollection": "fle2.test.esc", + "ecocCollection": "fle2.test.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "ssn", + "bsonType": "string", + "queries": { + "queryType": "equality", + "contention": 0 + } + } + ], + "strEncodeVersion": 99 + } + } +} \ No newline at end of file diff --git a/test/data/fle2-bad-str-encode-version/bad-create-cmd-mongocryptd-reply.json b/test/data/fle2-bad-str-encode-version/bad-create-cmd-mongocryptd-reply.json new file mode 100644 index 000000000..8a14cd9f1 --- /dev/null +++ b/test/data/fle2-bad-str-encode-version/bad-create-cmd-mongocryptd-reply.json @@ -0,0 +1,51 @@ +{ + "ok": { + "$numberInt": "1" + }, + "result": { + "create": "coll", + "encryptedFields": { + "fields": [ + { + "path": "encrypted", + "bsonType": "int", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + } + ], + "strEncodeVersion": 1 + }, + "encryptionInformation": { + "type": 1, + "schema": { + "db.coll": { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "escCollection": "esc", + "ecocCollection": "ecoc", + "fields": [ + { + "path": "encrypted", + "bsonType": "int", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + } + ] + } + } + } + }, + "hasEncryptedPlaceholders": false +} \ No newline at end of file diff --git a/test/data/fle2-bad-str-encode-version/bad-create-cmd-to-mongocryptd.json b/test/data/fle2-bad-str-encode-version/bad-create-cmd-to-mongocryptd.json new file mode 100644 index 000000000..b4ae213fd --- /dev/null +++ b/test/data/fle2-bad-str-encode-version/bad-create-cmd-to-mongocryptd.json @@ -0,0 +1,45 @@ +{ + "create": "coll", + "encryptedFields": { + "fields": [ + { + "path": "encrypted", + "bsonType": "int", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + } + ], + "strEncodeVersion": 1 + }, + "encryptionInformation": { + "type": 1, + "schema": { + "db.coll": { + "escCollection": "esc", + "ecocCollection": "ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encrypted", + "bsonType": "int", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + } + ] + } + } + } +} diff --git a/test/data/fle2-bad-str-encode-version/bad-create-cmd.json b/test/data/fle2-bad-str-encode-version/bad-create-cmd.json new file mode 100644 index 000000000..e00361dad --- /dev/null +++ b/test/data/fle2-bad-str-encode-version/bad-create-cmd.json @@ -0,0 +1,18 @@ +{ + "create": "coll", + "encryptedFields": { + "fields": [ + { + "path": "encrypted", + "bsonType": "int", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + } + ], + "strEncodeVersion": 99 + } +} \ No newline at end of file diff --git a/test/data/fle2-bad-str-encode-version/bad-encrypted-field-config-map.json b/test/data/fle2-bad-str-encode-version/bad-encrypted-field-config-map.json new file mode 100644 index 000000000..192455287 --- /dev/null +++ b/test/data/fle2-bad-str-encode-version/bad-encrypted-field-config-map.json @@ -0,0 +1,23 @@ +{ + "db.test": { + "escCollection": "fle2.test.esc", + "ecocCollection": "fle2.test.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "ssn", + "bsonType": "string", + "queries": { + "queryType": "equality", + "contention": 0 + } + } + ], + "strEncodeVersion": 99 + } +} \ No newline at end of file diff --git a/test/data/fle2-bad-str-encode-version/encrypted-payload.json b/test/data/fle2-bad-str-encode-version/encrypted-payload.json new file mode 100644 index 000000000..e8a27cf54 --- /dev/null +++ b/test/data/fle2-bad-str-encode-version/encrypted-payload.json @@ -0,0 +1,40 @@ +{ + "insert": "test", + "documents": [ + { + "_id": 1, + "ssn": { + "$binary": { + "base64": "C18BAAAFZAAgAAAAAHb62aV7+mqmaGcotPLdG3KP7S8diFwWMLM/5rYtqLrEBXMAIAAAAAAVJ6OWHRv3OtCozHpt3ZzfBhaxZirLv3B+G8PuaaO4EgVwADAAAAAAx0PWdXaep4jV5cRA2yQN+ULLwjv8e++oMonpfGOGs9BZ0uqPP7waiwZSwHsDx57+BXUAEAAAAAQSNFZ4EjSYdhI0EjRWeJASEHQAAgAAAAV2AFAAAAAAq83vqxI0mHYSNBI0VniQEkzZZBBDgeZh+h+gXEmOrSHYikH9u4e644rfZY9N9UQR4h76qKAmcbo43utRcXMQy+FXXIxSuNntFHZHTcNJhJoFZQAgAAAAAOuac/eRLYakKX6B0vZ1r3QodOQFfjqJD+xlGiPu4/PsBWwAIAAAAABpn2zcb7jOd/FK3F45nBxnLU6HOMwZzmGOZ0w35v/DqRJrAAAAAAAAAAAAAA==", + "subType": "06" + } + } + } + ], + "encryptionInformation": { + "type": 1, + "schema": { + "db.test": { + "escCollection": "fle2.test.esc", + "ecocCollection": "fle2.test.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "ssn", + "bsonType": "string", + "queries": { + "queryType": "equality", + "contention": 0 + } + } + ], + "strEncodeVersion": 1 + } + } + } +} diff --git a/test/data/fle2-create-encrypted-collection-encrypted-fields-unset-str-encode-version/cmd-to-mongocryptd.json b/test/data/fle2-create-encrypted-collection-encrypted-fields-unset-str-encode-version/cmd-to-mongocryptd.json new file mode 100644 index 000000000..b9f5c98e2 --- /dev/null +++ b/test/data/fle2-create-encrypted-collection-encrypted-fields-unset-str-encode-version/cmd-to-mongocryptd.json @@ -0,0 +1,45 @@ +{ + "create": "coll", + "encryptedFields": { + "fields": [ + { + "path": "encrypted", + "bsonType": "int", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + } + ] + }, + "encryptionInformation": { + "type": 1, + "schema": { + "db.coll": { + "escCollection": "esc", + "ecocCollection": "ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encrypted", + "bsonType": "int", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + } + ], + "strEncodeVersion": 1 + } + } + } +} diff --git a/test/data/fle2-create-encrypted-collection-encrypted-fields-unset-str-encode-version/mongocryptd-reply.json b/test/data/fle2-create-encrypted-collection-encrypted-fields-unset-str-encode-version/mongocryptd-reply.json new file mode 100644 index 000000000..58611cc5d --- /dev/null +++ b/test/data/fle2-create-encrypted-collection-encrypted-fields-unset-str-encode-version/mongocryptd-reply.json @@ -0,0 +1,51 @@ +{ + "ok": { + "$numberInt": "1" + }, + "result": { + "create": "coll", + "encryptedFields": { + "fields": [ + { + "path": "encrypted", + "bsonType": "int", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + } + ] + }, + "encryptionInformation": { + "type": 1, + "schema": { + "db.coll": { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "escCollection": "esc", + "ecocCollection": "ecoc", + "fields": [ + { + "path": "encrypted", + "bsonType": "int", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + } + ], + "strEncodeVersion": 1 + } + } + } + }, + "hasEncryptedPlaceholders": false +} \ No newline at end of file diff --git a/test/data/fle2-create-encrypted-collection-with-str-encode-version/cmd-to-mongocryptd.json b/test/data/fle2-create-encrypted-collection-with-str-encode-version/cmd-to-mongocryptd.json new file mode 100644 index 000000000..5b87904f3 --- /dev/null +++ b/test/data/fle2-create-encrypted-collection-with-str-encode-version/cmd-to-mongocryptd.json @@ -0,0 +1,46 @@ +{ + "create": "coll", + "encryptedFields": { + "fields": [ + { + "path": "encrypted", + "bsonType": "int", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + } + ], + "strEncodeVersion": 1 + }, + "encryptionInformation": { + "type": 1, + "schema": { + "db.coll": { + "escCollection": "esc", + "ecocCollection": "ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encrypted", + "bsonType": "int", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + } + ], + "strEncodeVersion": 1 + } + } + } +} diff --git a/test/data/fle2-create-encrypted-collection-with-str-encode-version/cmd.json b/test/data/fle2-create-encrypted-collection-with-str-encode-version/cmd.json new file mode 100644 index 000000000..3ebff7d9e --- /dev/null +++ b/test/data/fle2-create-encrypted-collection-with-str-encode-version/cmd.json @@ -0,0 +1,18 @@ +{ + "create": "coll", + "encryptedFields": { + "fields": [ + { + "path": "encrypted", + "bsonType": "int", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + } + ], + "strEncodeVersion": 1 + } +} \ No newline at end of file diff --git a/test/data/fle2-create-encrypted-collection-with-str-encode-version/encrypted-field-config-map.json b/test/data/fle2-create-encrypted-collection-with-str-encode-version/encrypted-field-config-map.json new file mode 100644 index 000000000..137d5f640 --- /dev/null +++ b/test/data/fle2-create-encrypted-collection-with-str-encode-version/encrypted-field-config-map.json @@ -0,0 +1,25 @@ +{ + "db.coll": { + "escCollection": "esc", + "ecocCollection": "ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encrypted", + "bsonType": "int", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + } + ], + "strEncodeVersion": 1 + } +} diff --git a/test/data/fle2-create-encrypted-collection-with-str-encode-version/encrypted-payload.json b/test/data/fle2-create-encrypted-collection-with-str-encode-version/encrypted-payload.json new file mode 100644 index 000000000..3ebff7d9e --- /dev/null +++ b/test/data/fle2-create-encrypted-collection-with-str-encode-version/encrypted-payload.json @@ -0,0 +1,18 @@ +{ + "create": "coll", + "encryptedFields": { + "fields": [ + { + "path": "encrypted", + "bsonType": "int", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + } + ], + "strEncodeVersion": 1 + } +} \ No newline at end of file diff --git a/test/data/fle2-create-encrypted-collection-with-str-encode-version/mongocryptd-reply.json b/test/data/fle2-create-encrypted-collection-with-str-encode-version/mongocryptd-reply.json new file mode 100644 index 000000000..6ba6123d7 --- /dev/null +++ b/test/data/fle2-create-encrypted-collection-with-str-encode-version/mongocryptd-reply.json @@ -0,0 +1,52 @@ +{ + "ok": { + "$numberInt": "1" + }, + "result": { + "create": "coll", + "encryptedFields": { + "fields": [ + { + "path": "encrypted", + "bsonType": "int", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + } + ], + "strEncodeVersion": 1 + }, + "encryptionInformation": { + "type": 1, + "schema": { + "db.coll": { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "escCollection": "esc", + "ecocCollection": "ecoc", + "fields": [ + { + "path": "encrypted", + "bsonType": "int", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + } + ], + "strEncodeVersion": 1 + } + } + } + }, + "hasEncryptedPlaceholders": false +} \ No newline at end of file diff --git a/test/data/fle2-create-encrypted-collection/cmd-to-mongocryptd.json b/test/data/fle2-create-encrypted-collection/cmd-to-mongocryptd.json new file mode 100644 index 000000000..a6eaa11a7 --- /dev/null +++ b/test/data/fle2-create-encrypted-collection/cmd-to-mongocryptd.json @@ -0,0 +1,44 @@ +{ + "create": "coll", + "encryptedFields": { + "fields": [ + { + "path": "encrypted", + "bsonType": "int", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + } + ] + }, + "encryptionInformation": { + "type": 1, + "schema": { + "db.coll": { + "escCollection": "esc", + "ecocCollection": "ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encrypted", + "bsonType": "int", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + } + ] + } + } + } +} diff --git a/test/data/fle2-create-encrypted-collection/cmd.json b/test/data/fle2-create-encrypted-collection/cmd.json new file mode 100644 index 000000000..7007d2b2c --- /dev/null +++ b/test/data/fle2-create-encrypted-collection/cmd.json @@ -0,0 +1,17 @@ +{ + "create": "coll", + "encryptedFields": { + "fields": [ + { + "path": "encrypted", + "bsonType": "int", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + } + ] + } +} \ No newline at end of file diff --git a/test/data/fle2-create-encrypted-collection/encrypted-field-config-map.json b/test/data/fle2-create-encrypted-collection/encrypted-field-config-map.json new file mode 100644 index 000000000..92608c3a9 --- /dev/null +++ b/test/data/fle2-create-encrypted-collection/encrypted-field-config-map.json @@ -0,0 +1,24 @@ +{ + "db.coll": { + "escCollection": "esc", + "ecocCollection": "ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encrypted", + "bsonType": "int", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + } + ] + } +} diff --git a/test/data/fle2-create-encrypted-collection/encrypted-payload.json b/test/data/fle2-create-encrypted-collection/encrypted-payload.json new file mode 100644 index 000000000..7007d2b2c --- /dev/null +++ b/test/data/fle2-create-encrypted-collection/encrypted-payload.json @@ -0,0 +1,17 @@ +{ + "create": "coll", + "encryptedFields": { + "fields": [ + { + "path": "encrypted", + "bsonType": "int", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + } + ] + } +} \ No newline at end of file diff --git a/test/data/fle2-create-encrypted-collection/mongocryptd-reply.json b/test/data/fle2-create-encrypted-collection/mongocryptd-reply.json new file mode 100644 index 000000000..f9bb1a80c --- /dev/null +++ b/test/data/fle2-create-encrypted-collection/mongocryptd-reply.json @@ -0,0 +1,50 @@ +{ + "ok": { + "$numberInt": "1" + }, + "result": { + "create": "coll", + "encryptedFields": { + "fields": [ + { + "path": "encrypted", + "bsonType": "int", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + } + ] + }, + "encryptionInformation": { + "type": 1, + "schema": { + "db.coll": { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "escCollection": "esc", + "ecocCollection": "ecoc", + "fields": [ + { + "path": "encrypted", + "bsonType": "int", + "queries": { + "queryType": "equality", + "contention": { + "$numberLong": "0" + } + } + } + ] + } + } + } + }, + "hasEncryptedPlaceholders": false +} \ No newline at end of file diff --git a/test/data/fle2-insert-text-search-with-str-encode-version/cmd.json b/test/data/fle2-insert-text-search-with-str-encode-version/cmd.json new file mode 100644 index 000000000..ca12d021d --- /dev/null +++ b/test/data/fle2-insert-text-search-with-str-encode-version/cmd.json @@ -0,0 +1,9 @@ +{ + "insert": "test", + "documents": [ + { + "_id": 1, + "ssn": "value123" + } + ] +} \ No newline at end of file diff --git a/test/data/fle2-insert-text-search-with-str-encode-version/encrypted-field-map.json b/test/data/fle2-insert-text-search-with-str-encode-version/encrypted-field-map.json new file mode 100644 index 000000000..d52efeb40 --- /dev/null +++ b/test/data/fle2-insert-text-search-with-str-encode-version/encrypted-field-map.json @@ -0,0 +1,30 @@ +{ + "db.test": { + "escCollection": "fle2.test.esc", + "ecocCollection": "fle2.test.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "ssn", + "bsonType": "string", + "queries": { + "queryType": "substringPreview", + "contention": { + "$numberLong": "0" + }, + "strMaxLength": 100, + "strMinQueryLength": 5, + "strMaxQueryLength": 20, + "caseSensitive": false, + "diacriticSensitive": true + } + } + ], + "strEncodeVersion": 1 + } +} \ No newline at end of file diff --git a/test/data/fle2-insert-text-search-with-str-encode-version/encrypted-payload.json b/test/data/fle2-insert-text-search-with-str-encode-version/encrypted-payload.json new file mode 100644 index 000000000..83927a238 --- /dev/null +++ b/test/data/fle2-insert-text-search-with-str-encode-version/encrypted-payload.json @@ -0,0 +1,47 @@ +{ + "insert": "test", + "documents": [ + { + "_id": 1, + "ssn": { + "$binary": { + "base64": "C18BAAAFZAAgAAAAAHb62aV7+mqmaGcotPLdG3KP7S8diFwWMLM/5rYtqLrEBXMAIAAAAAAVJ6OWHRv3OtCozHpt3ZzfBhaxZirLv3B+G8PuaaO4EgVwADAAAAAAx0PWdXaep4jV5cRA2yQN+ULLwjv8e++oMonpfGOGs9BZ0uqPP7waiwZSwHsDx57+BXUAEAAAAAQSNFZ4EjSYdhI0EjRWeJASEHQAAgAAAAV2AFAAAAAAq83vqxI0mHYSNBI0VniQEkzZZBBDgeZh+h+gXEmOrSHYikH9u4e644rfZY9N9UQR4h76qKAmcbo43utRcXMQy+FXXIxSuNntFHZHTcNJhJoFZQAgAAAAAOuac/eRLYakKX6B0vZ1r3QodOQFfjqJD+xlGiPu4/PsBWwAIAAAAABpn2zcb7jOd/FK3F45nBxnLU6HOMwZzmGOZ0w35v/DqRJrAAAAAAAAAAAAAA==", + "subType": "06" + } + } + } + ], + "encryptionInformation": { + "type": 1, + "schema": { + "db.test": { + "escCollection": "fle2.test.esc", + "ecocCollection": "fle2.test.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "ssn", + "bsonType": "string", + "queries": { + "queryType": "substringPreview", + "contention": { + "$numberLong": "0" + }, + "strMaxLength": 100, + "strMinQueryLength": 5, + "strMaxQueryLength": 20, + "caseSensitive": false, + "diacriticSensitive": true + } + } + ], + "strEncodeVersion": 1 + } + } + } +} diff --git a/test/data/fle2-insert-text-search-with-str-encode-version/mongocryptd-reply.json b/test/data/fle2-insert-text-search-with-str-encode-version/mongocryptd-reply.json new file mode 100644 index 000000000..30bd0e981 --- /dev/null +++ b/test/data/fle2-insert-text-search-with-str-encode-version/mongocryptd-reply.json @@ -0,0 +1,55 @@ +{ + "ok": { + "$numberInt": "1" + }, + "result": { + "insert": "test", + "documents": [ + { + "_id": 1, + "ssn": { + "$binary": { + "base64": "A2EAAAAQdAABAAAAEGEAAgAAAAVraQAQAAAABBI0VngSNJh2EjQSNFZ4kBIFa3UAEAAAAASrze+rEjSYdhI0EjRWeJASAnYACQAAAHZhbHVlMTIzABJjbQAAAAAAAAAAAAA=", + "subType": "06" + } + } + } + ], + "encryptionInformation": { + "type": { + "$numberInt": "1" + }, + "schema": { + "db.test": { + "escCollection": "fle2.test.esc", + "ecocCollection": "fle2.test.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "ssn", + "bsonType": "string", + "queries": { + "queryType": "substringPreview", + "contention": { + "$numberLong": "0" + }, + "strMaxLength": 100, + "strMinQueryLength": 5, + "strMaxQueryLength": 20, + "caseSensitive": false, + "diacriticSensitive": true + } + } + ], + "strEncodeVersion": 1 + } + } + } + }, + "hasEncryptedPlaceholders": true +} \ No newline at end of file diff --git a/test/data/fle2-insert-text-search/cmd.json b/test/data/fle2-insert-text-search/cmd.json new file mode 100644 index 000000000..ca12d021d --- /dev/null +++ b/test/data/fle2-insert-text-search/cmd.json @@ -0,0 +1,9 @@ +{ + "insert": "test", + "documents": [ + { + "_id": 1, + "ssn": "value123" + } + ] +} \ No newline at end of file diff --git a/test/data/fle2-insert-text-search/encrypted-field-map.json b/test/data/fle2-insert-text-search/encrypted-field-map.json new file mode 100644 index 000000000..066f72afc --- /dev/null +++ b/test/data/fle2-insert-text-search/encrypted-field-map.json @@ -0,0 +1,29 @@ +{ + "db.test": { + "escCollection": "fle2.test.esc", + "ecocCollection": "fle2.test.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "ssn", + "bsonType": "string", + "queries": { + "queryType": "substringPreview", + "contention": { + "$numberLong": "0" + }, + "strMaxLength": 100, + "strMinQueryLength": 5, + "strMaxQueryLength": 20, + "caseSensitive": false, + "diacriticSensitive": true + } + } + ] + } +} \ No newline at end of file diff --git a/test/data/fle2-insert-text-search/encrypted-payload.json b/test/data/fle2-insert-text-search/encrypted-payload.json new file mode 100644 index 000000000..83927a238 --- /dev/null +++ b/test/data/fle2-insert-text-search/encrypted-payload.json @@ -0,0 +1,47 @@ +{ + "insert": "test", + "documents": [ + { + "_id": 1, + "ssn": { + "$binary": { + "base64": "C18BAAAFZAAgAAAAAHb62aV7+mqmaGcotPLdG3KP7S8diFwWMLM/5rYtqLrEBXMAIAAAAAAVJ6OWHRv3OtCozHpt3ZzfBhaxZirLv3B+G8PuaaO4EgVwADAAAAAAx0PWdXaep4jV5cRA2yQN+ULLwjv8e++oMonpfGOGs9BZ0uqPP7waiwZSwHsDx57+BXUAEAAAAAQSNFZ4EjSYdhI0EjRWeJASEHQAAgAAAAV2AFAAAAAAq83vqxI0mHYSNBI0VniQEkzZZBBDgeZh+h+gXEmOrSHYikH9u4e644rfZY9N9UQR4h76qKAmcbo43utRcXMQy+FXXIxSuNntFHZHTcNJhJoFZQAgAAAAAOuac/eRLYakKX6B0vZ1r3QodOQFfjqJD+xlGiPu4/PsBWwAIAAAAABpn2zcb7jOd/FK3F45nBxnLU6HOMwZzmGOZ0w35v/DqRJrAAAAAAAAAAAAAA==", + "subType": "06" + } + } + } + ], + "encryptionInformation": { + "type": 1, + "schema": { + "db.test": { + "escCollection": "fle2.test.esc", + "ecocCollection": "fle2.test.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "ssn", + "bsonType": "string", + "queries": { + "queryType": "substringPreview", + "contention": { + "$numberLong": "0" + }, + "strMaxLength": 100, + "strMinQueryLength": 5, + "strMaxQueryLength": 20, + "caseSensitive": false, + "diacriticSensitive": true + } + } + ], + "strEncodeVersion": 1 + } + } + } +} diff --git a/test/data/fle2-insert-text-search/mongocryptd-reply.json b/test/data/fle2-insert-text-search/mongocryptd-reply.json new file mode 100644 index 000000000..30bd0e981 --- /dev/null +++ b/test/data/fle2-insert-text-search/mongocryptd-reply.json @@ -0,0 +1,55 @@ +{ + "ok": { + "$numberInt": "1" + }, + "result": { + "insert": "test", + "documents": [ + { + "_id": 1, + "ssn": { + "$binary": { + "base64": "A2EAAAAQdAABAAAAEGEAAgAAAAVraQAQAAAABBI0VngSNJh2EjQSNFZ4kBIFa3UAEAAAAASrze+rEjSYdhI0EjRWeJASAnYACQAAAHZhbHVlMTIzABJjbQAAAAAAAAAAAAA=", + "subType": "06" + } + } + } + ], + "encryptionInformation": { + "type": { + "$numberInt": "1" + }, + "schema": { + "db.test": { + "escCollection": "fle2.test.esc", + "ecocCollection": "fle2.test.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "ssn", + "bsonType": "string", + "queries": { + "queryType": "substringPreview", + "contention": { + "$numberLong": "0" + }, + "strMaxLength": 100, + "strMinQueryLength": 5, + "strMaxQueryLength": 20, + "caseSensitive": false, + "diacriticSensitive": true + } + } + ], + "strEncodeVersion": 1 + } + } + } + }, + "hasEncryptedPlaceholders": true +} \ No newline at end of file diff --git a/test/data/fle2-insert-v2-with-str-encode-version/cmd.json b/test/data/fle2-insert-v2-with-str-encode-version/cmd.json new file mode 100644 index 000000000..ca12d021d --- /dev/null +++ b/test/data/fle2-insert-v2-with-str-encode-version/cmd.json @@ -0,0 +1,9 @@ +{ + "insert": "test", + "documents": [ + { + "_id": 1, + "ssn": "value123" + } + ] +} \ No newline at end of file diff --git a/test/data/fle2-insert-v2-with-str-encode-version/encrypted-field-map.json b/test/data/fle2-insert-v2-with-str-encode-version/encrypted-field-map.json new file mode 100644 index 000000000..e3f02f231 --- /dev/null +++ b/test/data/fle2-insert-v2-with-str-encode-version/encrypted-field-map.json @@ -0,0 +1,23 @@ +{ + "db.test": { + "escCollection": "fle2.test.esc", + "ecocCollection": "fle2.test.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "ssn", + "bsonType": "string", + "queries": { + "queryType": "equality", + "contention": 0 + } + } + ], + "strEncodeVersion": 1 + } +} \ No newline at end of file diff --git a/test/data/fle2-insert-v2-with-str-encode-version/encrypted-payload.json b/test/data/fle2-insert-v2-with-str-encode-version/encrypted-payload.json new file mode 100644 index 000000000..e8a27cf54 --- /dev/null +++ b/test/data/fle2-insert-v2-with-str-encode-version/encrypted-payload.json @@ -0,0 +1,40 @@ +{ + "insert": "test", + "documents": [ + { + "_id": 1, + "ssn": { + "$binary": { + "base64": "C18BAAAFZAAgAAAAAHb62aV7+mqmaGcotPLdG3KP7S8diFwWMLM/5rYtqLrEBXMAIAAAAAAVJ6OWHRv3OtCozHpt3ZzfBhaxZirLv3B+G8PuaaO4EgVwADAAAAAAx0PWdXaep4jV5cRA2yQN+ULLwjv8e++oMonpfGOGs9BZ0uqPP7waiwZSwHsDx57+BXUAEAAAAAQSNFZ4EjSYdhI0EjRWeJASEHQAAgAAAAV2AFAAAAAAq83vqxI0mHYSNBI0VniQEkzZZBBDgeZh+h+gXEmOrSHYikH9u4e644rfZY9N9UQR4h76qKAmcbo43utRcXMQy+FXXIxSuNntFHZHTcNJhJoFZQAgAAAAAOuac/eRLYakKX6B0vZ1r3QodOQFfjqJD+xlGiPu4/PsBWwAIAAAAABpn2zcb7jOd/FK3F45nBxnLU6HOMwZzmGOZ0w35v/DqRJrAAAAAAAAAAAAAA==", + "subType": "06" + } + } + } + ], + "encryptionInformation": { + "type": 1, + "schema": { + "db.test": { + "escCollection": "fle2.test.esc", + "ecocCollection": "fle2.test.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "ssn", + "bsonType": "string", + "queries": { + "queryType": "equality", + "contention": 0 + } + } + ], + "strEncodeVersion": 1 + } + } + } +} diff --git a/test/data/fle2-insert-v2-with-str-encode-version/mongocryptd-reply.json b/test/data/fle2-insert-v2-with-str-encode-version/mongocryptd-reply.json new file mode 100644 index 000000000..7751c33f6 --- /dev/null +++ b/test/data/fle2-insert-v2-with-str-encode-version/mongocryptd-reply.json @@ -0,0 +1,50 @@ +{ + "ok": { + "$numberInt": "1" + }, + "result": { + "insert": "test", + "documents": [ + { + "_id": 1, + "ssn": { + "$binary": { + "base64": "A2EAAAAQdAABAAAAEGEAAgAAAAVraQAQAAAABBI0VngSNJh2EjQSNFZ4kBIFa3UAEAAAAASrze+rEjSYdhI0EjRWeJASAnYACQAAAHZhbHVlMTIzABJjbQAAAAAAAAAAAAA=", + "subType": "06" + } + } + } + ], + "encryptionInformation": { + "type": { + "$numberInt": "1" + }, + "schema": { + "db.test": { + "escCollection": "fle2.test.esc", + "ecocCollection": "fle2.test.ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "ssn", + "bsonType": "string", + "queries": { + "queryType": "equality", + "contention": { + "$numberInt": "0" + } + } + } + ], + "strEncodeVersion": 1 + } + } + } + }, + "hasEncryptedPlaceholders": true +} \ No newline at end of file diff --git a/test/data/fle2-text-search-create-encrypted-collection-with-str-encode-version/cmd-to-mongocryptd.json b/test/data/fle2-text-search-create-encrypted-collection-with-str-encode-version/cmd-to-mongocryptd.json new file mode 100644 index 000000000..7116f7cf2 --- /dev/null +++ b/test/data/fle2-text-search-create-encrypted-collection-with-str-encode-version/cmd-to-mongocryptd.json @@ -0,0 +1,56 @@ +{ + "create": "coll", + "encryptedFields": { + "fields": [ + { + "path": "encrypted", + "bsonType": "string", + "queries": { + "queryType": "substringPreview", + "contention": { + "$numberLong": "0" + }, + "strMaxLength": 100, + "strMinQueryLength": 5, + "strMaxQueryLength": 20, + "caseSensitive": false, + "diacriticSensitive": true + } + } + ], + "strEncodeVersion": 1 + }, + "encryptionInformation": { + "type": 1, + "schema": { + "db.coll": { + "escCollection": "esc", + "ecocCollection": "ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encrypted", + "bsonType": "string", + "queries": { + "queryType": "substringPreview", + "contention": { + "$numberLong": "0" + }, + "strMaxLength": 100, + "strMinQueryLength": 5, + "strMaxQueryLength": 20, + "caseSensitive": false, + "diacriticSensitive": true + } + } + ], + "strEncodeVersion": 1 + } + } + } +} diff --git a/test/data/fle2-text-search-create-encrypted-collection-with-str-encode-version/cmd.json b/test/data/fle2-text-search-create-encrypted-collection-with-str-encode-version/cmd.json new file mode 100644 index 000000000..f3f50a992 --- /dev/null +++ b/test/data/fle2-text-search-create-encrypted-collection-with-str-encode-version/cmd.json @@ -0,0 +1,23 @@ +{ + "create": "coll", + "encryptedFields": { + "fields": [ + { + "path": "encrypted", + "bsonType": "string", + "queries": { + "queryType": "substringPreview", + "contention": { + "$numberLong": "0" + }, + "strMaxLength": 100, + "strMinQueryLength": 5, + "strMaxQueryLength": 20, + "caseSensitive": false, + "diacriticSensitive": true + } + } + ], + "strEncodeVersion": 1 + } +} \ No newline at end of file diff --git a/test/data/fle2-text-search-create-encrypted-collection-with-str-encode-version/encrypted-field-config-map.json b/test/data/fle2-text-search-create-encrypted-collection-with-str-encode-version/encrypted-field-config-map.json new file mode 100644 index 000000000..9e8d52bdc --- /dev/null +++ b/test/data/fle2-text-search-create-encrypted-collection-with-str-encode-version/encrypted-field-config-map.json @@ -0,0 +1,30 @@ +{ + "db.coll": { + "escCollection": "esc", + "ecocCollection": "ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encrypted", + "bsonType": "string", + "queries": { + "queryType": "substringPreview", + "contention": { + "$numberLong": "0" + }, + "strMaxLength": 100, + "strMinQueryLength": 5, + "strMaxQueryLength": 20, + "caseSensitive": false, + "diacriticSensitive": true + } + } + ], + "strEncodeVersion": 1 + } +} diff --git a/test/data/fle2-text-search-create-encrypted-collection-with-str-encode-version/encrypted-payload.json b/test/data/fle2-text-search-create-encrypted-collection-with-str-encode-version/encrypted-payload.json new file mode 100644 index 000000000..f3f50a992 --- /dev/null +++ b/test/data/fle2-text-search-create-encrypted-collection-with-str-encode-version/encrypted-payload.json @@ -0,0 +1,23 @@ +{ + "create": "coll", + "encryptedFields": { + "fields": [ + { + "path": "encrypted", + "bsonType": "string", + "queries": { + "queryType": "substringPreview", + "contention": { + "$numberLong": "0" + }, + "strMaxLength": 100, + "strMinQueryLength": 5, + "strMaxQueryLength": 20, + "caseSensitive": false, + "diacriticSensitive": true + } + } + ], + "strEncodeVersion": 1 + } +} \ No newline at end of file diff --git a/test/data/fle2-text-search-create-encrypted-collection-with-str-encode-version/mongocryptd-reply.json b/test/data/fle2-text-search-create-encrypted-collection-with-str-encode-version/mongocryptd-reply.json new file mode 100644 index 000000000..b3a352436 --- /dev/null +++ b/test/data/fle2-text-search-create-encrypted-collection-with-str-encode-version/mongocryptd-reply.json @@ -0,0 +1,62 @@ +{ + "ok": { + "$numberInt": "1" + }, + "result": { + "create": "coll", + "encryptedFields": { + "fields": [ + { + "path": "encrypted", + "bsonType": "string", + "queries": { + "queryType": "substringPreview", + "contention": { + "$numberLong": "0" + }, + "strMaxLength": 100, + "strMinQueryLength": 5, + "strMaxQueryLength": 20, + "caseSensitive": false, + "diacriticSensitive": true + } + } + ], + "strEncodeVersion": 1 + }, + "encryptionInformation": { + "type": 1, + "schema": { + "db.coll": { + "escCollection": "esc", + "ecocCollection": "ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encrypted", + "bsonType": "string", + "queries": { + "queryType": "substringPreview", + "contention": { + "$numberLong": "0" + }, + "strMaxLength": 100, + "strMinQueryLength": 5, + "strMaxQueryLength": 20, + "caseSensitive": false, + "diacriticSensitive": true + } + } + ], + "strEncodeVersion": 1 + } + } + } + }, + "hasEncryptedPlaceholders": false +} \ No newline at end of file diff --git a/test/data/fle2-text-search-create-encrypted-collection/cmd-to-mongocryptd.json b/test/data/fle2-text-search-create-encrypted-collection/cmd-to-mongocryptd.json new file mode 100644 index 000000000..b88f92934 --- /dev/null +++ b/test/data/fle2-text-search-create-encrypted-collection/cmd-to-mongocryptd.json @@ -0,0 +1,55 @@ +{ + "create": "coll", + "encryptedFields": { + "fields": [ + { + "path": "encrypted", + "bsonType": "string", + "queries": { + "queryType": "substringPreview", + "contention": { + "$numberLong": "0" + }, + "strMaxLength": 100, + "strMinQueryLength": 5, + "strMaxQueryLength": 20, + "caseSensitive": false, + "diacriticSensitive": true + } + } + ] + }, + "encryptionInformation": { + "type": 1, + "schema": { + "db.coll": { + "escCollection": "esc", + "ecocCollection": "ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encrypted", + "bsonType": "string", + "queries": { + "queryType": "substringPreview", + "contention": { + "$numberLong": "0" + }, + "strMaxLength": 100, + "strMinQueryLength": 5, + "strMaxQueryLength": 20, + "caseSensitive": false, + "diacriticSensitive": true + } + } + ], + "strEncodeVersion": 1 + } + } + } +} diff --git a/test/data/fle2-text-search-create-encrypted-collection/cmd.json b/test/data/fle2-text-search-create-encrypted-collection/cmd.json new file mode 100644 index 000000000..2dbc89b0d --- /dev/null +++ b/test/data/fle2-text-search-create-encrypted-collection/cmd.json @@ -0,0 +1,22 @@ +{ + "create": "coll", + "encryptedFields": { + "fields": [ + { + "path": "encrypted", + "bsonType": "string", + "queries": { + "queryType": "substringPreview", + "contention": { + "$numberLong": "0" + }, + "strMaxLength": 100, + "strMinQueryLength": 5, + "strMaxQueryLength": 20, + "caseSensitive": false, + "diacriticSensitive": true + } + } + ] + } +} \ No newline at end of file diff --git a/test/data/fle2-text-search-create-encrypted-collection/encrypted-field-config-map.json b/test/data/fle2-text-search-create-encrypted-collection/encrypted-field-config-map.json new file mode 100644 index 000000000..7a58a8b28 --- /dev/null +++ b/test/data/fle2-text-search-create-encrypted-collection/encrypted-field-config-map.json @@ -0,0 +1,29 @@ +{ + "db.coll": { + "escCollection": "esc", + "ecocCollection": "ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encrypted", + "bsonType": "string", + "queries": { + "queryType": "substringPreview", + "contention": { + "$numberLong": "0" + }, + "strMaxLength": 100, + "strMinQueryLength": 5, + "strMaxQueryLength": 20, + "caseSensitive": false, + "diacriticSensitive": true + } + } + ] + } +} diff --git a/test/data/fle2-text-search-create-encrypted-collection/encrypted-payload.json b/test/data/fle2-text-search-create-encrypted-collection/encrypted-payload.json new file mode 100644 index 000000000..f3f50a992 --- /dev/null +++ b/test/data/fle2-text-search-create-encrypted-collection/encrypted-payload.json @@ -0,0 +1,23 @@ +{ + "create": "coll", + "encryptedFields": { + "fields": [ + { + "path": "encrypted", + "bsonType": "string", + "queries": { + "queryType": "substringPreview", + "contention": { + "$numberLong": "0" + }, + "strMaxLength": 100, + "strMinQueryLength": 5, + "strMaxQueryLength": 20, + "caseSensitive": false, + "diacriticSensitive": true + } + } + ], + "strEncodeVersion": 1 + } +} \ No newline at end of file diff --git a/test/data/fle2-text-search-create-encrypted-collection/mongocryptd-reply.json b/test/data/fle2-text-search-create-encrypted-collection/mongocryptd-reply.json new file mode 100644 index 000000000..0231a2b77 --- /dev/null +++ b/test/data/fle2-text-search-create-encrypted-collection/mongocryptd-reply.json @@ -0,0 +1,61 @@ +{ + "ok": { + "$numberInt": "1" + }, + "result": { + "create": "coll", + "encryptedFields": { + "fields": [ + { + "path": "encrypted", + "bsonType": "string", + "queries": { + "queryType": "substringPreview", + "contention": { + "$numberLong": "0" + }, + "strMaxLength": 100, + "strMinQueryLength": 5, + "strMaxQueryLength": 20, + "caseSensitive": false, + "diacriticSensitive": true + } + } + ] + }, + "encryptionInformation": { + "type": 1, + "schema": { + "db.coll": { + "escCollection": "esc", + "ecocCollection": "ecoc", + "fields": [ + { + "keyId": { + "$binary": { + "base64": "EjRWeBI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "path": "encrypted", + "bsonType": "string", + "queries": { + "queryType": "substringPreview", + "contention": { + "$numberLong": "0" + }, + "strMaxLength": 100, + "strMinQueryLength": 5, + "strMaxQueryLength": 20, + "caseSensitive": false, + "diacriticSensitive": true + } + } + ], + "strEncodeVersion": 1 + } + } + } + }, + "hasEncryptedPlaceholders": false +} \ No newline at end of file diff --git a/test/test-mc-efc.c b/test/test-mc-efc.c index 91c7e8752..156961324 100644 --- a/test/test-mc-efc.c +++ b/test/test-mc-efc.c @@ -39,6 +39,19 @@ static void _test_efc(_mongocrypt_tester_t *tester) { { _load_test_file(tester, "./test/data/efc/efc-oneField.json", &efc_bson); ASSERT_OK_STATUS(mc_EncryptedFieldConfig_parse(&efc, &efc_bson, status, use_range_v2), status); + ASSERT_CMPUINT8(efc.str_encode_version, ==, 0); + ptr = efc.fields; + ASSERT(ptr); + ASSERT_STREQUAL(ptr->path, "firstName"); + ASSERT_CMPBUF(expect_keyId1, ptr->keyId); + ASSERT(ptr->next == NULL); + mc_EncryptedFieldConfig_cleanup(&efc); + } + + { + _load_test_file(tester, "./test/data/efc/efc-oneField-goodVersionSet.json", &efc_bson); + ASSERT_OK_STATUS(mc_EncryptedFieldConfig_parse(&efc, &efc_bson, status, use_range_v2), status); + ASSERT_CMPUINT8(efc.str_encode_version, ==, 1); ptr = efc.fields; ASSERT(ptr); ASSERT_STREQUAL(ptr->path, "firstName"); @@ -50,6 +63,7 @@ static void _test_efc(_mongocrypt_tester_t *tester) { { _load_test_file(tester, "./test/data/efc/efc-extraField.json", &efc_bson); ASSERT_OK_STATUS(mc_EncryptedFieldConfig_parse(&efc, &efc_bson, status, use_range_v2), status); + ASSERT_CMPUINT8(efc.str_encode_version, ==, 0); ptr = efc.fields; ASSERT(ptr); ASSERT_STREQUAL(ptr->path, "firstName"); @@ -61,6 +75,7 @@ static void _test_efc(_mongocrypt_tester_t *tester) { { _load_test_file(tester, "./test/data/efc/efc-twoFields.json", &efc_bson); ASSERT_OK_STATUS(mc_EncryptedFieldConfig_parse(&efc, &efc_bson, status, use_range_v2), status); + ASSERT_CMPUINT8(efc.str_encode_version, ==, 0); ptr = efc.fields; ASSERT(ptr); ASSERT_STREQUAL(ptr->path, "lastName"); @@ -82,9 +97,37 @@ static void _test_efc(_mongocrypt_tester_t *tester) { _mongocrypt_status_reset(status); } + { + _load_test_file(tester, "./test/data/efc/efc-oneField-badVersionSet.json", &efc_bson); + ASSERT_FAILS_STATUS(mc_EncryptedFieldConfig_parse(&efc, &efc_bson, status, use_range_v2), + status, + "'strEncodeVersion' of 99 is not supported"); + mc_EncryptedFieldConfig_cleanup(&efc); + _mongocrypt_status_reset(status); + } + { _load_test_file(tester, "./test/data/efc/efc-textSearchFields.json", &efc_bson); ASSERT_OK_STATUS(mc_EncryptedFieldConfig_parse(&efc, &efc_bson, status, use_range_v2), status); + ASSERT_CMPUINT8(efc.str_encode_version, ==, LATEST_STR_ENCODE_VERSION); + ptr = efc.fields; + ASSERT(ptr); + ASSERT_STREQUAL(ptr->path, "lastName"); + ASSERT_CMPBUF(expect_keyId2, ptr->keyId); + ASSERT(ptr->supported_queries == (SUPPORTS_SUFFIX_PREVIEW_QUERIES | SUPPORTS_PREFIX_PREVIEW_QUERIES)); + ASSERT(ptr->next != NULL); + ptr = ptr->next; + ASSERT_STREQUAL(ptr->path, "firstName"); + ASSERT_CMPBUF(expect_keyId1, ptr->keyId); + ASSERT(ptr->supported_queries == SUPPORTS_SUBSTRING_PREVIEW_QUERIES); + ASSERT(ptr->next == NULL); + mc_EncryptedFieldConfig_cleanup(&efc); + } + + { + _load_test_file(tester, "./test/data/efc/efc-textSearchFields-goodVersionSet.json", &efc_bson); + ASSERT_OK_STATUS(mc_EncryptedFieldConfig_parse(&efc, &efc_bson, status, use_range_v2), status); + ASSERT_CMPUINT8(efc.str_encode_version, ==, 1); ptr = efc.fields; ASSERT(ptr); ASSERT_STREQUAL(ptr->path, "lastName"); @@ -99,6 +142,15 @@ static void _test_efc(_mongocrypt_tester_t *tester) { mc_EncryptedFieldConfig_cleanup(&efc); } + { + _load_test_file(tester, "./test/data/efc/efc-textSearchFields-badVersionSet.json", &efc_bson); + ASSERT_FAILS_STATUS(mc_EncryptedFieldConfig_parse(&efc, &efc_bson, status, use_range_v2), + status, + "'strEncodeVersion' of 99 is not supported"); + mc_EncryptedFieldConfig_cleanup(&efc); + _mongocrypt_status_reset(status); + } + _mongocrypt_buffer_cleanup(&expect_keyId2); _mongocrypt_buffer_cleanup(&expect_keyId1); mongocrypt_status_destroy(status); diff --git a/test/test-mongocrypt-ctx-encrypt.c b/test/test-mongocrypt-ctx-encrypt.c index abda18d56..e7805a8f4 100644 --- a/test/test-mongocrypt-ctx-encrypt.c +++ b/test/test-mongocrypt-ctx-encrypt.c @@ -20,6 +20,7 @@ #include "mongocrypt-crypto-private.h" // MONGOCRYPT_KEY_LEN #include "mongocrypt.h" #include "test-mongocrypt-assert-match-bson.h" +#include "test-mongocrypt-assert.h" #include "test-mongocrypt-crypto-std-hooks.h" #include "test-mongocrypt.h" @@ -1716,6 +1717,27 @@ static void _test_encrypt_fle2_insert_payload(_mongocrypt_tester_t *tester) { TEST_ENCRYPT_FLE2_ENCRYPTION_PLACEHOLDER(tester, "fle2-insert-v2", &source, NULL) } +static void _test_encrypt_fle2_insert_payload_with_str_encode_version(_mongocrypt_tester_t *tester) { + uint8_t rng_data[] = RNG_DATA; + + _test_rng_data_source source = {.buf = {.data = rng_data, .len = sizeof(rng_data) - 1u}}; + TEST_ENCRYPT_FLE2_ENCRYPTION_PLACEHOLDER(tester, "fle2-insert-v2-with-str-encode-version", &source, NULL) +} + +static void _test_encrypt_fle2_insert_text_search_payload(_mongocrypt_tester_t *tester) { + uint8_t rng_data[] = RNG_DATA; + + _test_rng_data_source source = {.buf = {.data = rng_data, .len = sizeof(rng_data) - 1u}}; + TEST_ENCRYPT_FLE2_ENCRYPTION_PLACEHOLDER(tester, "fle2-insert-text-search", &source, NULL) +} + +static void _test_encrypt_fle2_insert_text_search_payload_with_str_encode_version(_mongocrypt_tester_t *tester) { + uint8_t rng_data[] = RNG_DATA; + + _test_rng_data_source source = {.buf = {.data = rng_data, .len = sizeof(rng_data) - 1u}}; + TEST_ENCRYPT_FLE2_ENCRYPTION_PLACEHOLDER(tester, "fle2-insert-text-search-with-str-encode-version", &source, NULL) +} + #undef RNG_DATA // FLE2FindEqualityPayload only uses deterministic token generation. @@ -3257,6 +3279,25 @@ static void _test_dollardb_preserved_fle1(_mongocrypt_tester_t *tester) { mongocrypt_destroy(crypt); } +#define expect_and_reply_to_ismaster(ctx) \ + do { \ + ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_MARKINGS); \ + { \ + mongocrypt_binary_t *cmd_to_mongocryptd = mongocrypt_binary_new(); \ + \ + ASSERT_OK(mongocrypt_ctx_mongo_op(ctx, cmd_to_mongocryptd), ctx); \ + ASSERT_MONGOCRYPT_BINARY_EQUAL_BSON(TEST_FILE("./test/data/fle1-create/without-schema/" \ + "ismaster-to-mongocryptd.json"), \ + cmd_to_mongocryptd); \ + mongocrypt_binary_destroy(cmd_to_mongocryptd); \ + ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, \ + TEST_FILE("./test/data/fle1-create/without-schema/" \ + "mongocryptd-ismaster.json")), \ + ctx); \ + ASSERT_OK(mongocrypt_ctx_mongo_done(ctx), ctx); \ + } \ + } while (0) + static void _test_fle1_create_without_schema(_mongocrypt_tester_t *tester) { mongocrypt_t *crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_DEFAULT); mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt); @@ -3264,21 +3305,7 @@ static void _test_fle1_create_without_schema(_mongocrypt_tester_t *tester) { ASSERT_OK(mongocrypt_ctx_encrypt_init(ctx, "db", -1, TEST_FILE("./test/data/fle1-create/without-schema/cmd.json")), ctx); - ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_MARKINGS); - { - mongocrypt_binary_t *cmd_to_mongocryptd = mongocrypt_binary_new(); - - ASSERT_OK(mongocrypt_ctx_mongo_op(ctx, cmd_to_mongocryptd), ctx); - ASSERT_MONGOCRYPT_BINARY_EQUAL_BSON(TEST_FILE("./test/data/fle1-create/without-schema/" - "ismaster-to-mongocryptd.json"), - cmd_to_mongocryptd); - mongocrypt_binary_destroy(cmd_to_mongocryptd); - ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, - TEST_FILE("./test/data/fle1-create/without-schema/" - "mongocryptd-ismaster.json")), - ctx); - ASSERT_OK(mongocrypt_ctx_mongo_done(ctx), ctx); - } + expect_and_reply_to_ismaster(ctx); ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_MARKINGS); { @@ -3322,21 +3349,7 @@ static void _test_fle1_create_with_schema(_mongocrypt_tester_t *tester) { ASSERT_OK(mongocrypt_ctx_encrypt_init(ctx, "db", -1, TEST_FILE("./test/data/fle1-create/with-schema/cmd.json")), ctx); - ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_MARKINGS); - { - mongocrypt_binary_t *cmd_to_mongocryptd = mongocrypt_binary_new(); - - ASSERT_OK(mongocrypt_ctx_mongo_op(ctx, cmd_to_mongocryptd), ctx); - ASSERT_MONGOCRYPT_BINARY_EQUAL_BSON(TEST_FILE("./test/data/fle1-create/with-schema/" - "ismaster-to-mongocryptd.json"), - cmd_to_mongocryptd); - mongocrypt_binary_destroy(cmd_to_mongocryptd); - ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, - TEST_FILE("./test/data/fle1-create/with-schema/" - "mongocryptd-ismaster.json")), - ctx); - ASSERT_OK(mongocrypt_ctx_mongo_done(ctx), ctx); - } + expect_and_reply_to_ismaster(ctx); ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_MARKINGS); { @@ -3375,21 +3388,7 @@ static void _test_fle1_create_with_cmd_schema(_mongocrypt_tester_t *tester) { ASSERT_OK(mongocrypt_ctx_encrypt_init(ctx, "db", -1, TEST_FILE("./test/data/fle1-create/with-cmd-schema/cmd.json")), ctx); - ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_MARKINGS); - { - mongocrypt_binary_t *cmd_to_mongocryptd = mongocrypt_binary_new(); - - ASSERT_OK(mongocrypt_ctx_mongo_op(ctx, cmd_to_mongocryptd), ctx); - ASSERT_MONGOCRYPT_BINARY_EQUAL_BSON(TEST_FILE("./test/data/fle1-create/with-cmd-schema/" - "ismaster-to-mongocryptd.json"), - cmd_to_mongocryptd); - mongocrypt_binary_destroy(cmd_to_mongocryptd); - ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, - TEST_FILE("./test/data/fle1-create/with-cmd-schema/" - "mongocryptd-ismaster.json")), - ctx); - ASSERT_OK(mongocrypt_ctx_mongo_done(ctx), ctx); - } + expect_and_reply_to_ismaster(ctx); ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_MARKINGS); { @@ -3483,45 +3482,32 @@ static void _test_fle1_create_with_csfle(_mongocrypt_tester_t *tester) { mongocrypt_destroy(crypt); } -static void _test_fle2_create(_mongocrypt_tester_t *tester) { +static void test_successful_fle2_create(_mongocrypt_tester_t *tester, + const char *efc_map_path, + const char *cmd_path, + const char *cmd_to_cryptd_path, + const char *cryptd_reply_path, + const char *encrypted_payload_path) { mongocrypt_t *crypt = mongocrypt_new(); ASSERT_OK(mongocrypt_setopt_kms_provider_aws(crypt, "example", -1, "example", -1), crypt); - ASSERT_OK(mongocrypt_setopt_encrypted_field_config_map( - crypt, - TEST_FILE("./test/data/fle2-create/encrypted-field-config-map.json")), - crypt); + ASSERT_OK(mongocrypt_setopt_encrypted_field_config_map(crypt, TEST_FILE(efc_map_path)), crypt); ASSERT_OK(_mongocrypt_init_for_test(crypt), crypt); mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt); - ASSERT_OK(mongocrypt_ctx_encrypt_init(ctx, "db", -1, TEST_FILE("./test/data/fle2-create/cmd.json")), ctx); - - ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_MARKINGS); - { - mongocrypt_binary_t *cmd_to_mongocryptd = mongocrypt_binary_new(); + ASSERT_OK(mongocrypt_ctx_encrypt_init(ctx, "db", -1, TEST_FILE(cmd_path)), ctx); - ASSERT_OK(mongocrypt_ctx_mongo_op(ctx, cmd_to_mongocryptd), ctx); - ASSERT_MONGOCRYPT_BINARY_EQUAL_BSON(TEST_FILE("./test/data/fle1-create/without-schema/" - "ismaster-to-mongocryptd.json"), - cmd_to_mongocryptd); - mongocrypt_binary_destroy(cmd_to_mongocryptd); - ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, - TEST_FILE("./test/data/fle1-create/without-schema/" - "mongocryptd-ismaster.json")), - ctx); - ASSERT_OK(mongocrypt_ctx_mongo_done(ctx), ctx); - } + expect_and_reply_to_ismaster(ctx); ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_MARKINGS); { mongocrypt_binary_t *cmd_to_mongocryptd = mongocrypt_binary_new(); ASSERT_OK(mongocrypt_ctx_mongo_op(ctx, cmd_to_mongocryptd), ctx); - ASSERT_MONGOCRYPT_BINARY_EQUAL_BSON(TEST_FILE("./test/data/fle2-create/cmd-to-mongocryptd.json"), - cmd_to_mongocryptd); + ASSERT_MONGOCRYPT_BINARY_EQUAL_BSON(TEST_FILE(cmd_to_cryptd_path), cmd_to_mongocryptd); mongocrypt_binary_destroy(cmd_to_mongocryptd); - ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, TEST_FILE("./test/data/fle2-create/mongocryptd-reply.json")), ctx); + ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, TEST_FILE(cryptd_reply_path)), ctx); ASSERT_OK(mongocrypt_ctx_mongo_done(ctx), ctx); } @@ -3529,7 +3515,7 @@ static void _test_fle2_create(_mongocrypt_tester_t *tester) { { mongocrypt_binary_t *out = mongocrypt_binary_new(); ASSERT_OK(mongocrypt_ctx_finalize(ctx, out), ctx); - ASSERT_MONGOCRYPT_BINARY_EQUAL_BSON(TEST_FILE("./test/data/fle2-create/encrypted-payload.json"), out); + ASSERT_MONGOCRYPT_BINARY_EQUAL_BSON(TEST_FILE(encrypted_payload_path), out); mongocrypt_binary_destroy(out); } @@ -3537,6 +3523,58 @@ static void _test_fle2_create(_mongocrypt_tester_t *tester) { mongocrypt_destroy(crypt); } +#define TEST_SUCCESSFUL_FLE2_CREATE(efc_path, cmd_path, cryptd_path, payload_path) \ + test_successful_fle2_create(tester, \ + "./test/data/" efc_path "/encrypted-field-config-map.json", \ + "./test/data/" cmd_path "/cmd.json", \ + "./test/data/" cryptd_path "/cmd-to-mongocryptd.json", \ + "./test/data/" cryptd_path "/mongocryptd-reply.json", \ + "./test/data/" payload_path "/encrypted-payload.json") + +#define TEST_SUCCESSFUL_FLE2_CREATE_ONEDIR(path) TEST_SUCCESSFUL_FLE2_CREATE(path, path, path, path) + +static void _test_fle2_create(_mongocrypt_tester_t *tester) { + TEST_SUCCESSFUL_FLE2_CREATE_ONEDIR("fle2-create"); +} + +static void _test_fle2_create_with_encrypted_fields(_mongocrypt_tester_t *tester) { + TEST_SUCCESSFUL_FLE2_CREATE_ONEDIR("fle2-create-encrypted-collection"); +} + +static void _test_fle2_create_with_encrypted_fields_and_str_encode_version(_mongocrypt_tester_t *tester) { + TEST_SUCCESSFUL_FLE2_CREATE_ONEDIR("fle2-create-encrypted-collection-with-str-encode-version"); +} + +static void _test_fle2_create_with_encrypted_fields_unset_str_encode_version(_mongocrypt_tester_t *tester) { + TEST_SUCCESSFUL_FLE2_CREATE("fle2-create-encrypted-collection-with-str-encode-version", + "fle2-create-encrypted-collection", + "fle2-create-encrypted-collection-encrypted-fields-unset-str-encode-version", + "fle2-create-encrypted-collection-with-str-encode-version"); +} + +static void _test_fle2_text_search_create_with_encrypted_fields(_mongocrypt_tester_t *tester) { + TEST_SUCCESSFUL_FLE2_CREATE_ONEDIR("fle2-text-search-create-encrypted-collection"); +} + +static void _test_fle2_text_search_create_with_encrypted_fields_and_str_encode_version(_mongocrypt_tester_t *tester) { + TEST_SUCCESSFUL_FLE2_CREATE_ONEDIR("fle2-text-search-create-encrypted-collection-with-str-encode-version"); +} + +static void _test_fle2_text_search_create_with_encrypted_fields_unset_str_encode_version(_mongocrypt_tester_t *tester) { + TEST_SUCCESSFUL_FLE2_CREATE("fle2-text-search-create-encrypted-collection-with-str-encode-version", + "fle2-text-search-create-encrypted-collection", + "fle2-text-search-create-encrypted-collection", + "fle2-text-search-create-encrypted-collection-with-str-encode-version"); +} + +static void +_test_fle2_text_search_create_with_encrypted_fields_unmatching_str_encode_version(_mongocrypt_tester_t *tester) { + TEST_SUCCESSFUL_FLE2_CREATE("fle2-text-search-create-encrypted-collection", + "fle2-text-search-create-encrypted-collection-with-str-encode-version", + "fle2-text-search-create-encrypted-collection-with-str-encode-version", + "fle2-text-search-create-encrypted-collection-with-str-encode-version"); +} + /* Regression test for MONGOCRYPT-435 */ static void _test_fle2_create_bypass_query_analysis(_mongocrypt_tester_t *tester) { mongocrypt_t *crypt = mongocrypt_new(); @@ -4703,6 +4741,92 @@ static void _test_does_not_warn_for_empty_local_schema(_mongocrypt_tester_t *tes mongocrypt_destroy(crypt); } +static void _test_fle2_encrypted_field_config_with_bad_str_encode_version(_mongocrypt_tester_t *tester) { + mongocrypt_t *crypt = mongocrypt_new(); + + ASSERT_OK(mongocrypt_setopt_kms_provider_aws(crypt, "example", -1, "example", -1), crypt); + ASSERT_OK(mongocrypt_setopt_encrypted_field_config_map( + crypt, + TEST_FILE("./test/data/fle2-bad-str-encode-version/bad-encrypted-field-config-map.json")), + crypt); + ASSERT_OK(_mongocrypt_init_for_test(crypt), crypt); + + mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt); + ASSERT_FAILS(mongocrypt_ctx_encrypt_init(ctx, "db", -1, TEST_FILE("./test/data/fle2-insert-v2/cmd.json")), + ctx, + "'strEncodeVersion' of 99 is not supported"); + + mongocrypt_ctx_destroy(ctx); + mongocrypt_destroy(crypt); +} + +static void _test_fle2_encrypted_fields_with_unmatching_str_encode_version(_mongocrypt_tester_t *tester) { + mongocrypt_t *crypt = mongocrypt_new(); + + ASSERT_OK(mongocrypt_setopt_kms_provider_aws(crypt, "example", -1, "example", -1), crypt); + ASSERT_OK(mongocrypt_setopt_encrypted_field_config_map(crypt, + TEST_FILE("./test/data/fle2-create-encrypted-collection/" + "encrypted-field-config-map.json")), + crypt); + ASSERT_OK(_mongocrypt_init_for_test(crypt), crypt); + + mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt); + + ASSERT_OK(mongocrypt_ctx_encrypt_init( + ctx, + "db", + -1, + TEST_FILE("./test/data/fle2-create-encrypted-collection-with-str-encode-version/cmd.json")), + ctx); + + expect_and_reply_to_ismaster(ctx); + + ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_MARKINGS); + { + mongocrypt_binary_t *cmd_to_mongocryptd = mongocrypt_binary_new(); + + ASSERT_OK(mongocrypt_ctx_mongo_op(ctx, cmd_to_mongocryptd), ctx); + ASSERT_MONGOCRYPT_BINARY_EQUAL_BSON( + TEST_FILE("./test/data/fle2-bad-str-encode-version/bad-create-cmd-to-mongocryptd.json"), + cmd_to_mongocryptd); + mongocrypt_binary_destroy(cmd_to_mongocryptd); + ASSERT_OK(mongocrypt_ctx_mongo_feed( + ctx, + TEST_FILE("./test/data/fle2-bad-str-encode-version/bad-create-cmd-mongocryptd-reply.json")), + ctx); + ASSERT_OK(mongocrypt_ctx_mongo_done(ctx), ctx); + } + + ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_READY); + { + mongocrypt_binary_t *out = mongocrypt_binary_new(); + ASSERT_FAILS(mongocrypt_ctx_finalize(ctx, out), + ctx, + "'strEncodeVersion' of 1 does not match efc->str_encode_version of 0"); + mongocrypt_binary_destroy(out); + } + + mongocrypt_ctx_destroy(ctx); + mongocrypt_destroy(crypt); +} + +static void _test_fle2_collinfo_with_bad_str_encode_version(_mongocrypt_tester_t *tester) { + mongocrypt_t *crypt = mongocrypt_new(); + ASSERT_OK(mongocrypt_setopt_kms_provider_aws(crypt, "example", -1, "example", -1), crypt); + ASSERT_OK(_mongocrypt_init_for_test(crypt), crypt); + mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt); + + ASSERT_OK(mongocrypt_ctx_encrypt_init(ctx, "db", -1, TEST_FILE("./test/data/fle2-insert-v2/cmd.json")), ctx); + + ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_COLLINFO); + ASSERT_FAILS(mongocrypt_ctx_mongo_feed(ctx, TEST_FILE("./test/data/fle2-bad-str-encode-version/bad-collinfo.json")), + ctx, + "'strEncodeVersion' of 99 is not supported"); + + mongocrypt_ctx_destroy(ctx); + mongocrypt_destroy(crypt); +} + void _mongocrypt_tester_install_ctx_encrypt(_mongocrypt_tester_t *tester) { INSTALL_TEST(_test_explicit_encrypt_init); INSTALL_TEST(_test_encrypt_init); @@ -4738,6 +4862,7 @@ void _mongocrypt_tester_install_ctx_encrypt(_mongocrypt_tester_t *tester) { INSTALL_TEST(_test_encrypt_remote_encryptedfields); INSTALL_TEST(_test_encrypt_with_bypassqueryanalysis); INSTALL_TEST(_test_encrypt_fle2_insert_payload); + INSTALL_TEST(_test_encrypt_fle2_insert_payload_with_str_encode_version); INSTALL_TEST(_test_encrypt_fle2_find_payload); INSTALL_TEST(_test_encrypt_fle2_unindexed_encrypted_payload); INSTALL_TEST(_test_encrypt_fle2_explicit); @@ -4758,6 +4883,13 @@ void _mongocrypt_tester_install_ctx_encrypt(_mongocrypt_tester_t *tester) { INSTALL_TEST(_test_fle1_create_old_mongocryptd); INSTALL_TEST(_test_fle1_create_with_csfle); INSTALL_TEST(_test_fle2_create); + INSTALL_TEST(_test_fle2_create_with_encrypted_fields); + INSTALL_TEST(_test_fle2_create_with_encrypted_fields_and_str_encode_version); + INSTALL_TEST(_test_fle2_create_with_encrypted_fields_unset_str_encode_version); + INSTALL_TEST(_test_fle2_text_search_create_with_encrypted_fields); + INSTALL_TEST(_test_fle2_text_search_create_with_encrypted_fields_and_str_encode_version); + INSTALL_TEST(_test_fle2_text_search_create_with_encrypted_fields_unset_str_encode_version); + INSTALL_TEST(_test_fle2_text_search_create_with_encrypted_fields_unmatching_str_encode_version); INSTALL_TEST(_test_fle2_create_bypass_query_analysis); INSTALL_TEST(_test_encrypt_macos_no_ctr); INSTALL_TEST(_test_fle1_collmod_with_jsonSchema); @@ -4780,10 +4912,15 @@ void _mongocrypt_tester_install_ctx_encrypt(_mongocrypt_tester_t *tester) { INSTALL_TEST(_test_encrypt_fle2_find_range_payload_decimal128); INSTALL_TEST(_test_encrypt_fle2_find_range_payload_decimal128_precision); #endif + INSTALL_TEST(_test_encrypt_fle2_insert_text_search_payload); + INSTALL_TEST(_test_encrypt_fle2_insert_text_search_payload_with_str_encode_version); INSTALL_TEST(_test_bulkWrite); INSTALL_TEST(_test_rangePreview_fails); INSTALL_TEST(_test_no_trimFactor); INSTALL_TEST(_test_range_sends_cryptoParams); INSTALL_TEST(_test_encrypt_retry); INSTALL_TEST(_test_does_not_warn_for_empty_local_schema); + INSTALL_TEST(_test_fle2_encrypted_field_config_with_bad_str_encode_version); + INSTALL_TEST(_test_fle2_encrypted_fields_with_unmatching_str_encode_version); + INSTALL_TEST(_test_fle2_collinfo_with_bad_str_encode_version); }