libmongocrypt-helper 1.19.0.0.1001 → 1.20.1.0.1001

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. checksums.yaml +4 -4
  2. data/ext/libmongocrypt/libmongocrypt/CHANGELOG.md +28 -0
  3. data/ext/libmongocrypt/libmongocrypt/README.md +3 -0
  4. data/ext/libmongocrypt/libmongocrypt/cmake/FetchMongoC.cmake +1 -1
  5. data/ext/libmongocrypt/libmongocrypt/etc/cyclonedx.sbom.json +8 -8
  6. data/ext/libmongocrypt/libmongocrypt/etc/purls.txt +1 -1
  7. data/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_kmip_response_parser.c +4 -0
  8. data/ext/libmongocrypt/libmongocrypt/src/mc-efc-private.h +5 -3
  9. data/ext/libmongocrypt/libmongocrypt/src/mc-efc.c +6 -17
  10. data/ext/libmongocrypt/libmongocrypt/src/mc-textopts.c +6 -3
  11. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ctx-encrypt.c +18 -10
  12. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ctx-private.h +6 -1
  13. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ctx.c +20 -7
  14. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-opts.c +4 -0
  15. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt.h +3 -3
  16. data/ext/libmongocrypt/libmongocrypt/test/data/efc/efc-textSearchFields.json +18 -2
  17. data/ext/libmongocrypt/libmongocrypt/test/test-mc-efc.c +10 -2
  18. data/ext/libmongocrypt/libmongocrypt/test/test-mc-textopts.c +1 -1
  19. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-ctx-encrypt.c +39 -26
  20. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-ctx-setopt.c +14 -9
  21. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-kms-ctx.c +96 -0
  22. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt.c +10 -0
  23. data/lib/libmongocrypt_helper/version.rb +2 -2
  24. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b049e3785ef7124bc0172a97aca5a01ac2c883998bf066bd399b23aaa6f7ab29
4
- data.tar.gz: b993577d300b0aafe7bd074774829edbe4a54425a1bbe631cdfa6424d73abba7
3
+ metadata.gz: 5f3bd46869436cf55ec31236a73965ec1f198f75809d53e084aebb6c056bead0
4
+ data.tar.gz: 4868779b572f103a7f7f6ae88ea15032dd829e31c5a85e1f41364bd0d7f17d60
5
5
  SHA512:
6
- metadata.gz: 7effe0b13cb6bdea52e7ae92e8ae7fb3ca8230936d95e128d5e11ee35964ec848e46691fd8342e594918915f268ff3b6fa9a924f65d3015c1c25b17e22fc6e6b
7
- data.tar.gz: 4ee52e78b00238026409e733f629ab1067179909d20605c981cd7ce4229ed976ece08fd7f8b4db68645d33cbb571c3a04054e604d9ffbe7e7c5752a8bd98b23b
6
+ metadata.gz: 57f84ed485336784bd0dd5008a4d2f893146f3cb4128c121d5e91dc5bb8c80c07f8d7a6e44edd869327876c1b0410b1790b84a0548bb0459b6e7bc53a7151a83
7
+ data.tar.gz: 27917b4a2c97d98db62661d48f0c3dace264f84f83ba9fd1f9de351dc11a20bb0f29445c51ffa94b82b51716adb1bf925bf18804358d5bac1b701651bc735846
@@ -1,5 +1,26 @@
1
1
  # ChangeLog
2
2
 
3
+ ## 1.20.1
4
+
5
+ ## Changed
6
+ - Bump downloaded libbson version from 2.3.0 to 2.3.3 to address configuration error with CMake 4.4.0.
7
+
8
+ ## 1.20.0
9
+
10
+ ### Added
11
+ - Stable support for substring queries.
12
+
13
+ ## 1.19.2
14
+
15
+ ### Added
16
+ - Add static library files to GitHub releases.
17
+
18
+ ## 1.19.1
19
+
20
+ ### Added
21
+ - Restore support for the experimental `prefixPreview` and `suffixPreview` query types.
22
+
23
+
3
24
  ## 1.19.0
4
25
 
5
26
  ### Added
@@ -11,6 +32,13 @@
11
32
  ### Removed
12
33
  - Support for the experimental `prefixPreview` and `suffixPreview` query types.
13
34
 
35
+
36
+ ## 1.18.2
37
+
38
+ ### Fixed
39
+ - Add musl arm64 release to GitHub release. This was an omission in 1.18.0.
40
+ - Reject large KMS replies.
41
+
14
42
  ## 1.18.1
15
43
 
16
44
  ### Fixed
@@ -78,6 +78,9 @@ A Windows DLL for x86_64 is available on the Github Releases page. See the [late
78
78
 
79
79
  Use `gpg` to verify the signature. The public key for `libmongocrypt` is available on https://pgp.mongodb.com/.
80
80
 
81
+ ## Python Releases ##
82
+ Python releases and tags are signed using the MongoDB Python driver PGP key. Use `gpg` to verify the signature. The public key is available at https://pgp.mongodb.com/python-driver.pub.
83
+
81
84
 
82
85
  ### Testing ###
83
86
  `test-mongocrypt` mocks all I/O with files stored in the `test/data` and `test/example` directories. Run `test-mongocrypt` from the source directory:
@@ -2,7 +2,7 @@ include (FetchContent)
2
2
 
3
3
  # Set the tag that we will fetch.
4
4
  # When updating the version of libbson, also update the version in etc/purls.txt and .evergreen/prep_c_driver_source.sh
5
- set (MONGOC_FETCH_TAG_FOR_LIBBSON "2.3.0" CACHE STRING "The Git tag of mongo-c-driver that will be fetched to obtain libbson")
5
+ set (MONGOC_FETCH_TAG_FOR_LIBBSON "2.3.3" CACHE STRING "The Git tag of mongo-c-driver that will be fetched to obtain libbson")
6
6
 
7
7
  # Add an option to disable patching if a patch command is unavailable.
8
8
  option (LIBBSON_PATCH_ENABLED "Whether to apply patches to the libbson library" ON)
@@ -1,16 +1,16 @@
1
1
  {
2
2
  "components": [
3
3
  {
4
- "bom-ref": "pkg:github/mongodb/mongo-c-driver@v2.3.0#src/libbson",
4
+ "bom-ref": "pkg:github/mongodb/mongo-c-driver@2.3.3#src/libbson",
5
5
  "copyright": "Copyright 2009-present MongoDB, Inc.",
6
6
  "externalReferences": [
7
7
  {
8
8
  "type": "distribution",
9
- "url": "https://github.com/mongodb/mongo-c-driver/archive/v2.3.0.tar.gz"
9
+ "url": "https://github.com/mongodb/mongo-c-driver/archive/2.3.3.tar.gz"
10
10
  },
11
11
  {
12
12
  "type": "website",
13
- "url": "https://github.com/mongodb/mongo-c-driver/tree/v2.3.0"
13
+ "url": "https://github.com/mongodb/mongo-c-driver/tree/2.3.3"
14
14
  }
15
15
  ],
16
16
  "group": "mongodb",
@@ -22,9 +22,9 @@
22
22
  }
23
23
  ],
24
24
  "name": "mongo-c-driver",
25
- "purl": "pkg:github/mongodb/mongo-c-driver@v2.3.0#src/libbson",
25
+ "purl": "pkg:github/mongodb/mongo-c-driver@2.3.3#src/libbson",
26
26
  "type": "library",
27
- "version": "v2.3.0"
27
+ "version": "2.3.3"
28
28
  },
29
29
  {
30
30
  "bom-ref": "pkg:generic/IntelRDFPMathLib@20U2?download_url=https://www.netlib.org/misc/intel/IntelRDFPMathLib20U2.tar.gz",
@@ -53,11 +53,11 @@
53
53
  "ref": "pkg:generic/IntelRDFPMathLib@20U2?download_url=https://www.netlib.org/misc/intel/IntelRDFPMathLib20U2.tar.gz"
54
54
  },
55
55
  {
56
- "ref": "pkg:github/mongodb/mongo-c-driver@v2.3.0#src/libbson"
56
+ "ref": "pkg:github/mongodb/mongo-c-driver@2.3.3#src/libbson"
57
57
  }
58
58
  ],
