Skip to content

Commit c7a0498

Browse files
authored
CDRIVER-4445 Add CSE Prose Test 16 (#1085)
1 parent 8ef35c4 commit c7a0498

File tree

1 file changed

+266
-4
lines changed

1 file changed

+266
-4
lines changed

src/libmongoc/tests/test-mongoc-client-side-encryption.c

Lines changed: 266 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,46 @@ _make_tls_opts (void)
295295
return tls_opts;
296296
}
297297

298+
static bson_t *
299+
_make_kms_masterkey (char const *provider)
300+
{
301+
if (strcmp (provider, "aws") == 0) {
302+
return BCON_NEW ("region",
303+
"us-east-1",
304+
"key",
305+
"arn:aws:kms:us-east-1:579766882180:key/"
306+
"89fcc2c4-08b0-4bd9-9f25-e30687b580d0");
307+
}
308+
309+
if (strcmp (provider, "azure") == 0) {
310+
return BCON_NEW ("keyVaultEndpoint",
311+
"key-vault-csfle.vault.azure.net",
312+
"keyName",
313+
"key-name-csfle");
314+
}
315+
316+
if (strcmp (provider, "gcp") == 0) {
317+
return BCON_NEW ("projectId",
318+
"devprod-drivers",
319+
"location",
320+
"global",
321+
"keyRing",
322+
"key-ring-csfle",
323+
"keyName",
324+
"key-name-csfle");
325+
}
326+
327+
if (strcmp (provider, "kmip") == 0) {
328+
return bson_new ();
329+
}
330+
331+
if (strcmp (provider, "local") == 0) {
332+
return bson_new ();
333+
}
334+
335+
return NULL;
336+
}
337+
298338
typedef struct {
299339
int num_inserts;
300340
} limits_apm_ctx_t;
@@ -4638,6 +4678,218 @@ test_decryption_events_case4 (void *unused)
46384678
decryption_events_fixture_destroy (def);
46394679
}
46404680

