|
17 | 17 | #include <mongocrypt-marking-private.h> |
18 | 18 |
|
19 | 19 | #include "kms_message/kms_b64.h" |
| 20 | +#include "mc-fle2-insert-update-payload-private-v2.h" |
20 | 21 | #include "mongocrypt-binary-private.h" |
21 | 22 | #include "mongocrypt-crypto-private.h" // MONGOCRYPT_KEY_LEN |
22 | 23 | #include "mongocrypt.h" |
@@ -5976,6 +5977,87 @@ static void _test_lookup(_mongocrypt_tester_t *tester) { |
5976 | 5977 | #undef TF |
5977 | 5978 | } |
5978 | 5979 |
|
| 5980 | +static bool _deterministic_contention(int64_t exclusive_upper_bound, int64_t *out) { |
| 5981 | + ASSERT(out); |
| 5982 | + (void)exclusive_upper_bound; |
| 5983 | + *out = 1; |
| 5984 | + return true; |
| 5985 | +} |
| 5986 | + |
| 5987 | +static void _test_deterministic_contention(_mongocrypt_tester_t *tester) { |
| 5988 | + mongocrypt_status_t *const status = mongocrypt_status_new(); |
| 5989 | + |
| 5990 | + mongocrypt_t *const crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_SKIP_INIT); |
| 5991 | + ASSERT_OK(mongocrypt_init(crypt), crypt); |
| 5992 | + _mongocrypt_opts_set_contention_factor_fn(crypt, &_deterministic_contention); // register deterministic fn wth crypt |
| 5993 | + |
| 5994 | + // Expect the callback returns 1. |
| 5995 | + { |
| 5996 | + int64_t out; |
| 5997 | + ASSERT(crypt->opts.contention_factor_fn(4, &out)); |
| 5998 | + ASSERT_CMPINT64(out, ==, 1); |
| 5999 | + } |
| 6000 | + |
| 6001 | + // Start explicit encryption: |
| 6002 | + mongocrypt_ctx_t *const ctx = mongocrypt_ctx_new(crypt); |
| 6003 | + |
| 6004 | + // Use the QE algorithm "Indexed", which uses a contention factor: |
| 6005 | + ASSERT_OK(mongocrypt_ctx_setopt_algorithm(ctx, MONGOCRYPT_ALGORITHM_INDEXED_STR, -1), ctx); |
| 6006 | + |
| 6007 | + { |
| 6008 | + _mongocrypt_buffer_t keyABC_id; |
| 6009 | + _mongocrypt_buffer_copy_from_hex(&keyABC_id, "ABCDEFAB123498761234123456789012"); |
| 6010 | + ASSERT_OK(mongocrypt_ctx_setopt_key_id(ctx, _mongocrypt_buffer_as_binary(&keyABC_id)), ctx); |
| 6011 | + _mongocrypt_buffer_cleanup(&keyABC_id); |
| 6012 | + } |
| 6013 | + |
| 6014 | + // Set max contention factor of 4: |
| 6015 | + ASSERT_OK(mongocrypt_ctx_setopt_contention_factor(ctx, 4), ctx); |
| 6016 | + |
| 6017 | + // Encrypt the value 123: |
| 6018 | + ASSERT_OK(mongocrypt_ctx_explicit_encrypt_init(ctx, TEST_BSON("{'v': 123}")), ctx); |
| 6019 | + |
| 6020 | + // Expect key is needed: |
| 6021 | + ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_KEYS); |
| 6022 | + { |
| 6023 | + mongocrypt_binary_t *const keyABC = |
| 6024 | + TEST_FILE("./test/data/keys/ABCDEFAB123498761234123456789012-local-document.json"); |
| 6025 | + ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, keyABC), ctx); |
| 6026 | + ASSERT_OK(mongocrypt_ctx_mongo_done(ctx), ctx); |
| 6027 | + } |
| 6028 | + |
| 6029 | + // Expect ready to encrypt: |
| 6030 | + ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_READY); |
| 6031 | + { |
| 6032 | + mongocrypt_binary_t *got = mongocrypt_binary_new(); |
| 6033 | + bool ret = mongocrypt_ctx_finalize(ctx, got); |
| 6034 | + ASSERT_OK(ret, ctx); |
| 6035 | + |
| 6036 | + // The result is represented in a BSON document: { "v": <binary> }. |
| 6037 | + // Do the long-winded conversion: binary -> BSON -> buffer: |
| 6038 | + _mongocrypt_buffer_t got_buffer; |
| 6039 | + { |
| 6040 | + bson_t got_bson; |
| 6041 | + ASSERT(_mongocrypt_binary_to_bson(got, &got_bson)); |
| 6042 | + bson_iter_t got_iter; |
| 6043 | + ASSERT(bson_iter_init_find(&got_iter, &got_bson, "v")); |
| 6044 | + ASSERT(_mongocrypt_buffer_from_binary_iter(&got_buffer, &got_iter)); |
| 6045 | + } |
| 6046 | + |
| 6047 | + // Check the contention factor in the resulting payload: |
| 6048 | + mc_FLE2InsertUpdatePayloadV2_t got_payload; |
| 6049 | + mc_FLE2InsertUpdatePayloadV2_init(&got_payload); |
| 6050 | + ASSERT_OK_STATUS(mc_FLE2InsertUpdatePayloadV2_parse(&got_payload, &got_buffer, status), status); |
| 6051 | + ASSERT_CMPINT64(got_payload.contentionFactor, ==, 1); // Set by _deterministic_contention. |
| 6052 | + mc_FLE2InsertUpdatePayloadV2_cleanup(&got_payload); |
| 6053 | + mongocrypt_binary_destroy(got); |
| 6054 | + } |
| 6055 | + |
| 6056 | + mongocrypt_ctx_destroy(ctx); |
| 6057 | + mongocrypt_destroy(crypt); |
| 6058 | + mongocrypt_status_destroy(status); |
| 6059 | +} |
| 6060 | + |
5979 | 6061 | void _mongocrypt_tester_install_ctx_encrypt(_mongocrypt_tester_t *tester) { |
5980 | 6062 | INSTALL_TEST(_test_explicit_encrypt_init); |
5981 | 6063 | INSTALL_TEST(_test_encrypt_init); |
@@ -6074,4 +6156,5 @@ void _mongocrypt_tester_install_ctx_encrypt(_mongocrypt_tester_t *tester) { |
6074 | 6156 | INSTALL_TEST(_test_fle2_encrypted_fields_with_unmatching_str_encode_version); |
6075 | 6157 | INSTALL_TEST(_test_fle2_collinfo_with_bad_str_encode_version); |
6076 | 6158 | INSTALL_TEST(_test_lookup); |
| 6159 | + INSTALL_TEST(_test_deterministic_contention); |
6077 | 6160 | } |
0 commit comments