@@ -295,6 +295,46 @@ _make_tls_opts (void)
295
295
return tls_opts ;
296
296
}
297
297
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
+
298
338
typedef struct {
299
339
int num_inserts ;
300
340
} limits_apm_ctx_t ;
@@ -4638,6 +4678,218 @@ test_decryption_events_case4 (void *unused)
4638
4678
decryption_events_fixture_destroy (def );
4639
4679
}
4640
4680
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
+
4641
4893
/* test_qe_docs_example tests the documentation example requested in
4642
4894
* CDRIVER-4379. */
4643
4895
static void
@@ -5014,10 +5266,8 @@ _test_auto_aws (bool should_succeed)
5014
5266
} else {
5015
5267
// We should encounter an error while attempting to connect to the EC2
5016
5268
// 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 , "" );
5021
5271
}
5022
5272
}
5023
5273
@@ -5029,18 +5279,22 @@ _test_auto_aws (bool should_succeed)
5029
5279
static void
5030
5280
test_auto_aws_fail (void * unused )
5031
5281
{
5282
+ BSON_UNUSED (unused );
5032
5283
_test_auto_aws (false);
5033
5284
}
5034
5285
5035
5286
static void
5036
5287
test_auto_aws_succeed (void * unused )
5037
5288
{
5289
+ BSON_UNUSED (unused );
5038
5290
_test_auto_aws (true);
5039
5291
}
5040
5292
5041
5293
static int
5042
5294
_have_aws_creds_env (void * unused )
5043
5295
{
5296
+ BSON_UNUSED (unused );
5297
+
5044
5298
// State variable:
5045
5299
// Zero: Haven't checked yet
5046
5300
// One: We have AWS creds
@@ -5187,6 +5441,14 @@ test_client_side_encryption_install (TestSuite *suite)
5187
5441
NULL ,
5188
5442
test_framework_skip_if_no_client_side_encryption ,
5189
5443
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 );
5190
5452
5191
5453
/* Other, C driver specific, tests. */
5192
5454
TestSuite_AddFull (suite ,
0 commit comments