4681+
static void
4682+
_test_rewrap_with_separate_client_encryption (const char *src_provider,
4683+
const char *dst_provider)
4684+
{
4685+
mongoc_uri_t *const uri = test_framework_get_uri ();
4686+
mongoc_client_encryption_opts_t *const ce_opts =
4687+
mongoc_client_encryption_opts_new ();
4688+
mongoc_client_t *const src_client =
4689+
test_framework_client_new_from_uri (uri, NULL);
4690+
mongoc_client_t *const dst_client =
4691+
test_framework_client_new_from_uri (uri, NULL);
4692+
4693+
bson_error_t error = {0};
4694+
bson_value_t keyid = {0};
4695+
4696+
BSON_ASSERT (uri);
4697+
BSON_ASSERT (ce_opts);
4698+
BSON_ASSERT (src_client);
4699+
BSON_ASSERT (dst_client);
4700+
4701+
test_framework_set_ssl_opts (src_client);
4702+
test_framework_set_ssl_opts (dst_client);
4703+
4704+
{
4705+
mongoc_client_encryption_opts_set_keyvault_client (ce_opts, src_client);
4706+
mongoc_client_encryption_opts_set_keyvault_namespace (
4707+
ce_opts, "keyvault", "datakeys");
4708+
4709+
{
4710+
bson_t *const kms_providers = _make_kms_providers (true, true);
4711+
BSON_ASSERT (kms_providers);
4712+
mongoc_client_encryption_opts_set_kms_providers (ce_opts,
4713+
kms_providers);
4714+
bson_destroy (kms_providers);
4715+
}
4716+
4717+
{
4718+
bson_t *const tls_opts = _make_tls_opts ();
4719+
BSON_ASSERT (tls_opts);
4720+
mongoc_client_encryption_opts_set_tls_opts (ce_opts, tls_opts);
4721+
bson_destroy (tls_opts);
4722+
}
4723+
}
4724+
4725+
4726+
// 1. Drop the collection keyvault.datakeys.
4727+
{
4728+
mongoc_collection_t *datakeys =
4729+
mongoc_client_get_collection (src_client, "keyvault", "datakeys");
4730+
ASSERT (datakeys);
4731+
(void) mongoc_collection_drop (datakeys, NULL);
4732+
mongoc_collection_destroy (datakeys);
4733+
}
4734+
4735+
// 2. Create a ClientEncryption object named clientEncryption1 with these
4736+
// options: (see ce_opts).
4737+
mongoc_client_encryption_t *clientEncryption1 =
4738+
mongoc_client_encryption_new (ce_opts, &error);
4739+
ASSERT_OR_PRINT (clientEncryption1, error);
4740+
4741+
// 3. Call clientEncryption1.createDataKey with srcProvider and these
4742+
// options: (see below).
4743+
{
4744+
mongoc_client_encryption_datakey_opts_t *dk_opts =
4745+
mongoc_client_encryption_datakey_opts_new ();
4746+
4747+
{
4748+
bson_t *const src_masterkey = _make_kms_masterkey (src_provider);
4749+
BSON_ASSERT (src_masterkey);
4750+
mongoc_client_encryption_datakey_opts_set_masterkey (dk_opts,
4751+
src_masterkey);
4752+
bson_destroy (src_masterkey);
4753+
}
4754+
4755+
ASSERT_OR_PRINT (
4756+
mongoc_client_encryption_create_datakey (
4757+
clientEncryption1, src_provider, dk_opts, &keyid, &error),
4758+
error);
4759+
4760+
mongoc_client_encryption_datakey_opts_destroy (dk_opts);
4761+
}
4762+
4763+
bson_value_t ciphertext = {0};
4764+
4765+
// 4. Call clientEncryption1.encrypt with the value "test" and these options:
4766+
// (see below).
4767+
{
4768+
char message[] = "test";
4769+
4770+
bson_value_t bson_value;
4771+
4772+
bson_value.value_type = BSON_TYPE_UTF8;
4773+
bson_value.value.v_utf8.str = message;
4774+
bson_value.value.v_utf8.len =
4775+
(uint32_t) strlen (bson_value.value.v_utf8.str);
4776+
4777+
mongoc_client_encryption_encrypt_opts_t *const e_opts =
4778+
mongoc_client_encryption_encrypt_opts_new ();
4779+
mongoc_client_encryption_encrypt_opts_set_keyid (e_opts, &keyid);
4780+
mongoc_client_encryption_encrypt_opts_set_algorithm (
4781+
e_opts, MONGOC_AEAD_AES_256_CBC_HMAC_SHA_512_DETERMINISTIC);
4782+
ASSERT_OR_PRINT (
4783+
mongoc_client_encryption_encrypt (
4784+
clientEncryption1, &bson_value, e_opts, &ciphertext, &error),
4785+
error);
4786+
mongoc_client_encryption_encrypt_opts_destroy (e_opts);
4787+
}
4788+
4789+
// 5. Create a ClientEncryption object named clientEncryption2 with these
4790+
// options: (see ce_opts).
4791+
mongoc_client_encryption_t *clientEncryption2 =
4792+
mongoc_client_encryption_new (ce_opts, &error);
4793+
ASSERT_OR_PRINT (clientEncryption2, error);
4794+
4795+
mongoc_client_encryption_rewrap_many_datakey_result_t *const result =
4796+
mongoc_client_encryption_rewrap_many_datakey_result_new ();
4797+
BSON_ASSERT (result);
4798+
4799+
// 6. Call clientEncryption2.rewrapManyDataKey with an empty filter and these
4800+
// options: (see below).
4801+
{
4802+
{
4803+
bson_t *const dst_masterkey = _make_kms_masterkey (dst_provider);
4804+
BSON_ASSERT (dst_masterkey);
4805+
ASSERT_OR_PRINT (
4806+
mongoc_client_encryption_rewrap_many_datakey (clientEncryption2,
4807+
NULL,
4808+
dst_provider,
4809+
dst_masterkey,
4810+
result,
4811+
&error),
4812+
error);
4813+
bson_destroy (dst_masterkey);
4814+
}
4815+
4816+
// Assert that the returned
4817+
// RewrapManyDataKeyResult.bulkWriteResult.modifiedCount is 1.
4818+
const bson_t *const bulk_write_result =
4819+
mongoc_client_encryption_rewrap_many_datakey_result_get_bulk_write_result (
4820+
result);
4821+
ASSERT (bulk_write_result);
4822+
ASSERT_WITH_MSG (
4823+
match_bson (bulk_write_result, tmp_bson ("{'nModified': 1}"), false),
4824+
"'%s' does not match expected value",
4825+
tmp_json (bulk_write_result));
4826+
}
4827+
4828+
// 7. Call clientEncryption1.decrypt with the ciphertext. Assert the return
4829+
// value is "test".
4830+
{
4831+
bson_value_t decrypted = {0};
4832+
4833+
ASSERT (mongoc_client_encryption_decrypt (
4834+
clientEncryption1, &ciphertext, &decrypted, &error));
4835+
4836+
ASSERT (decrypted.value_type == BSON_TYPE_UTF8);
4837+
ASSERT (decrypted.value.v_utf8.len != 0u);
4838+
ASSERT_CMPSTR (decrypted.value.v_utf8.str, "test");
4839+
4840+
bson_value_destroy (&decrypted);
4841+
}
4842+
4843+
// 8. Call clientEncryption2.decrypt with the ciphertext. Assert the return
4844+
// value is "test".
4845+
{
4846+
bson_value_t decrypted = {0};
4847+
4848+
ASSERT (mongoc_client_encryption_decrypt (
4849+
clientEncryption2, &ciphertext, &decrypted, &error));
4850+
4851+
ASSERT (decrypted.value_type == BSON_TYPE_UTF8);
4852+
ASSERT (decrypted.value.v_utf8.len != 0u);
4853+
ASSERT_CMPSTR (decrypted.value.v_utf8.str, "test");
4854+
4855+
bson_value_destroy (&decrypted);
4856+
}
4857+
4858+
mongoc_client_encryption_rewrap_many_datakey_result_destroy (result);
4859+
mongoc_client_encryption_destroy (clientEncryption2);
4860+
bson_value_destroy (&ciphertext);
4861+
bson_value_destroy (&keyid);
4862+
mongoc_client_encryption_destroy (clientEncryption1);
4863+
mongoc_client_encryption_opts_destroy (ce_opts);
4864+
mongoc_uri_destroy (uri);
4865+
mongoc_client_destroy (dst_client);
4866+
mongoc_client_destroy (src_client);
4867+
}
4868+
4869+
/* Prose Test 16: Rewrap with separate ClientEncryption */
4870+
static void
4871+
test_rewrap_with_separate_client_encryption (void *unused)
4872+
{
4873+
BSON_UNUSED (unused);
4874+
4875+
const char *const providers[] = {"aws", "azure", "gcp", "kmip", "local"};
4876+
const size_t providers_len = sizeof (providers) / sizeof (*providers);
4877+
4878+
for (size_t src_idx = 0u; src_idx < providers_len; ++src_idx) {
4879+
for (size_t dst_idx = 0u; dst_idx < providers_len; ++dst_idx) {
4880+
const char *const src = providers[src_idx];
4881+
const char *const dst = providers[dst_idx];
4882+
4883+
if (test_suite_debug_output ()) {
4884+
printf (" - %s -> %s\n", src, dst);
4885+
fflush (stdout);
4886+
}
4887+
4888+
_test_rewrap_with_separate_client_encryption (src, dst);
4889+
}
4890+
}
4891+
}
4892+
46414893
/* test_qe_docs_example tests the documentation example requested in
46424894
* CDRIVER-4379. */
46434895
static void
@@ -5014,10 +5266,8 @@ _test_auto_aws (bool should_succeed)
50145266
} else {
50155267
// We should encounter an error while attempting to connect to the EC2
50165268
// metadata server.
5017-
ASSERT_ERROR_CONTAINS (error,
5018-
MONGOC_ERROR_CLIENT,
5019-
MONGOC_ERROR_CLIENT_AUTHENTICATE,
5020-
"");
5269+
ASSERT_ERROR_CONTAINS (
5270+
error, MONGOC_ERROR_CLIENT, MONGOC_ERROR_CLIENT_AUTHENTICATE, "");
50215271
}
50225272
}
50235273

