diff --git a/src/mongocrypt-opts.c b/src/mongocrypt-opts.c index c5b7b5833..7b9da7415 100644 --- a/src/mongocrypt-opts.c +++ b/src/mongocrypt-opts.c @@ -984,6 +984,10 @@ bool _mongocrypt_parse_kms_providers(mongocrypt_binary_t *kms_providers_definiti } else if (0 == strcmp(field_name, "kmip") && bson_empty(&field_bson)) { kms_providers->need_credentials |= MONGOCRYPT_KMS_PROVIDER_KMIP; } else if (0 == strcmp(field_name, "kmip")) { + if (0 != (kms_providers->configured_providers & MONGOCRYPT_KMS_PROVIDER_KMIP)) { + CLIENT_ERR("kmip KMS provider already set"); + return false; + } if (!_mongocrypt_opts_kms_provider_kmip_parse(&kms_providers->kmip_mut, field_name, &field_bson, status)) { return false; } diff --git a/test/test-mongocrypt.c b/test/test-mongocrypt.c index 4aaf6881c..3e09bd45e 100644 --- a/test/test-mongocrypt.c +++ b/test/test-mongocrypt.c @@ -906,6 +906,16 @@ static void _test_setopt_kms_providers(_mongocrypt_tester_t *tester) { ASSERT_FAILS(mongocrypt_setopt_kms_providers(crypt, more), crypt, "already set"); mongocrypt_destroy(crypt); } + + // Errors if followed by call to `mongocrypt_setopt_kms_providers` configuring "kmip". + // This is a regression test for: MONGOCRYPT-956 + { + mongocrypt_binary_t *kms_providers = TEST_BSON("{'kmip' : {'endpoint' : 'localhost'}}"); + mongocrypt_t *crypt = mongocrypt_new(); + ASSERT_OK(mongocrypt_setopt_kms_providers(crypt, kms_providers), crypt); + ASSERT_FAILS(mongocrypt_setopt_kms_providers(crypt, kms_providers), crypt, "already set"); + mongocrypt_destroy(crypt); + } } static void test_tmp_bsonf(_mongocrypt_tester_t *tester) {