Skip to content

Commit

Permalink
MONGOCRYPT-463 check the collMod command for validator.$jsonSchema (
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinAlbs committed Aug 12, 2022
1 parent affe1d9 commit f87e575
Show file tree
Hide file tree
Showing 7 changed files with 126 additions and 8 deletions.
23 changes: 15 additions & 8 deletions src/mongocrypt-ctx-encrypt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1935,8 +1935,9 @@ _try_empty_schema_for_create (mongocrypt_ctx_t *ctx)
return true;
}

/* _try_schema_from_create_cmd tries to find a JSON schema included in a create
* command by checking for "validator.$jsonSchema". Example:
/* _try_schema_from_create_or_collMod_cmd tries to find a JSON schema included
* in a create or collMod command by checking for "validator.$jsonSchema".
* Example:
* {
* "create" : "coll",
* "validator" : {
Expand All @@ -1947,18 +1948,23 @@ _try_empty_schema_for_create (mongocrypt_ctx_t *ctx)
* }
* If the "create" command does not include a JSON schema, an empty JSON schema
* is returned. This is to avoid an unnecessary 'listCollections' command for
* create. */
* create.
*
* If the "collMod" command does not include a JSON schema, a schema is later
* requested by entering the MONGOCRYPT_CTX_NEED_MONGO_COLLINFO state.
* This is because a "collMod" command may have sensitive data in the
* "validator" field.
*/
static bool
_try_schema_from_create_cmd (mongocrypt_ctx_t *ctx)
_try_schema_from_create_or_collMod_cmd (mongocrypt_ctx_t *ctx)
{
_mongocrypt_ctx_encrypt_t *ectx;
mongocrypt_status_t *status = ctx->status;

ectx = (_mongocrypt_ctx_encrypt_t *) ctx;
/* As a special case, use an empty schema for the 'create' command. */
const char *cmd_name = ectx->cmd_name;

if (0 != strcmp (cmd_name, "create")) {
if (0 != strcmp (cmd_name, "create") && 0 != strcmp (cmd_name, "collMod")) {
return true;
}

Expand Down Expand Up @@ -2138,7 +2144,8 @@ mongocrypt_ctx_explicit_encrypt_init (mongocrypt_ctx_t *ctx,
if (ctx->opts.index_type.set &&
ctx->opts.index_type.value == MONGOCRYPT_INDEX_TYPE_EQUALITY &&
!ctx->opts.contention_factor.set) {
return _mongocrypt_ctx_fail_w_msg (ctx, "contention factor is required for indexed algorithm");
return _mongocrypt_ctx_fail_w_msg (
ctx, "contention factor is required for indexed algorithm");
}

ectx = (_mongocrypt_ctx_encrypt_t *) ctx;
Expand Down Expand Up @@ -2523,7 +2530,7 @@ mongocrypt_ctx_encrypt_ismaster_done (mongocrypt_ctx_t *ctx)
return false;
}
if (_mongocrypt_buffer_empty (&ectx->encrypted_field_config)) {
if (!_try_schema_from_create_cmd (ctx)) {
if (!_try_schema_from_create_or_collMod_cmd (ctx)) {
return false;
}

Expand Down
12 changes: 12 additions & 0 deletions test/data/fle1-collMod/cmd-to-mongocryptd.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"collMod": "encryptedCollection",
"validator": {
"$jsonSchema": {
"bsonType": "object"
}
},
"jsonSchema": {
"bsonType": "object"
},
"isRemoteSchema": true
}
8 changes: 8 additions & 0 deletions test/data/fle1-collMod/cmd.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"collMod": "encryptedCollection",
"validator": {
"$jsonSchema": {
"bsonType": "object"
}
}
}
8 changes: 8 additions & 0 deletions test/data/fle1-collMod/insert/cmd.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"insert": "encryptedCollection",
"documents": [
{
"x": 1
}
]
}
9 changes: 9 additions & 0 deletions test/data/fle1-collMod/insert/collinfo.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"options": {
"validator": {
"$jsonSchema": {
"bsonType": "object"
}
}
}
}
14 changes: 14 additions & 0 deletions test/data/fle1-collMod/mongocryptd-reply.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"ok": {
"$numberInt": "1"
},
"result": {
"collMod": "encryptedCollection",
"validator": {
"$jsonSchema": {
"bsonType": "object"
}
}
},
"hasEncryptedPlaceholders": false
}
60 changes: 60 additions & 0 deletions test/test-mongocrypt-ctx-encrypt.c
Original file line number Diff line number Diff line change
Expand Up @@ -4379,6 +4379,64 @@ _test_encrypt_macos_no_ctr (_mongocrypt_tester_t *tester)
mongocrypt_destroy (crypt);
}

/* If collMod contains a $jsonSchema, expect the same $jsonSchema to be used in
* the command to mongocryptd. This is a regression test for MONGOCRYPT-463. */
static void
_test_fle1_collmod_with_jsonSchema (_mongocrypt_tester_t *tester)
{
mongocrypt_t *crypt =
_mongocrypt_tester_mongocrypt (TESTER_MONGOCRYPT_DEFAULT);

mongocrypt_ctx_t *ctx = mongocrypt_ctx_new (crypt);

ASSERT_OK (
mongocrypt_ctx_encrypt_init (
ctx, "db", -1, TEST_FILE ("./test/data/fle1-collMod/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-collMod/cmd-to-mongocryptd.json"),
cmd_to_mongocryptd);
mongocrypt_binary_destroy (cmd_to_mongocryptd);
ASSERT_OK (
mongocrypt_ctx_mongo_feed (
ctx, TEST_FILE ("./test/data/fle1-collMod/mongocryptd-reply.json")),
ctx);
ASSERT_OK (mongocrypt_ctx_mongo_done (ctx), ctx);
}

mongocrypt_ctx_destroy (ctx);
mongocrypt_destroy (crypt);
}

/* If collMod does not contain a $jsonSchema, expect a schema to be requested.
*/
static void
_test_fle1_collmod_without_jsonSchema (_mongocrypt_tester_t *tester)
{
mongocrypt_t *crypt =
_mongocrypt_tester_mongocrypt (TESTER_MONGOCRYPT_DEFAULT);

mongocrypt_ctx_t *ctx = mongocrypt_ctx_new (crypt);

ASSERT_OK (
mongocrypt_ctx_encrypt_init (
ctx, "db", -1, TEST_BSON ("{'collMod': 'encryptedCollection'}")),
ctx);

ASSERT_STATE_EQUAL (mongocrypt_ctx_state (ctx),
MONGOCRYPT_CTX_NEED_MONGO_COLLINFO);

mongocrypt_ctx_destroy (ctx);
mongocrypt_destroy (crypt);
}

void
_mongocrypt_tester_install_ctx_encrypt (_mongocrypt_tester_t *tester)
{
Expand Down Expand Up @@ -4438,4 +4496,6 @@ _mongocrypt_tester_install_ctx_encrypt (_mongocrypt_tester_t *tester)
INSTALL_TEST (_test_fle2_create);
INSTALL_TEST (_test_fle2_create_bypass_query_analysis);
INSTALL_TEST (_test_encrypt_macos_no_ctr);
INSTALL_TEST (_test_fle1_collmod_with_jsonSchema);
INSTALL_TEST (_test_fle1_collmod_without_jsonSchema);
}

0 comments on commit f87e575

Please sign in to comment.