@@ -5029,18 +5279,22 @@ _test_auto_aws (bool should_succeed)
50295279
static void
50305280
test_auto_aws_fail (void *unused)
50315281
{
5282+
BSON_UNUSED (unused);
50325283
_test_auto_aws (false);
50335284
}
50345285

50355286
static void
50365287
test_auto_aws_succeed (void *unused)
50375288
{
5289+
BSON_UNUSED (unused);
50385290
_test_auto_aws (true);
50395291
}
50405292

50415293
static int
50425294
_have_aws_creds_env (void *unused)
50435295
{
5296+
BSON_UNUSED (unused);
5297+
50445298
// State variable:
50455299
// Zero: Haven't checked yet
50465300
// One: We have AWS creds
@@ -5187,6 +5441,14 @@ test_client_side_encryption_install (TestSuite *suite)
51875441
NULL,
51885442
test_framework_skip_if_no_client_side_encryption,
51895443
test_framework_skip_if_max_wire_version_less_than_8);
5444+
TestSuite_AddFull (suite,
5445+
"/client_side_encryption/prose_test_16",
5446+
test_rewrap_with_separate_client_encryption,
5447+
NULL,
5448+
NULL,
5449+
test_framework_skip_if_no_client_side_encryption,
5450+
test_framework_skip_if_max_wire_version_less_than_8,
5451+
test_framework_skip_if_slow);
51905452

51915453
/* Other, C driver specific, tests. */
51925454
TestSuite_AddFull (suite,

0 commit comments

Comments
 (0)