59
59
  "metadata": {
60
- "timestamp": "2026-05-01T14:49:06.464175+00:00",
60
+ "timestamp": "2026-07-14T13:56:19.068748+00:00",
61
61
  "tools": [
62
62
  {
63
63
  "externalReferences": [
@@ -100,7 +100,7 @@
100
100
  }
101
101
  ]
102
102
  },
103
- "serialNumber": "urn:uuid:5c89265b-cc3d-4649-878b-17b482325b56",
103
+ "serialNumber": "urn:uuid:870a42e2-38df-4271-afee-8ffa5c28bcf7",
104
104
  "version": 1,
105
105
  "$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json",
106
106
  "bomFormat": "CycloneDX",
@@ -8,7 +8,7 @@
8
8
  # `copyright` property. This information can be manually added.
9
9
 
10
10
  # libbson is obtained via `cmake/FetchMongoC.cmake`.
11
- pkg:github/mongodb/mongo-c-driver@v2.3.0?#src/libbson
11
+ pkg:github/mongodb/mongo-c-driver@2.3.3?#src/libbson
12
12
 
13
13
  # IntelDFP is obtained via `cmake/IntelDFP.cmake`
14
14
  pkg:generic/IntelRDFPMathLib@20U2?download_url=https://www.netlib.org/misc/intel/IntelRDFPMathLib20U2.tar.gz
@@ -111,6 +111,10 @@ kms_kmip_response_parser_feed (kms_kmip_response_parser_t *parser,
111
111
  uint32_t temp;
112
112
  memcpy (&temp, parser->buf->str + FIRST_LENGTH_OFFSET, sizeof (uint32_t));
113
113
  parser->first_len = KMS_UINT32_FROM_BE (temp);
114
+ if (parser->first_len > KMS_PARSER_MAX_RESPONSE_LEN) {
115
+ KMS_ERROR (parser, "KMS KMIP response too large");
116
+ return false;
117
+ }
114
118
  }
115
119
  return true;
116
120
  }
@@ -28,13 +28,15 @@ typedef enum _supported_query_type_flags {
28
28
  SUPPORTS_RANGE_QUERIES = 1 << 1,
29
29
  // Range preview query supported
30
30
  SUPPORTS_RANGE_PREVIEW_DEPRECATED_QUERIES = 1 << 2,
31
- // Text search preview query supported
32
- SUPPORTS_SUBSTRING_PREVIEW_QUERIES = 1 << 3,
31
+ // Text search query supported
32
+ SUPPORTS_SUBSTRING_QUERIES = 1 << 3,
33
33
  SUPPORTS_SUFFIX_QUERIES = 1 << 4,
34
34
  SUPPORTS_PREFIX_QUERIES = 1 << 5,
35
- // prefixPreview and suffixPreview are dropped. Setting this results in an error.
35
+ // suffixPreview and prefixPreview are deprecated aliases for suffix and prefix, respectively.
36
36
  SUPPORTS_SUFFIX_PREVIEW_DEPRECATED_QUERIES = 1 << 6,
37
37
  SUPPORTS_PREFIX_PREVIEW_DEPRECATED_QUERIES = 1 << 7,
38
+ // substring preview query supported
39
+ SUPPORTS_SUBSTRING_PREVIEW_DEPRECATED_QUERIES = 1 << 8,
38
40
  } supported_query_type_flags;
39
41
 
40
42
  typedef struct _mc_EncryptedField_t {
@@ -33,8 +33,9 @@ static bool _parse_query_type_string(const char *queryType, supported_query_type
33
33
  *out = SUPPORTS_RANGE_QUERIES;
34
34
  } else if (mstr_eq_ignore_case(mstrv_lit(MONGOCRYPT_QUERY_TYPE_RANGEPREVIEW_DEPRECATED_STR), qtv)) {
35
35
  *out = SUPPORTS_RANGE_PREVIEW_DEPRECATED_QUERIES;
36
- } else if (mstr_eq_ignore_case(mstrv_lit(MONGOCRYPT_QUERY_TYPE_SUBSTRINGPREVIEW_STR), qtv)) {
37
- *out = SUPPORTS_SUBSTRING_PREVIEW_QUERIES;
36
+ } else if (mstr_eq_ignore_case(mstrv_lit(MONGOCRYPT_QUERY_TYPE_SUBSTRINGPREVIEW_DEPRECATED_STR), qtv)
37
+ || mstr_eq_ignore_case(mstrv_lit(MONGOCRYPT_QUERY_TYPE_SUBSTRING_STR), qtv)) {
38
+ *out = SUPPORTS_SUBSTRING_QUERIES;
38
39
  } else if (mstr_eq_ignore_case(mstrv_lit(MONGOCRYPT_QUERY_TYPE_SUFFIX_STR), qtv)) {
39
40
  *out = SUPPORTS_SUFFIX_QUERIES;
40
41
  } else if (mstr_eq_ignore_case(mstrv_lit(MONGOCRYPT_QUERY_TYPE_PREFIX_STR), qtv)) {
@@ -178,20 +179,6 @@ static bool _parse_field(mc_EncryptedFieldConfig_t *efc, bson_t *field, mongocry
178
179
  return false;
179
180
  }
180
181
 
181
- if (query_types & SUPPORTS_PREFIX_PREVIEW_DEPRECATED_QUERIES) {
182
- CLIENT_ERR("Cannot use field '%s' with 'prefixPreview' queries. 'prefixPreview' is unsupported. Use 'prefix' "
183
- "instead.",
184
- field_path);
185
- return false;
186
- }
187
-
188
- if (query_types & SUPPORTS_SUFFIX_PREVIEW_DEPRECATED_QUERIES) {
189
- CLIENT_ERR("Cannot use field '%s' with 'suffixPreview' queries. 'suffixPreview' is unsupported. Use 'suffix' "
190
- "instead.",
191
- field_path);
192
- return false;
193
- }
194
-
195
182
  /* Prepend a new mc_EncryptedField_t */
196
183
  mc_EncryptedField_t *ef = bson_malloc0(sizeof(mc_EncryptedField_t));
197
184
  if (has_keyid) {
@@ -258,7 +245,9 @@ bool mc_EncryptedFieldConfig_parse(mc_EncryptedFieldConfig_t *efc,
258
245
 
259
246
  if (!bson_iter_init_find(&iter, efc_bson, "strEncodeVersion")) {
260
247
  if (all_supported_queries
261
- & (SUPPORTS_SUBSTRING_PREVIEW_QUERIES | SUPPORTS_SUFFIX_QUERIES | SUPPORTS_PREFIX_QUERIES)) {
248
+ & (SUPPORTS_SUBSTRING_QUERIES | SUPPORTS_SUBSTRING_PREVIEW_DEPRECATED_QUERIES | SUPPORTS_SUFFIX_QUERIES
249
+ | SUPPORTS_PREFIX_QUERIES | SUPPORTS_SUFFIX_PREVIEW_DEPRECATED_QUERIES
250
+ | SUPPORTS_PREFIX_PREVIEW_DEPRECATED_QUERIES)) {
262
251
  // Has at least one text search query type, set to latest by default.
263
252
  efc->str_encode_version = LATEST_STR_ENCODE_VERSION;
264
253
  } else {
@@ -368,15 +368,18 @@ bool mc_TextOpts_to_FLE2TextSearchInsertSpec_for_query(const mc_TextOpts_t *txo,
368
368
  CLIENT_ERR("Unexpected query type: %s\n", _mongocrypt_query_type_to_string(query_type));
369
369
  return false;
370
370
  }
371
- case MONGOCRYPT_QUERY_TYPE_PREFIX: {
371
+ case MONGOCRYPT_QUERY_TYPE_PREFIX:
372
+ case MONGOCRYPT_QUERY_TYPE_PREFIXPREVIEW_DEPRECATED: {
372
373
  include_prefix = true;
373
374
  break;
374
375
  }
375
- case MONGOCRYPT_QUERY_TYPE_SUFFIX: {
376
+ case MONGOCRYPT_QUERY_TYPE_SUFFIX:
377
+ case MONGOCRYPT_QUERY_TYPE_SUFFIXPREVIEW_DEPRECATED: {
376
378
  include_suffix = true;
377
379
  break;
378
380
  }
379
- case MONGOCRYPT_QUERY_TYPE_SUBSTRINGPREVIEW: {
381
+ case MONGOCRYPT_QUERY_TYPE_SUBSTRING:
382
+ case MONGOCRYPT_QUERY_TYPE_SUBSTRINGPREVIEW_DEPRECATED: {
380
383
  include_substring = true;
381
384
  break;
382
385
  }
@@ -890,8 +890,9 @@ static moe_result must_omit_encryptionInformation(const char *command_name,
890
890
  bool has_fields_requiring_ei = false;
891
891
  for (const mc_EncryptedField_t *ef = efc->fields; ef != NULL; ef = ef->next) {
892
892
  if (ef->supported_queries
893
- & (SUPPORTS_RANGE_QUERIES | SUPPORTS_SUBSTRING_PREVIEW_QUERIES | SUPPORTS_SUFFIX_QUERIES
894
- | SUPPORTS_PREFIX_QUERIES)) {
893
+ & (SUPPORTS_RANGE_QUERIES | SUPPORTS_SUBSTRING_QUERIES | SUPPORTS_SUFFIX_QUERIES
894
+ | SUPPORTS_PREFIX_QUERIES | SUPPORTS_SUBSTRING_PREVIEW_DEPRECATED_QUERIES
895
+ | SUPPORTS_SUFFIX_PREVIEW_DEPRECATED_QUERIES | SUPPORTS_PREFIX_PREVIEW_DEPRECATED_QUERIES)) {
895
896
  has_fields_requiring_ei = true;
896
897
  break;
897
898
  }
@@ -1011,8 +1012,9 @@ static bool _fle2_append_compactionTokens(mongocrypt_t *crypt,
1011
1012
  const _mongocrypt_buffer_t *ecoct_buf = mc_ECOCToken_get(ecoct);
1012
1013
 
1013
1014
  if (ptr->supported_queries
1014
- & (SUPPORTS_RANGE_QUERIES | SUPPORTS_SUBSTRING_PREVIEW_QUERIES | SUPPORTS_SUFFIX_QUERIES
1015
- | SUPPORTS_PREFIX_QUERIES)) {
1015
+ & (SUPPORTS_RANGE_QUERIES | SUPPORTS_SUBSTRING_QUERIES | SUPPORTS_SUFFIX_QUERIES | SUPPORTS_PREFIX_QUERIES
1016
+ | SUPPORTS_SUBSTRING_PREVIEW_DEPRECATED_QUERIES | SUPPORTS_SUFFIX_PREVIEW_DEPRECATED_QUERIES
1017
+ | SUPPORTS_PREFIX_PREVIEW_DEPRECATED_QUERIES)) {
1016
1018
  // Append the document {ecoc: <ECOCToken>, anchorPaddingToken: <AnchorPaddingTokenRoot>}
1017
1019
  esct = mc_ESCToken_new(crypto, cl1t, status);
1018
1020
  if (!esct) {
@@ -1522,7 +1524,10 @@ static bool _fle2_finalize_explicit(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *
1522
1524
  // fallthrough
1523
1525
  case MONGOCRYPT_QUERY_TYPE_SUFFIX:
1524
1526
  case MONGOCRYPT_QUERY_TYPE_PREFIX:
1525
- case MONGOCRYPT_QUERY_TYPE_SUBSTRINGPREVIEW:
1527
+ case MONGOCRYPT_QUERY_TYPE_SUBSTRING:
1528
+ case MONGOCRYPT_QUERY_TYPE_SUFFIXPREVIEW_DEPRECATED:
1529
+ case MONGOCRYPT_QUERY_TYPE_PREFIXPREVIEW_DEPRECATED:
1530
+ case MONGOCRYPT_QUERY_TYPE_SUBSTRINGPREVIEW_DEPRECATED:
1526
1531
  case MONGOCRYPT_QUERY_TYPE_RANGE:
1527
1532
  case MONGOCRYPT_QUERY_TYPE_EQUALITY: marking.u.fle2.type = MONGOCRYPT_FLE2_PLACEHOLDER_TYPE_FIND; break;
1528
1533
  default: _mongocrypt_ctx_fail_w_msg(ctx, "Invalid value for EncryptOpts.queryType"); goto fail;
@@ -2087,19 +2092,19 @@ static bool explicit_encrypt_init(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *ms
2087
2092
 
2088
2093
  if (ctx->opts.query_type.set) {
2089
2094
  const mongocrypt_query_type_t qt = ctx->opts.query_type.value;
2090
- if (qt == MONGOCRYPT_QUERY_TYPE_PREFIX) {
2095
+ if (qt == MONGOCRYPT_QUERY_TYPE_PREFIX || qt == MONGOCRYPT_QUERY_TYPE_PREFIXPREVIEW_DEPRECATED) {
2091
2096
  if (!(ctx->opts.index_type.set && ctx->opts.index_type.value == MONGOCRYPT_INDEX_TYPE_STRING)) {
2092
2097
  return _mongocrypt_ctx_fail_w_msg(ctx, "prefix query type requires string index type");
2093
2098
  }
2094
2099
  }
2095
- if (qt == MONGOCRYPT_QUERY_TYPE_SUFFIX) {
2100
+ if (qt == MONGOCRYPT_QUERY_TYPE_SUFFIX || qt == MONGOCRYPT_QUERY_TYPE_SUFFIXPREVIEW_DEPRECATED) {
2096
2101
  if (!(ctx->opts.index_type.set && ctx->opts.index_type.value == MONGOCRYPT_INDEX_TYPE_STRING)) {
2097
2102
  return _mongocrypt_ctx_fail_w_msg(ctx, "suffix query type requires string index type");
2098
2103
  }
2099
2104
  }
2100
- if (qt == MONGOCRYPT_QUERY_TYPE_SUBSTRINGPREVIEW) {
2105
+ if (qt == MONGOCRYPT_QUERY_TYPE_SUBSTRING || qt == MONGOCRYPT_QUERY_TYPE_SUBSTRINGPREVIEW_DEPRECATED) {
2101
2106
  if (!(ctx->opts.index_type.set && ctx->opts.index_type.value == MONGOCRYPT_INDEX_TYPE_STRING)) {
2102
- return _mongocrypt_ctx_fail_w_msg(ctx, "substringPreview query type requires string index type");
2107
+ return _mongocrypt_ctx_fail_w_msg(ctx, "substring query type requires string index type");
2103
2108
  }
2104
2109
  }
2105
2110
  }
@@ -2182,7 +2187,10 @@ static bool explicit_encrypt_init(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *ms
2182
2187
  // fallthrough
2183
2188
  case MONGOCRYPT_QUERY_TYPE_PREFIX:
2184
2189
  case MONGOCRYPT_QUERY_TYPE_SUFFIX:
2185
- case MONGOCRYPT_QUERY_TYPE_SUBSTRINGPREVIEW:
2190
+ case MONGOCRYPT_QUERY_TYPE_SUBSTRING:
2191
+ case MONGOCRYPT_QUERY_TYPE_PREFIXPREVIEW_DEPRECATED:
2192
+ case MONGOCRYPT_QUERY_TYPE_SUFFIXPREVIEW_DEPRECATED:
2193
+ case MONGOCRYPT_QUERY_TYPE_SUBSTRINGPREVIEW_DEPRECATED:
2186
2194
  matches = (ctx->opts.index_type.value == MONGOCRYPT_INDEX_TYPE_STRING);
2187
2195
  break;
2188
2196
  default:
@@ -46,7 +46,12 @@ typedef enum _mongocrypt_query_type_t {
46
46
  MONGOCRYPT_QUERY_TYPE_RANGEPREVIEW_DEPRECATED = 3,
47
47
  MONGOCRYPT_QUERY_TYPE_PREFIX = 4,
48
48
  MONGOCRYPT_QUERY_TYPE_SUFFIX = 5,
49
- MONGOCRYPT_QUERY_TYPE_SUBSTRINGPREVIEW = 6,
49
+ MONGOCRYPT_QUERY_TYPE_SUBSTRING = 6,
50
+ // prefixPreview and suffixPreview are deprecated aliases for prefix and suffix, respectively. They behave
51
+ // identically; the distinct values exist for consistency (cf. rangePreview) and to ease eventual removal.
52
+ MONGOCRYPT_QUERY_TYPE_PREFIXPREVIEW_DEPRECATED = 7,
53
+ MONGOCRYPT_QUERY_TYPE_SUFFIXPREVIEW_DEPRECATED = 8,
54
+ MONGOCRYPT_QUERY_TYPE_SUBSTRINGPREVIEW_DEPRECATED = 9,
50
55
  } mongocrypt_query_type_t;
51
56
 
52
57
  const char *_mongocrypt_query_type_to_string(mongocrypt_query_type_t val);
@@ -248,6 +248,9 @@ bool mongocrypt_ctx_setopt_algorithm(mongocrypt_ctx_t *ctx, const char *algorith
248
248
  } else if (mstr_eq_ignore_case(algo_str, mstrv_lit(MONGOCRYPT_ALGORITHM_STRING_STR))) {
249
249
  ctx->opts.index_type.value = MONGOCRYPT_INDEX_TYPE_STRING;
250
250
  ctx->opts.index_type.set = true;
251
+ } else if (mstr_eq_ignore_case(algo_str, mstrv_lit(MONGOCRYPT_ALGORITHM_TEXTPREVIEW_DEPRECATED_STR))) {
252
+ _mongocrypt_ctx_fail_w_msg(ctx, "Algorithm 'textPreview' is deprecated, please use 'string'");
253
+ return false;
251
254
  } else {
252
255
  char *error = bson_strdup_printf("unsupported algorithm string \"%.*s\"",
253
256
  algo_str.len <= (size_t)INT_MAX ? (int)algo_str.len : INT_MAX,
@@ -1027,14 +1030,21 @@ bool mongocrypt_ctx_setopt_query_type(mongocrypt_ctx_t *ctx, const char *query_t
1027
1030
  } else if (mstr_eq_ignore_case(qt_str, mstrv_lit(MONGOCRYPT_QUERY_TYPE_SUFFIX_STR))) {
1028
1031
  ctx->opts.query_type.value = MONGOCRYPT_QUERY_TYPE_SUFFIX;
1029
1032
  ctx->opts.query_type.set = true;
1033
+ } else if (mstr_eq_ignore_case(qt_str, mstrv_lit(MONGOCRYPT_QUERY_TYPE_SUBSTRING_STR))) {
1034
+ ctx->opts.query_type.value = MONGOCRYPT_QUERY_TYPE_SUBSTRING;
1035
+ ctx->opts.query_type.set = true;
1030
1036
  } else if (mstr_eq_ignore_case(qt_str, mstrv_lit(MONGOCRYPT_QUERY_TYPE_PREFIXPREVIEW_DEPRECATED_STR))) {
1031
- _mongocrypt_ctx_fail_w_msg(ctx, "Query type 'prefixPreview' is deprecated, please use 'prefix'");
1032
- return false;
1037
+ // 'prefixPreview' is a deprecated alias for 'prefix'.
1038
+ ctx->opts.query_type.value = MONGOCRYPT_QUERY_TYPE_PREFIXPREVIEW_DEPRECATED;
1039
+ ctx->opts.query_type.set = true;
1033
1040
  } else if (mstr_eq_ignore_case(qt_str, mstrv_lit(MONGOCRYPT_QUERY_TYPE_SUFFIXPREVIEW_DEPRECATED_STR))) {
1034
- _mongocrypt_ctx_fail_w_msg(ctx, "Query type 'suffixPreview' is deprecated, please use 'suffix'");
1035
- return false;
1036
- } else if (mstr_eq_ignore_case(qt_str, mstrv_lit(MONGOCRYPT_QUERY_TYPE_SUBSTRINGPREVIEW_STR))) {
1037
- ctx->opts.query_type.value = MONGOCRYPT_QUERY_TYPE_SUBSTRINGPREVIEW;
1041
+ // 'suffixPreview' is a deprecated alias for 'suffix'.
1042
+ ctx->opts.query_type.value = MONGOCRYPT_QUERY_TYPE_SUFFIXPREVIEW_DEPRECATED;
1043
+ ctx->opts.query_type.set = true;
1044
+ } else if (mstr_eq_ignore_case(qt_str, mstrv_lit(MONGOCRYPT_QUERY_TYPE_SUBSTRINGPREVIEW_DEPRECATED_STR))) {
1045
+ // TODO: MONGOCRYPT-938 disallow substringPreview
1046
+ // _mongocrypt_ctx_fail_w_msg(ctx, "Query type 'substringPreview' is deprecated, please use 'substring'");
1047
+ ctx->opts.query_type.value = MONGOCRYPT_QUERY_TYPE_SUBSTRINGPREVIEW_DEPRECATED;
1038
1048
  ctx->opts.query_type.set = true;
1039
1049
  } else {
1040
1050
  /* don't check if qt_str.len fits in int; we want the diagnostic output */
@@ -1066,7 +1076,10 @@ const char *_mongocrypt_query_type_to_string(mongocrypt_query_type_t val) {
1066
1076
  case MONGOCRYPT_QUERY_TYPE_RANGE: return "Range";
1067
1077
  case MONGOCRYPT_QUERY_TYPE_PREFIX: return "Prefix";
1068
1078
  case MONGOCRYPT_QUERY_TYPE_SUFFIX: return "Suffix";
1069
- case MONGOCRYPT_QUERY_TYPE_SUBSTRINGPREVIEW: return "SubstringPreview";
1079
+ case MONGOCRYPT_QUERY_TYPE_SUBSTRING: return "Substring";
1080
+ case MONGOCRYPT_QUERY_TYPE_PREFIXPREVIEW_DEPRECATED: return "PrefixPreview";
1081
+ case MONGOCRYPT_QUERY_TYPE_SUFFIXPREVIEW_DEPRECATED: return "SuffixPreview";
1082
+ case MONGOCRYPT_QUERY_TYPE_SUBSTRINGPREVIEW_DEPRECATED: return "SubstringPreview";
1070
1083
  default: return "Unknown";
1071
1084
  }
1072
1085
  }
@@ -984,6 +984,10 @@ bool _mongocrypt_parse_kms_providers(mongocrypt_binary_t *kms_providers_definiti
984
984
  } else if (0 == strcmp(field_name, "kmip") && bson_empty(&field_bson)) {
985
985
  kms_providers->need_credentials |= MONGOCRYPT_KMS_PROVIDER_KMIP;
986
986
  } else if (0 == strcmp(field_name, "kmip")) {
987
+ if (0 != (kms_providers->configured_providers & MONGOCRYPT_KMS_PROVIDER_KMIP)) {
988
+ CLIENT_ERR("kmip KMS provider already set");
989
+ return false;
990
+ }
987
991
  if (!_mongocrypt_opts_kms_provider_kmip_parse(&kms_providers->kmip_mut, field_name, &field_bson, status)) {
988
992
  return false;
989
993
  }
@@ -1559,7 +1559,6 @@ bool mongocrypt_ctx_setopt_algorithm_range(mongocrypt_ctx_t *ctx, mongocrypt_bin
1559
1559
  /**
1560
1560
  * Set options for explicit encryption with the "string" algorithm.
1561
1561
  *
1562
- * NOTE: Use of the "substringPreview" query type is experimental only and may be removed in a future non-major release.
1563
1562
  * @p opts is a BSON document of the form:
1564
1563
  * {
1565
1564
  * "caseSensitive": bool,
@@ -1601,8 +1600,9 @@ bool mongocrypt_setopt_key_expiration(mongocrypt_t *crypt, uint64_t cache_expira
1601
1600
  // DEPRECATED: Support "rangePreview" has been removed in favor of "range".
1602
1601
  #define MONGOCRYPT_QUERY_TYPE_RANGEPREVIEW_DEPRECATED_STR "rangePreview"
1603
1602
  #define MONGOCRYPT_QUERY_TYPE_RANGE_STR "range"
1604
- /// NOTE: "substringPreview" is experimental and may be removed in a future non-major release.
1605
- #define MONGOCRYPT_QUERY_TYPE_SUBSTRINGPREVIEW_STR "substringPreview"
1603
+ /// DEPRECATED: Support for "substringPreview" has been removed in favor of "substring"
1604
+ #define MONGOCRYPT_QUERY_TYPE_SUBSTRINGPREVIEW_DEPRECATED_STR "substringPreview"
1605
+ #define MONGOCRYPT_QUERY_TYPE_SUBSTRING_STR "substring"
1606
1606
  /// DEPRECATED: Support for "suffixPreview" has been removed in favor of "suffix"
1607
1607
  #define MONGOCRYPT_QUERY_TYPE_SUFFIXPREVIEW_DEPRECATED_STR "suffixPreview"
1608
1608
  #define MONGOCRYPT_QUERY_TYPE_SUFFIX_STR "suffix"
@@ -66,6 +66,22 @@
66
66
  }
67
67
  }
68
68
  ]
69
- }
69
+ },
70
+ {
71
+ "keyId": {
72
+ "$binary": {
73
+ "base64": "q83vqxI0mHYSNBI0VniQEg==",
74
+ "subType": "04"
75
+ }
76
+ },
77
+ "path": "preferredName",
78
+ "bsonType": "string",
79
+ "queries": {
80
+ "queryType": "substring",
81
+ "contention": {
82
+ "$numberLong": "0"
83
+ }
84
+ }
85
+ }
70
86
  ]
71
- }
87
+ }
@@ -31,10 +31,12 @@ static void _test_efc(_mongocrypt_tester_t *tester) {
31
31
  _mongocrypt_buffer_t expect_keyId1;
32
32
  _mongocrypt_buffer_t expect_keyId2;
33
33
  _mongocrypt_buffer_t expect_keyId3;
34
+ _mongocrypt_buffer_t expect_keyId4;
34
35
 
35
36
  _mongocrypt_buffer_copy_from_hex(&expect_keyId1, "12345678123498761234123456789012");
36
37
  _mongocrypt_buffer_copy_from_hex(&expect_keyId2, "abcdefab123498761234123456789012");
37
38
  _mongocrypt_buffer_copy_from_hex(&expect_keyId3, "12345678123498761234123456abcdef");
39
+ _mongocrypt_buffer_copy_from_hex(&expect_keyId4, "abcdefab123498761234123456789012");
38
40
 
39
41
  {
40
42
  _load_test_file(tester, "./test/data/efc/efc-oneField.json", &efc_bson);
@@ -112,6 +114,11 @@ static void _test_efc(_mongocrypt_tester_t *tester) {
112
114
  ASSERT_CMPUINT8(efc.str_encode_version, ==, LATEST_STR_ENCODE_VERSION);
113
115
  ptr = efc.fields;
114
116
  ASSERT(ptr);
117
+ ASSERT_STREQUAL(ptr->path, "preferredName");
118
+ ASSERT_CMPBUF(expect_keyId4, ptr->keyId);
119
+ ASSERT(ptr->supported_queries == SUPPORTS_SUBSTRING_QUERIES);
120
+ ASSERT(ptr->next != NULL);
121
+ ptr = ptr->next;
115
122
  ASSERT_STREQUAL(ptr->path, "middleName");
116
123
  ASSERT_CMPBUF(expect_keyId3, ptr->keyId);
117
124
  ASSERT(ptr->supported_queries == (SUPPORTS_SUFFIX_QUERIES | SUPPORTS_PREFIX_QUERIES));
@@ -124,7 +131,7 @@ static void _test_efc(_mongocrypt_tester_t *tester) {
124
131
  ptr = ptr->next;
125
132
  ASSERT_STREQUAL(ptr->path, "firstName");
126
133
  ASSERT_CMPBUF(expect_keyId1, ptr->keyId);
127
- ASSERT(ptr->supported_queries == SUPPORTS_SUBSTRING_PREVIEW_QUERIES);
134
+ ASSERT(ptr->supported_queries == SUPPORTS_SUBSTRING_QUERIES);
128
135
  ASSERT(ptr->next == NULL);
129
136
  mc_EncryptedFieldConfig_cleanup(&efc);
130
137
  }
@@ -142,7 +149,7 @@ static void _test_efc(_mongocrypt_tester_t *tester) {
142
149
  ptr = ptr->next;
143
150
  ASSERT_STREQUAL(ptr->path, "firstName");
144
151
  ASSERT_CMPBUF(expect_keyId1, ptr->keyId);
145
- ASSERT(ptr->supported_queries == SUPPORTS_SUBSTRING_PREVIEW_QUERIES);
152
+ ASSERT(ptr->supported_queries == SUPPORTS_SUBSTRING_QUERIES);
146
153
  ASSERT(ptr->next == NULL);
147
154
  mc_EncryptedFieldConfig_cleanup(&efc);
148
155
  }
@@ -165,6 +172,7 @@ static void _test_efc(_mongocrypt_tester_t *tester) {
165
172
  _mongocrypt_status_reset(status);
166
173
  }
167
174
 
175
+ _mongocrypt_buffer_cleanup(&expect_keyId4);
168
176
  _mongocrypt_buffer_cleanup(&expect_keyId3);
169
177
  _mongocrypt_buffer_cleanup(&expect_keyId2);
170
178
  _mongocrypt_buffer_cleanup(&expect_keyId1);
@@ -245,7 +245,7 @@ static void test_mc_TextOpts_to_FLE2TextSearchInsertSpec_for_query(_mongocrypt_t
245
245
  "substring" : {"strMaxLength" : 10, "strMinQueryLength" : 3, "strMaxQueryLength" : 8}
246
246
  }),
247
247
  .v = RAW_STRING({"v" : "test"}),
248
- .qt = MONGOCRYPT_QUERY_TYPE_SUBSTRINGPREVIEW,
248
+ .qt = MONGOCRYPT_QUERY_TYPE_SUBSTRING,
249
249
  .expect = RAW_STRING(
250
250
  {"v" : {"v" : "test", "casef" : false, "diacf" : true, "substr" : {"mlen" : 10, "ub" : 8, "lb" : 3}}})},
251
251
  {.desc = "Works with prefix",
@@ -2511,10 +2511,11 @@ static void _test_encrypt_fle2_explicit(_mongocrypt_tester_t *tester) {
2511
2511
  }
2512
2512
 
2513
2513
  {
2514
+ // "suffixPreview" is a deprecated alias for "suffix" and must produce identical output.
2514
2515
  ee_testcase tc = {0};
2515
- tc.desc = "find suffix";
2516
+ tc.desc = "find suffixPreview";
2516
2517
  tc.algorithm = MONGOCRYPT_ALGORITHM_STRING_STR;
2517
- tc.query_type = MONGOCRYPT_QUERY_TYPE_SUFFIX_STR;
2518
+ tc.query_type = MONGOCRYPT_QUERY_TYPE_SUFFIXPREVIEW_DEPRECATED_STR;
2518
2519
  tc.contention_factor = OPT_I64(1);
2519
2520
  tc.msg = TEST_BSON("{'v': 'abc'}");
2520
2521
  tc.user_key_id = &keyABC_id;
@@ -2529,10 +2530,11 @@ static void _test_encrypt_fle2_explicit(_mongocrypt_tester_t *tester) {
2529
2530
  }
2530
2531
 
2531
2532
  {
2533
+ // "prefixPreview" is a deprecated alias for "prefix" and must produce identical output.
2532
2534
  ee_testcase tc = {0};
2533
- tc.desc = "find prefix";
2535
+ tc.desc = "find prefixPreview";
2534
2536
  tc.algorithm = MONGOCRYPT_ALGORITHM_STRING_STR;
2535
- tc.query_type = MONGOCRYPT_QUERY_TYPE_PREFIX_STR;
2537
+ tc.query_type = MONGOCRYPT_QUERY_TYPE_PREFIXPREVIEW_DEPRECATED_STR;
2536
2538
  tc.contention_factor = OPT_I64(1);
2537
2539
  tc.msg = TEST_BSON("{'v': 'abc'}");
2538
2540
  tc.user_key_id = &keyABC_id;
@@ -2548,9 +2550,27 @@ static void _test_encrypt_fle2_explicit(_mongocrypt_tester_t *tester) {
2548
2550
 
2549
2551
  {
2550
2552
  ee_testcase tc = {0};
2551
- tc.desc = "insert substring";
2553
+ tc.desc = "find substring";
2552
2554
  tc.algorithm = MONGOCRYPT_ALGORITHM_STRING_STR;
2553
- tc.query_type = MONGOCRYPT_QUERY_TYPE_SUBSTRINGPREVIEW_STR;
2555
+ tc.query_type = MONGOCRYPT_QUERY_TYPE_SUBSTRINGPREVIEW_DEPRECATED_STR;
2556
+ tc.contention_factor = OPT_I64(1);
2557
+ tc.msg = TEST_BSON("{'v': 'abc'}");
2558
+ tc.user_key_id = &keyABC_id;
2559
+ tc.keys_to_feed[0] = keyABC;
2560
+ tc.text_opts = TEST_BSON(RAW_STRING({
2561
+ "caseSensitive" : true,
2562
+ "diacriticSensitive" : true,
2563
+ "substring" : {"strMaxLength" : 100, "strMinQueryLength" : 1, "strMaxQueryLength" : 100}
2564
+ }));
2565
+ tc.expect = TEST_FILE("./test/data/fle2-explicit/find-substring.json");
2566
+ ee_testcase_run(&tc);
2567
+ }
2568
+
2569
+ {
2570
+ ee_testcase tc = {0};
2571
+ tc.desc = "find substring";
2572
+ tc.algorithm = MONGOCRYPT_ALGORITHM_STRING_STR;
2573
+ tc.query_type = MONGOCRYPT_QUERY_TYPE_SUBSTRING_STR;
2554
2574
  tc.contention_factor = OPT_I64(1);
2555
2575
  tc.msg = TEST_BSON("{'v': 'abc'}");
2556
2576
  tc.user_key_id = &keyABC_id;
@@ -4410,8 +4430,9 @@ static void _test_rangePreview_fails(_mongocrypt_tester_t *tester) {
4410
4430
  bson_free(local_kek);
4411
4431
  }
4412
4432
 
4413
- // `_test_prefixPreview_suffixPreview_fails` tests that use of "prefixPreview" or "suffixPreview" errors.
4414
- static void _test_prefixPreview_suffixPreview_fails(_mongocrypt_tester_t *tester) {
4433
+ // `_test_prefixPreview_suffixPreview_succeeds` tests that "prefixPreview" and "suffixPreview" are accepted as
4434
+ // deprecated aliases for "prefix" and "suffix".
4435
+ static void _test_prefixPreview_suffixPreview_succeeds(_mongocrypt_tester_t *tester) {
4415
4436
  #define TF(suffix) TEST_FILE("./test/data/fle2-insert-text-search-preview/" suffix)
4416
4437
 
4417
4438
  // local_kek is the KEK used to encrypt the keyMaterial in ./test/data/key-document-local.json
@@ -4420,35 +4441,31 @@ static void _test_prefixPreview_suffixPreview_fails(_mongocrypt_tester_t *tester
4420
4441
  mongocrypt_binary_t *kms_providers =
4421
4442
  TEST_BSON(BSON_STR({"local" : {"key" : {"$binary" : {"base64" : "%s", "subType" : "00"}}}}), local_kek);
4422
4443
 
4423
- // Test setting 'prefixPreview' as an explicit encryption queryType results in error.
4444
+ // Test setting 'prefixPreview' as an explicit encryption queryType succeeds.
4424
4445
  {
4425
4446
  mongocrypt_t *crypt = mongocrypt_new();
4426
4447
  mongocrypt_setopt_kms_providers(crypt, kms_providers);
4427
4448
  ASSERT_OK(mongocrypt_init(crypt), crypt);
4428
4449
  mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
4429
4450
  ASSERT_OK(ctx, crypt);
4430
- ASSERT_FAILS(mongocrypt_ctx_setopt_query_type(ctx, MONGOCRYPT_QUERY_TYPE_PREFIXPREVIEW_DEPRECATED_STR, -1),
4431
- ctx,
4432
- "Query type 'prefixPreview' is deprecated");
4451
+ ASSERT_OK(mongocrypt_ctx_setopt_query_type(ctx, MONGOCRYPT_QUERY_TYPE_PREFIXPREVIEW_DEPRECATED_STR, -1), ctx);
4433
4452
  mongocrypt_ctx_destroy(ctx);
4434
4453
  mongocrypt_destroy(crypt);
4435
4454
  }
4436
4455
 
4437
- // Test setting 'suffixPreview' as an explicit encryption queryType results in error.
4456
+ // Test setting 'suffixPreview' as an explicit encryption queryType succeeds.
4438
4457
  {
4439
4458
  mongocrypt_t *crypt = mongocrypt_new();
4440
4459
  mongocrypt_setopt_kms_providers(crypt, kms_providers);
4441
4460
  ASSERT_OK(mongocrypt_init(crypt), crypt);
4442
4461
  mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
4443
4462
  ASSERT_OK(ctx, crypt);
4444
- ASSERT_FAILS(mongocrypt_ctx_setopt_query_type(ctx, MONGOCRYPT_QUERY_TYPE_SUFFIXPREVIEW_DEPRECATED_STR, -1),
4445
- ctx,
4446
- "Query type 'suffixPreview' is deprecated");
4463
+ ASSERT_OK(mongocrypt_ctx_setopt_query_type(ctx, MONGOCRYPT_QUERY_TYPE_SUFFIXPREVIEW_DEPRECATED_STR, -1), ctx);
4447
4464
  mongocrypt_ctx_destroy(ctx);
4448
4465
  mongocrypt_destroy(crypt);
4449
4466
  }
4450
4467
 
4451
- // Test setting 'prefixPreview' from encryptedFields results in error.
4468
+ // Test setting 'prefixPreview' from encryptedFields succeeds.
4452
4469
  {
4453
4470
  mongocrypt_t *crypt = mongocrypt_new();
4454
4471
  mongocrypt_setopt_kms_providers(crypt, kms_providers);
@@ -4457,14 +4474,12 @@ static void _test_prefixPreview_suffixPreview_fails(_mongocrypt_tester_t *tester
4457
4474
  ASSERT_OK(mongocrypt_init(crypt), crypt);
4458
4475
  mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
4459
4476
  ASSERT_OK(ctx, crypt);
4460
- ASSERT_FAILS(mongocrypt_ctx_encrypt_init(ctx, "db", -1, TF("cmd.json")),
4461
- ctx,
4462
- "Cannot use field 'encrypted' with 'prefixPreview' queries");
4477
+ ASSERT_OK(mongocrypt_ctx_encrypt_init(ctx, "db", -1, TF("cmd.json")), ctx);
4463
4478
  mongocrypt_ctx_destroy(ctx);
4464
4479
  mongocrypt_destroy(crypt);
4465
4480
  }
4466
4481
 
4467
- // Test setting 'suffixPreview' from encryptedFields results in error.
4482
+ // Test setting 'suffixPreview' from encryptedFields succeeds.
4468
4483
  {
4469
4484
  mongocrypt_t *crypt = mongocrypt_new();
4470
4485
  mongocrypt_setopt_kms_providers(crypt, kms_providers);
@@ -4473,9 +4488,7 @@ static void _test_prefixPreview_suffixPreview_fails(_mongocrypt_tester_t *tester
4473
4488
  ASSERT_OK(mongocrypt_init(crypt), crypt);
4474
4489
  mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
4475
4490
  ASSERT_OK(ctx, crypt);
4476
- ASSERT_FAILS(mongocrypt_ctx_encrypt_init(ctx, "db", -1, TF("cmd.json")),
4477
- ctx,
4478
- "Cannot use field 'encrypted' with 'suffixPreview' queries");
4491
+ ASSERT_OK(mongocrypt_ctx_encrypt_init(ctx, "db", -1, TF("cmd.json")), ctx);
4479
4492
  mongocrypt_ctx_destroy(ctx);
4480
4493
  mongocrypt_destroy(crypt);
4481
4494
  }
@@ -4490,7 +4503,7 @@ static void _test_textPreview_fails(_mongocrypt_tester_t *tester) {
4490
4503
  mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
4491
4504
  ASSERT_FAILS(mongocrypt_ctx_setopt_algorithm(ctx, MONGOCRYPT_ALGORITHM_TEXTPREVIEW_DEPRECATED_STR, -1),
4492
4505
  ctx,
4493
- "unsupported algorithm");
4506
+ "please use 'string'");
4494
4507
  mongocrypt_ctx_destroy(ctx);
4495
4508
  mongocrypt_destroy(crypt);
4496
4509
  }
@@ -6904,7 +6917,7 @@ void _mongocrypt_tester_install_ctx_encrypt(_mongocrypt_tester_t *tester) {
6904
6917
  INSTALL_TEST(_test_encrypt_fle2_insert_text_search_payload_with_str_encode_version);
6905
6918
  INSTALL_TEST(_test_bulkWrite);
6906
6919
  INSTALL_TEST(_test_rangePreview_fails);
6907
- INSTALL_TEST(_test_prefixPreview_suffixPreview_fails);
6920
+ INSTALL_TEST(_test_prefixPreview_suffixPreview_succeeds);
6908
6921
  INSTALL_TEST(_test_textPreview_fails);
6909
6922
  INSTALL_TEST(_test_no_trimFactor);
6910
6923
  INSTALL_TEST(_test_range_sends_cryptoParams);
@@ -1004,9 +1004,18 @@ static void _test_setopt_for_explicit_encrypt(_mongocrypt_tester_t *tester) {
1004
1004
  /* Set key ID to get past the 'either key id or key alt name required'
1005
1005
  * error */
1006
1006
  ASSERT_KEY_ID_OK(uuid);
1007
- ASSERT_OK(mongocrypt_ctx_setopt_query_type(ctx, MONGOCRYPT_QUERY_TYPE_SUBSTRINGPREVIEW_STR, -1), ctx);
1007
+ ASSERT_OK(mongocrypt_ctx_setopt_query_type(ctx, MONGOCRYPT_QUERY_TYPE_SUBSTRINGPREVIEW_DEPRECATED_STR, -1),
1008
+ ctx);
1008
1009
  ASSERT_OK(mongocrypt_ctx_setopt_algorithm(ctx, MONGOCRYPT_ALGORITHM_RANGE_STR, -1), ctx);
1009
- ASSERT_EX_ENCRYPT_INIT_FAILS(bson, "substringPreview query type requires string index type");
1010
+ ASSERT_EX_ENCRYPT_INIT_FAILS(bson, "substring query type requires string index type");
1011
+
1012
+ REFRESH;
1013
+ /* Set key ID to get past the 'either key id or key alt name required'
1014
+ * error */
1015
+ ASSERT_KEY_ID_OK(uuid);
1016
+ ASSERT_OK(mongocrypt_ctx_setopt_query_type(ctx, MONGOCRYPT_QUERY_TYPE_SUBSTRING_STR, -1), ctx);
1017
+ ASSERT_OK(mongocrypt_ctx_setopt_algorithm(ctx, MONGOCRYPT_ALGORITHM_RANGE_STR, -1), ctx);
1018
+ ASSERT_EX_ENCRYPT_INIT_FAILS(bson, "substring query type requires string index type");
1010
1019
 
1011
1020
  REFRESH;
1012
1021
  /* Set key ID to get past the 'either key id or key alt name required'
@@ -1041,23 +1050,19 @@ static void _test_setopt_for_explicit_encrypt(_mongocrypt_tester_t *tester) {
1041
1050
  ASSERT_EX_ENCRYPT_INIT_FAILS(bson, "suffix query type requires string index type");
1042
1051
  }
1043
1052
 
1044
- // Can't use "prefixPreview" or "suffixPreview".
1053
+ // "prefixPreview" and "suffixPreview" are accepted as deprecated aliases for "prefix" and "suffix".
1045
1054
  {
1046
1055
  mongocrypt_destroy(crypt);
1047
1056
  crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_DEFAULT);
1048
1057
  REFRESH_CTX;
1049
1058
  ASSERT_KEY_ID_OK(uuid);
1050
- ASSERT_FAILS(mongocrypt_ctx_setopt_query_type(ctx, MONGOCRYPT_QUERY_TYPE_PREFIXPREVIEW_DEPRECATED_STR, -1),
1051
- ctx,
1052
- "'prefixPreview' is deprecated");
1059
+ ASSERT_OK(mongocrypt_ctx_setopt_query_type(ctx, MONGOCRYPT_QUERY_TYPE_PREFIXPREVIEW_DEPRECATED_STR, -1), ctx);
1053
1060
 
1054
1061
  mongocrypt_destroy(crypt);
1055
1062
  crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_DEFAULT);
1056
1063
  REFRESH_CTX;
1057
1064
  ASSERT_KEY_ID_OK(uuid);
1058
- ASSERT_FAILS(mongocrypt_ctx_setopt_query_type(ctx, MONGOCRYPT_QUERY_TYPE_SUFFIXPREVIEW_DEPRECATED_STR, -1),
1059
- ctx,
1060
- "'suffixPreview' is deprecated");
1065
+ ASSERT_OK(mongocrypt_ctx_setopt_query_type(ctx, MONGOCRYPT_QUERY_TYPE_SUFFIXPREVIEW_DEPRECATED_STR, -1), ctx);
1061
1066
  }
1062
1067
 
1063
1068
  /* It is an error to set a string algorithm without setting text options */
@@ -20,6 +20,7 @@
20
20
  #include "mongocrypt-key-private.h"
21
21
  #include "mongocrypt-kms-ctx-private.h"
22
22
  #include "mongocrypt-private.h"
23
+ #include "test-mongocrypt-assert.h"
23
24
  #include "test-mongocrypt-util.h"
24
25
  #include "test-mongocrypt.h"
25
26
 
@@ -885,6 +886,100 @@ static void _test_mongocrypt_kms_ctx_feed_empty_bytes(_mongocrypt_tester_t *test
885
886
  mongocrypt_status_destroy(status);
886
887
  }
887
888
 
889
+ // _test_mongocrypt_kms_ctx_kmip_response_bad_length tests KMIP responses that report bad lengths.
890
+ static void _test_mongocrypt_kms_ctx_kmip_response_bad_length(_mongocrypt_tester_t *tester) {
891
+ mongocrypt_t *crypt = _mongocrypt_tester_mongocrypt(TESTER_MONGOCRYPT_DEFAULT);
892
+ bool ok;
893
+ uint8_t secretdata[KMS_KMIP_REQUEST_SECRETDATA_LENGTH] = {0};
894
+ mongocrypt_status_t *status = mongocrypt_status_new();
895
+ _mongocrypt_endpoint_t *endpoint = _mongocrypt_endpoint_new("example.com", -1, NULL /* opts */, status);
896
+ ASSERT_OK_STATUS(endpoint != NULL, status);
897
+
898
+ // Regression test for MONGOCRYPT-909: test UINT32_MAX
899
+ {
900
+ mongocrypt_kms_ctx_t kms_ctx = {0};
901
+ static const char *kmip_header = "\x42\x00\x7b\x01" // Tag=ResponseMessage, Type=Structure
902
+ "\xff\xff\xff\xff"; // Length = UINT32_MAX
903
+
904
+ ok = _mongocrypt_kms_ctx_init_kmip_register(&kms_ctx,
905
+ endpoint,
906
+ secretdata,
907
+ KMS_KMIP_REQUEST_SECRETDATA_LENGTH,
908
+ "kmip",
909
+ &crypt->log);
910
+ ASSERT_OK_STATUS(ok, kms_ctx.status);
911
+
912
+ // Parser requests 8 bytes for initial header:
913
+ ASSERT_CMPINT(mongocrypt_kms_ctx_bytes_needed(&kms_ctx), ==, 8u);
914
+
915
+ mongocrypt_binary_t *bytes = mongocrypt_binary_new_from_data((uint8_t *)kmip_header, 8u);
916
+
917
+ // Expect error (not abort):
918
+ ASSERT_FAILS(mongocrypt_kms_ctx_feed(&kms_ctx, bytes), &kms_ctx, "KMS KMIP response too large");
919
+
920
+ mongocrypt_binary_destroy(bytes);
921
+ _mongocrypt_kms_ctx_cleanup(&kms_ctx);
922
+ }
923
+
924
+ // Length reported is less than data fed.
925
+ {
926
+ mongocrypt_kms_ctx_t kms_ctx = {0};
927
+ static const char *kmip_header = "\x42\x00\x7b\x01" // Tag=ResponseMessage, Type=Structure
928
+ "\x00\x00\x00\x01"; // Length = 1
929
+ ASSERT_OK_STATUS(endpoint != NULL, status);
930
+
931
+ ok = _mongocrypt_kms_ctx_init_kmip_register(&kms_ctx,
932
+ endpoint,
933
+ secretdata,
934
+ KMS_KMIP_REQUEST_SECRETDATA_LENGTH,
935
+ "kmip",
936
+ &crypt->log);
937
+ ASSERT_OK_STATUS(ok, kms_ctx.status);
938
+
939
+ // Parser requests 8 bytes for initial header:
940
+ ASSERT_CMPINT(mongocrypt_kms_ctx_bytes_needed(&kms_ctx), ==, 8u);
941
+
942
+ mongocrypt_binary_t *bytes = mongocrypt_binary_new_from_data((uint8_t *)kmip_header, 8u);
943
+ ASSERT_OK(mongocrypt_kms_ctx_feed(&kms_ctx, bytes), &kms_ctx);
944
+
945
+ ASSERT_CMPINT(mongocrypt_kms_ctx_bytes_needed(&kms_ctx), ==, 1u);
946
+ // Attempting to feed more data errors.
947
+ ASSERT_FAILS(mongocrypt_kms_ctx_feed(&kms_ctx, bytes), &kms_ctx, "KMS response fed too much data");
948
+
949
+ mongocrypt_binary_destroy(bytes);
950
+ _mongocrypt_kms_ctx_cleanup(&kms_ctx);
951
+ }
952
+
953
+ // Length reported is zero.
954
+ {
955
+ mongocrypt_kms_ctx_t kms_ctx = {0};
956
+ static const char *kmip_header = "\x42\x00\x7b\x01" // Tag=ResponseMessage, Type=Structure
957
+ "\x00\x00\x00\x00"; // Length = 0
958
+ ASSERT_OK_STATUS(endpoint != NULL, status);
959
+
960
+ ok = _mongocrypt_kms_ctx_init_kmip_register(&kms_ctx,
961
+ endpoint,
962
+ secretdata,
963
+ KMS_KMIP_REQUEST_SECRETDATA_LENGTH,
964
+ "kmip",
965
+ &crypt->log);
966
+ ASSERT_OK_STATUS(ok, kms_ctx.status);
967
+
968
+ // Parser requests 8 bytes for initial header:
969
+ ASSERT_CMPINT(mongocrypt_kms_ctx_bytes_needed(&kms_ctx), ==, 8u);
970
+
971
+ mongocrypt_binary_t *bytes = mongocrypt_binary_new_from_data((uint8_t *)kmip_header, 8u);
972
+ ASSERT_FAILS(mongocrypt_kms_ctx_feed(&kms_ctx, bytes), &kms_ctx, "Error getting UniqueIdentifer");
973
+
974
+ mongocrypt_binary_destroy(bytes);
975
+ _mongocrypt_kms_ctx_cleanup(&kms_ctx);
976
+ }
977
+
978
+ _mongocrypt_endpoint_destroy(endpoint);
979
+ mongocrypt_status_destroy(status);
980
+ mongocrypt_destroy(crypt);
981
+ }
982
+
888
983
  void _mongocrypt_tester_install_kms_ctx(_mongocrypt_tester_t *tester) {
889
984
  INSTALL_TEST(_test_mongocrypt_kms_ctx_kmip_register);
890
985
  INSTALL_TEST(_test_mongocrypt_kms_ctx_kmip_activate);
@@ -895,4 +990,5 @@ void _mongocrypt_tester_install_kms_ctx(_mongocrypt_tester_t *tester) {
895
990
  INSTALL_TEST(_test_mongocrypt_kms_ctx_get_kms_provider);
896
991
  INSTALL_TEST(_test_mongocrypt_kms_ctx_default_port);
897
992
  INSTALL_TEST(_test_mongocrypt_kms_ctx_feed_empty_bytes);
993
+ INSTALL_TEST(_test_mongocrypt_kms_ctx_kmip_response_bad_length);
898
994
  }
@@ -906,6 +906,16 @@ static void _test_setopt_kms_providers(_mongocrypt_tester_t *tester) {
906
906
  ASSERT_FAILS(mongocrypt_setopt_kms_providers(crypt, more), crypt, "already set");
907
907
  mongocrypt_destroy(crypt);
908
908
  }
909
+
910
+ // Errors if followed by call to `mongocrypt_setopt_kms_providers` configuring "kmip".
911
+ // This is a regression test for: MONGOCRYPT-956
912
+ {
913
+ mongocrypt_binary_t *kms_providers = TEST_BSON("{'kmip' : {'endpoint' : 'localhost'}}");
914
+ mongocrypt_t *crypt = mongocrypt_new();
915
+ ASSERT_OK(mongocrypt_setopt_kms_providers(crypt, kms_providers), crypt);
916
+ ASSERT_FAILS(mongocrypt_setopt_kms_providers(crypt, kms_providers), crypt, "already set");
917
+ mongocrypt_destroy(crypt);
918
+ }
909
919
  }
910
920
 
911
921
  static void test_tmp_bsonf(_mongocrypt_tester_t *tester) {
@@ -1,5 +1,5 @@
1
1
  module LibmongocryptHelper
2
- VERSION = '1.19.0.0.1001'
2
+ VERSION = '1.20.1.0.1001'
3
3
 
4
- LIBMONGOCRYPT_VERSION = '1.19.0'
4
+ LIBMONGOCRYPT_VERSION = '1.20.1'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: libmongocrypt-helper
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.19.0.0.1001
4
+ version: 1.20.1.0.1001
5
5
  platform: ruby
6
6
  authors:
7
7
  - The MongoDB Ruby Team
@@ -1250,7 +1250,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
1250
1250
  - !ruby/object:Gem::Version
1251
1251
  version: '0'
1252
1252
  requirements: []
1253
- rubygems_version: 4.0.13
1253
+ rubygems_version: 4.0.17
1254
1254
  specification_version: 4
1255
1255
  summary: libmongocrypt convenience package
1256
1256
  test_files: []