libmongocrypt-helper 1.12.0.0.1001 → 1.13.2.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 (491) hide show
  1. checksums.yaml +4 -4
  2. data/ext/libmongocrypt/libmongocrypt/CHANGELOG.md +19 -0
  3. data/ext/libmongocrypt/libmongocrypt/CMakeLists.txt +10 -0
  4. data/ext/libmongocrypt/libmongocrypt/CODEOWNERS +1 -4
  5. data/ext/libmongocrypt/libmongocrypt/CONTRIBUTING.md +14 -0
  6. data/ext/libmongocrypt/libmongocrypt/Earthfile +49 -50
  7. data/ext/libmongocrypt/libmongocrypt/README.md +8 -17
  8. data/ext/libmongocrypt/libmongocrypt/bindings/python/CHANGELOG.rst +6 -0
  9. data/ext/libmongocrypt/libmongocrypt/bindings/python/README.rst +1 -1
  10. data/ext/libmongocrypt/libmongocrypt/bindings/python/libmongocrypt-version.txt +1 -1
  11. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/binding.py +39 -1
  12. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/mongocrypt.py +32 -0
  13. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/version.py +1 -1
  14. data/ext/libmongocrypt/libmongocrypt/bindings/python/release.sh +1 -1
  15. data/ext/libmongocrypt/libmongocrypt/bindings/python/sbom.json +8 -8
  16. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/compact/success/encrypted-field-config-map.json +0 -1
  17. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/encrypted-field-config-map.json +0 -2
  18. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/test_mongocrypt.py +11 -11
  19. data/ext/libmongocrypt/libmongocrypt/cmake/FetchMongoC.cmake +4 -2
  20. data/ext/libmongocrypt/libmongocrypt/cmake/ImportBSON.cmake +3 -5
  21. data/ext/libmongocrypt/libmongocrypt/doc/releasing.md +14 -27
  22. data/ext/libmongocrypt/libmongocrypt/etc/cyclonedx.sbom.json +9 -9
  23. data/ext/libmongocrypt/libmongocrypt/etc/format.sh +0 -2
  24. data/ext/libmongocrypt/libmongocrypt/etc/libbson-remove-GCC-diagnostic-in-functions.patch +158 -0
  25. data/ext/libmongocrypt/libmongocrypt/etc/libbson-remove-GCC-diagnostic-pragma.patch +3 -3
  26. data/ext/libmongocrypt/libmongocrypt/etc/purls.txt +1 -1
  27. data/ext/libmongocrypt/libmongocrypt/integrating.md +42 -11
  28. data/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_crypto_windows.c +2 -2
  29. data/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_message.c +1 -1
  30. data/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_message_private.h +2 -2
  31. data/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_request.c +3 -3
  32. data/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kmip_reader_writer.c +5 -5
  33. data/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kms_assert.h +25 -8
  34. data/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kms_azure_online.c +2 -2
  35. data/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kms_gcp_online.c +3 -3
  36. data/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kms_request.c +12 -10
  37. data/ext/libmongocrypt/libmongocrypt/src/mc-efc-private.h +5 -0
  38. data/ext/libmongocrypt/libmongocrypt/src/mc-efc.c +35 -1
  39. data/ext/libmongocrypt/libmongocrypt/src/mc-fle-blob-subtype-private.h +4 -1
  40. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-encryption-placeholder-private.h +79 -0
  41. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-encryption-placeholder.c +226 -2
  42. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-equality-payload-v2.c +0 -1
  43. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-equality-payload.c +0 -1
  44. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-insert-update-payload-private-v2.h +34 -0
  45. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-insert-update-payload-v2.c +165 -1
  46. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-insert-update-payload.c +0 -1
  47. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-payload-iev-private-v2.h +105 -7
  48. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-payload-iev-v2.c +381 -70
  49. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-tag-and-encrypted-metadata-block-private.h +7 -2
  50. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-tag-and-encrypted-metadata-block.c +17 -0
  51. data/ext/libmongocrypt/libmongocrypt/src/mc-schema-broker-private.h +126 -0
  52. data/ext/libmongocrypt/libmongocrypt/src/mc-schema-broker.c +1075 -0
  53. data/ext/libmongocrypt/libmongocrypt/src/mc-str-encode-string-sets-private.h +95 -0
  54. data/ext/libmongocrypt/libmongocrypt/src/mc-str-encode-string-sets.c +304 -0
  55. data/ext/libmongocrypt/libmongocrypt/src/mc-text-search-str-encode-private.h +45 -0
  56. data/ext/libmongocrypt/libmongocrypt/src/mc-text-search-str-encode.c +248 -0
  57. data/ext/libmongocrypt/libmongocrypt/src/mc-tokens-private.h +112 -2
  58. data/ext/libmongocrypt/libmongocrypt/src/mc-tokens.c +166 -2
  59. data/ext/libmongocrypt/libmongocrypt/src/mlib/windows-lean.h +2 -0
  60. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-buffer-private.h +11 -0
  61. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-buffer.c +36 -3
  62. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ctx-decrypt.c +8 -4
  63. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ctx-encrypt.c +430 -857
  64. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ctx-private.h +5 -19
  65. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-kms-ctx.c +1 -1
  66. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-marking.c +516 -523
  67. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-opts-private.h +0 -4
  68. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-private.h +7 -12
  69. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-traverse-util.c +1 -1
  70. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-util.c +3 -1
  71. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt.c +6 -9
  72. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt.h +17 -0
  73. data/ext/libmongocrypt/libmongocrypt/src/os_posix/os_dll.c +3 -1
  74. data/ext/libmongocrypt/libmongocrypt/src/unicode/case-fold-map.c +1434 -0
  75. data/ext/libmongocrypt/libmongocrypt/src/unicode/diacritic-fold-map.c +2884 -0
  76. data/ext/libmongocrypt/libmongocrypt/src/unicode/fold.c +139 -0
  77. data/ext/libmongocrypt/libmongocrypt/src/unicode/fold.h +58 -0
  78. data/ext/libmongocrypt/libmongocrypt/test/data/bulkWrite/unencrypted/payload.json +2 -2
  79. data/ext/libmongocrypt/libmongocrypt/test/data/cleanup/missing-key-id/collinfo.json +1 -0
  80. data/ext/libmongocrypt/libmongocrypt/test/data/cleanup/no-fields/collinfo.json +1 -0
  81. data/ext/libmongocrypt/libmongocrypt/test/data/cleanup/success/collinfo.json +1 -0
  82. data/ext/libmongocrypt/libmongocrypt/test/data/compact/anchor-pad/collinfo.json +1 -1
  83. data/ext/libmongocrypt/libmongocrypt/test/data/compact/anchor-pad/encrypted-payload-range-v2.json +20 -21
  84. data/ext/libmongocrypt/libmongocrypt/test/data/compact/missing-key-id/collinfo.json +2 -2
  85. data/ext/libmongocrypt/libmongocrypt/test/data/compact/no-fields/collinfo.json +1 -1
  86. data/ext/libmongocrypt/libmongocrypt/test/data/compact/no-range/collinfo.json +1 -1
  87. data/ext/libmongocrypt/libmongocrypt/test/data/compact/success/collinfo.json +1 -1
  88. data/ext/libmongocrypt/libmongocrypt/test/data/compact/success/encrypted-field-config-map.json +0 -1
  89. data/ext/libmongocrypt/libmongocrypt/test/data/compact/success/encrypted-payload-range-v2.json +20 -21
  90. data/ext/libmongocrypt/libmongocrypt/test/data/dollardb/omitted/cmd-to-mongocryptd.json +1 -2
  91. data/ext/libmongocrypt/libmongocrypt/test/data/dollardb/omitted/collinfo.json +2 -2
  92. data/ext/libmongocrypt/libmongocrypt/test/data/dollardb/omitted/encrypted-payload.json +2 -3
  93. data/ext/libmongocrypt/libmongocrypt/test/data/dollardb/omitted/mongocryptd-reply.json +1 -2
  94. data/ext/libmongocrypt/libmongocrypt/test/data/dollardb/preserved/cmd-to-mongocryptd.json +1 -2
  95. data/ext/libmongocrypt/libmongocrypt/test/data/dollardb/preserved/collinfo.json +2 -2
  96. data/ext/libmongocrypt/libmongocrypt/test/data/dollardb/preserved/encrypted-payload.json +2 -3
  97. data/ext/libmongocrypt/libmongocrypt/test/data/dollardb/preserved/mongocryptd-reply.json +1 -2
  98. data/ext/libmongocrypt/libmongocrypt/test/data/dollardb/preserved_empty/cmd-to-mongocryptd.json +1 -2
  99. data/ext/libmongocrypt/libmongocrypt/test/data/dollardb/preserved_empty/collinfo.json +2 -2
  100. data/ext/libmongocrypt/libmongocrypt/test/data/dollardb/preserved_empty/mongocryptd-reply.json +1 -2
  101. data/ext/libmongocrypt/libmongocrypt/test/data/dollardb/preserved_fle1/collinfo.json +2 -1
  102. data/ext/libmongocrypt/libmongocrypt/test/data/efc/efc-extraField.json +0 -1
  103. data/ext/libmongocrypt/libmongocrypt/test/data/efc/efc-missingKeyId.json +0 -1
  104. data/ext/libmongocrypt/libmongocrypt/test/data/efc/efc-oneField-badVersionSet.json +23 -0
  105. data/ext/libmongocrypt/libmongocrypt/test/data/efc/efc-oneField-goodVersionSet.json +23 -0
  106. data/ext/libmongocrypt/libmongocrypt/test/data/efc/efc-oneField.json +0 -1
  107. data/ext/libmongocrypt/libmongocrypt/test/data/efc/efc-textSearchFields-badVersionSet.json +48 -0
  108. data/ext/libmongocrypt/libmongocrypt/test/data/efc/efc-textSearchFields-goodVersionSet.json +48 -0
  109. data/ext/libmongocrypt/libmongocrypt/test/data/efc/efc-textSearchFields.json +47 -0
  110. data/ext/libmongocrypt/libmongocrypt/test/data/efc/efc-twoFields.json +0 -1
  111. data/ext/libmongocrypt/libmongocrypt/test/data/encrypted-field-config-map.json +1 -3
  112. data/ext/libmongocrypt/libmongocrypt/test/data/explicit-decrypt/FLE1DeterministicEncryptedValue.json +8 -0
  113. data/ext/libmongocrypt/libmongocrypt/test/data/explicit-decrypt/FLE1EncryptionPlaceholder.json +8 -0
  114. data/ext/libmongocrypt/libmongocrypt/test/data/explicit-decrypt/FLE1RandomEncryptedValue.json +8 -0
  115. data/ext/libmongocrypt/libmongocrypt/test/data/explicit-decrypt/FLE2EncryptionPlaceholder.json +8 -0
  116. data/ext/libmongocrypt/libmongocrypt/test/data/explicit-decrypt/FLE2EqualityIndexedValueV2.json +8 -0
  117. data/ext/libmongocrypt/libmongocrypt/test/data/explicit-decrypt/FLE2FindEqualityPayloadV2.json +8 -0
  118. data/ext/libmongocrypt/libmongocrypt/test/data/explicit-decrypt/FLE2IndexedEqualityEncryptedValue.json +8 -0
  119. data/ext/libmongocrypt/libmongocrypt/test/data/explicit-decrypt/FLE2IndexedEqualityEncryptedValueV2.json +8 -0
  120. data/ext/libmongocrypt/libmongocrypt/test/data/explicit-decrypt/FLE2IndexedRangeEncryptedValue.json +8 -0
  121. data/ext/libmongocrypt/libmongocrypt/test/data/explicit-decrypt/FLE2IndexedRangeEncryptedValueV2.json +8 -0
  122. data/ext/libmongocrypt/libmongocrypt/test/data/explicit-decrypt/FLE2InsertUpdatePayload-with-edges-V2.json +8 -0
  123. data/ext/libmongocrypt/libmongocrypt/test/data/explicit-decrypt/FLE2InsertUpdatePayload-with-edges.json +8 -0
  124. data/ext/libmongocrypt/libmongocrypt/test/data/{fle2-explicit/insert-indexed.json → explicit-decrypt/FLE2InsertUpdatePayload.json} +1 -1
  125. data/ext/libmongocrypt/libmongocrypt/test/data/explicit-decrypt/FLE2InsertUpdatePayloadV2.json +8 -0
  126. data/ext/libmongocrypt/libmongocrypt/test/data/explicit-decrypt/FLE2RangeIndexedValueV2.json +8 -0
  127. data/ext/libmongocrypt/libmongocrypt/test/data/explicit-decrypt/FLE2UnindexedEncryptedValue.json +8 -0
  128. data/ext/libmongocrypt/libmongocrypt/test/data/explicit-decrypt/FLE2UnindexedEncryptedValueV2.json +8 -0
  129. data/ext/libmongocrypt/libmongocrypt/test/data/find-with-encryptionInformation.json +0 -1
  130. data/ext/libmongocrypt/libmongocrypt/test/data/fle1-explain/with-csfle/collinfo.json +2 -1
  131. data/ext/libmongocrypt/libmongocrypt/test/data/fle1-explain/with-mongocryptd/collinfo.json +2 -1
  132. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-bad-str-encode-version/bad-collinfo.json +26 -0
  133. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-bad-str-encode-version/bad-create-cmd-mongocryptd-reply.json +51 -0
  134. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-bad-str-encode-version/bad-create-cmd-to-mongocryptd.json +45 -0
  135. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-bad-str-encode-version/bad-create-cmd.json +18 -0
  136. data/ext/libmongocrypt/libmongocrypt/test/data/{fle2-find-range/int32/encrypted-field-map.json → fle2-bad-str-encode-version/bad-encrypted-field-config-map.json} +7 -12
  137. data/ext/libmongocrypt/libmongocrypt/test/data/{fle2-insert → fle2-bad-str-encode-version}/encrypted-payload.json +4 -4
  138. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-create/cmd-to-mongocryptd.json +1 -2
  139. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-create/encrypted-field-config-map.json +1 -2
  140. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-create-encrypted-collection/cmd-to-mongocryptd.json +44 -0
  141. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-create-encrypted-collection/cmd.json +17 -0
  142. data/ext/libmongocrypt/libmongocrypt/test/data/{fle2-find-equality/encrypted-field-map.json → fle2-create-encrypted-collection/encrypted-field-config-map.json} +9 -8
  143. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-create-encrypted-collection/encrypted-payload.json +17 -0
  144. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-create-encrypted-collection/mongocryptd-reply.json +50 -0
  145. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-create-encrypted-collection-encrypted-fields-unset-str-encode-version/cmd-to-mongocryptd.json +45 -0
  146. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-create-encrypted-collection-encrypted-fields-unset-str-encode-version/mongocryptd-reply.json +51 -0
  147. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-create-encrypted-collection-with-str-encode-version/cmd-to-mongocryptd.json +46 -0
  148. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-create-encrypted-collection-with-str-encode-version/cmd.json +18 -0
  149. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-create-encrypted-collection-with-str-encode-version/encrypted-field-config-map.json +25 -0
  150. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-create-encrypted-collection-with-str-encode-version/encrypted-payload.json +18 -0
  151. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-create-encrypted-collection-with-str-encode-version/mongocryptd-reply.json +52 -0
  152. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-delete/empty/collinfo.json +1 -1
  153. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-delete/empty/encrypted-field-config-map.json +0 -1
  154. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-delete/empty/encrypted-payload-v2.json +57 -59
  155. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-delete/empty/mongocryptd-reply.json +63 -64
  156. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-delete/success/collinfo.json +1 -1
  157. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-delete/success/encrypted-field-config-map.json +0 -1
  158. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-delete/success/encrypted-payload-v2.json +64 -66
  159. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-delete/success/mongocryptd-reply.json +69 -70
  160. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-explain/with-csfle/collinfo.json +1 -1
  161. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-explain/with-csfle/encrypted-payload.json +1 -2
  162. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-explain/with-mongocryptd/cmd-to-mongocryptd.json +1 -2
  163. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-explain/with-mongocryptd/collinfo.json +2 -2
  164. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-explain/with-mongocryptd/encrypted-payload.json +2 -3
  165. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-explain/with-mongocryptd/mongocryptd-reply.json +1 -2
  166. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-explicit/cmd-to-mongocryptd.json +0 -1
  167. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-explicit/cmd-to-mongod.json +0 -1
  168. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-explicit/reply-from-mongocryptd.json +0 -1
  169. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int32/encrypted-field-map.json +0 -1
  170. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-text-search/cmd.json +9 -0
  171. data/ext/libmongocrypt/libmongocrypt/test/data/{fle2-find-range/date → fle2-insert-text-search}/encrypted-field-map.json +10 -9
  172. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-text-search/encrypted-payload.json +47 -0
  173. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-text-search/mongocryptd-reply.json +55 -0
  174. data/ext/libmongocrypt/libmongocrypt/test/data/{fle2-find-range/double → fle2-insert-text-search-with-str-encode-version}/encrypted-field-map.json +12 -10
  175. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-text-search-with-str-encode-version/encrypted-payload.json +47 -0
  176. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-text-search-with-str-encode-version/mongocryptd-reply.json +55 -0
  177. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-v2-with-str-encode-version/cmd.json +9 -0
  178. data/ext/libmongocrypt/libmongocrypt/test/data/{fle2-insert → fle2-insert-v2-with-str-encode-version}/encrypted-field-map.json +2 -2
  179. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-v2-with-str-encode-version/encrypted-payload.json +40 -0
  180. data/ext/libmongocrypt/libmongocrypt/test/data/{fle2-insert → fle2-insert-v2-with-str-encode-version}/mongocryptd-reply.json +2 -2
  181. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-text-search-create-encrypted-collection/cmd-to-mongocryptd.json +55 -0
  182. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-text-search-create-encrypted-collection/cmd.json +22 -0
  183. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-text-search-create-encrypted-collection/encrypted-field-config-map.json +29 -0
  184. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-text-search-create-encrypted-collection/encrypted-payload.json +23 -0
  185. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-text-search-create-encrypted-collection/mongocryptd-reply.json +61 -0
  186. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-text-search-create-encrypted-collection-with-str-encode-version/cmd-to-mongocryptd.json +56 -0
  187. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-text-search-create-encrypted-collection-with-str-encode-version/cmd.json +23 -0
  188. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-text-search-create-encrypted-collection-with-str-encode-version/encrypted-field-config-map.json +30 -0
  189. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-text-search-create-encrypted-collection-with-str-encode-version/encrypted-payload.json +23 -0
  190. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-text-search-create-encrypted-collection-with-str-encode-version/mongocryptd-reply.json +62 -0
  191. data/ext/libmongocrypt/libmongocrypt/test/data/iev-v2/FLECrudTest-insertOneText.json +20 -0
  192. data/ext/libmongocrypt/libmongocrypt/test/data/iev-v2/FLECrudTest-insertOneTextLarge.json +930 -0
  193. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/csfle/cmd-to-mongocryptd.json +60 -0
  194. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/csfle/cmd.json +14 -0
  195. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/csfle/collInfo-c1.json +39 -0
  196. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/csfle/collInfo-c2.json +39 -0
  197. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/csfle-facet/cmd.json +20 -0
  198. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/csfle-mismatch/cmd.json +14 -0
  199. data/ext/libmongocrypt/libmongocrypt/{bindings/java/mongocrypt/src/test/resources/collection-info.json → test/data/lookup/csfle-mismatch/collInfo-c1.json} +13 -11
  200. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/csfle-mismatch/collInfo-c3.json +39 -0
  201. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/csfle-nested/cmd.json +24 -0
  202. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/csfle-only-schemaMap/cmd-to-mongocryptd.json +60 -0
  203. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/csfle-only-schemaMap/cmd.json +14 -0
  204. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/csfle-only-schemaMap/schemaMap.json +40 -0
  205. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/csfle-schemaMap/cmd-to-mongocryptd.json +60 -0
  206. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/csfle-schemaMap/cmd.json +14 -0
  207. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/csfle-schemaMap/collInfo-c1.json +39 -0
  208. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/csfle-schemaMap/schemaMap.json +21 -0
  209. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/csfle-self/cmd-to-mongocryptd.json +34 -0
  210. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/csfle-self/cmd.json +14 -0
  211. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/csfle-self/collInfo-c1.json +39 -0
  212. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/csfle-sibling/cmd-to-mongocryptd.json +49 -0
  213. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/csfle-sibling/cmd.json +14 -0
  214. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/csfle-sibling/collInfo-c1.json +39 -0
  215. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/csfle-sibling/collInfo-c2.json +29 -0
  216. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/csfle-sibling/reply-from-mongocryptd.json +18 -0
  217. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/csfle-unionWith/cmd.json +21 -0
  218. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/csfle-view/cmd.json +14 -0
  219. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/csfle-view/collInfo-c1.json +39 -0
  220. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/csfle-view/collInfo-v1.json +11 -0
  221. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/csfle/csfle/cmd-to-mongocryptd.json +65 -0
  222. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/csfle/csfle/cmd-to-mongod.json +26 -0
  223. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/csfle/csfle/cmd.json +19 -0
  224. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/csfle/csfle/collInfo-c1.json +39 -0
  225. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/csfle/csfle/collInfo-c2.json +39 -0
  226. data/ext/libmongocrypt/libmongocrypt/{bindings/java/mongocrypt/src/test/resources/keys/ABCDEFAB123498761234123456789012-local-document.json → test/data/lookup/mixed/csfle/csfle/key-doc.json} +4 -4
  227. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/csfle/csfle/reply-from-mongocryptd.json +33 -0
  228. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/csfle/no-schema/cmd-to-mongocryptd.json +47 -0
  229. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/csfle/no-schema/cmd-to-mongod.json +26 -0
  230. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/csfle/no-schema/cmd.json +19 -0
  231. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/csfle/no-schema/collInfo-c1.json +39 -0
  232. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/csfle/no-schema/collInfo-c2.json +17 -0
  233. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/csfle/no-schema/key-doc.json +30 -0
  234. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/csfle/no-schema/reply-from-mongocryptd.json +33 -0
  235. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/csfle/qe/cmd-to-mongocryptd.json +70 -0
  236. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/csfle/qe/cmd.json +19 -0
  237. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/csfle/qe/collInfo-c1.json +39 -0
  238. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/csfle/qe/collInfo-c2.json +42 -0
  239. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/no-schema/csfle/cmd-to-mongocryptd.json +47 -0
  240. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/no-schema/csfle/cmd-to-mongod.json +26 -0
  241. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/no-schema/csfle/cmd.json +19 -0
  242. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/no-schema/csfle/collInfo-c1.json +17 -0
  243. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/no-schema/csfle/collInfo-c2.json +39 -0
  244. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/no-schema/csfle/key-doc.json +30 -0
  245. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/no-schema/csfle/reply-from-mongocryptd.json +33 -0
  246. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/no-schema/no-schema/cmd-to-mongocryptd.json +29 -0
  247. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/no-schema/no-schema/cmd-to-mongod.json +19 -0
  248. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/no-schema/no-schema/cmd.json +19 -0
  249. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/no-schema/no-schema/collInfo-c1.json +17 -0
  250. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/no-schema/no-schema/collInfo-c2.json +17 -0
  251. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/no-schema/no-schema/reply-from-mongocryptd.json +26 -0
  252. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/no-schema/qe/cmd-to-mongocryptd.json +53 -0
  253. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/no-schema/qe/cmd-to-mongod.json +58 -0
  254. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/no-schema/qe/cmd.json +19 -0
  255. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/no-schema/qe/collInfo-c1.json +17 -0
  256. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/no-schema/qe/collInfo-c2.json +42 -0
  257. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/no-schema/qe/key-doc.json +30 -0
  258. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/no-schema/qe/reply-from-mongocryptd.json +65 -0
  259. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/qe/csfle/cmd-to-mongocryptd.json +70 -0
  260. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/qe/csfle/cmd.json +19 -0
  261. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/qe/csfle/collInfo-c1.json +42 -0
  262. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/qe/csfle/collInfo-c2.json +39 -0
  263. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/qe/no-schema/cmd-to-mongocryptd.json +53 -0
  264. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/qe/no-schema/cmd-to-mongod.json +56 -0
  265. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/qe/no-schema/cmd.json +19 -0
  266. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/qe/no-schema/collInfo-c1.json +42 -0
  267. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/qe/no-schema/collInfo-c2.json +17 -0
  268. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/qe/no-schema/key-doc.json +30 -0
  269. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/qe/no-schema/reply-from-mongocryptd.json +63 -0
  270. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/qe/qe/cmd-to-mongocryptd.json +66 -0
  271. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/qe/qe/cmd-to-mongod.json +71 -0
  272. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/qe/qe/cmd.json +19 -0
  273. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/qe/qe/collInfo-c1.json +42 -0
  274. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/qe/qe/collInfo-c2.json +42 -0
  275. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/qe/qe/key-doc.json +30 -0
  276. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/mixed/qe/qe/reply-from-mongocryptd.json +78 -0
  277. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/qe/cmd-to-mongocryptd.json +61 -0
  278. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/qe/cmd-to-mongod.json +14 -0
  279. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/qe/cmd.json +14 -0
  280. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/qe/collInfo-c1.json +42 -0
  281. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/qe/collInfo-c2.json +42 -0
  282. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/qe/reply-from-mongocryptd.json +68 -0
  283. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/qe-encryptedFieldsMap/cmd-to-mongocryptd.json +66 -0
  284. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/qe-encryptedFieldsMap/cmd-to-mongod.json +71 -0
  285. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/qe-encryptedFieldsMap/cmd.json +19 -0
  286. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/qe-encryptedFieldsMap/collInfo-c1.json +42 -0
  287. data/ext/libmongocrypt/libmongocrypt/test/data/{fle2-insert-unindexed/encrypted-field-map.json → lookup/qe-encryptedFieldsMap/encryptedFieldsMap.json} +6 -7
  288. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/qe-encryptedFieldsMap/key-doc.json +30 -0
  289. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/qe-encryptedFieldsMap/reply-from-mongocryptd.json +78 -0
  290. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/qe-self/cmd-to-mongocryptd.json +46 -0
  291. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/qe-self/cmd-to-mongod.json +53 -0
  292. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/qe-self/cmd.json +19 -0
  293. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/qe-self/collInfo-c1.json +42 -0
  294. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/qe-self/key-doc.json +30 -0
  295. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/qe-self/reply-from-mongocryptd.json +58 -0
  296. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/qe-with-payload/cmd-to-mongocryptd.json +66 -0
  297. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/qe-with-payload/cmd-to-mongod.json +75 -0
  298. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/qe-with-payload/cmd.json +19 -0
  299. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/qe-with-payload/collInfo-c1.json +42 -0
  300. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/qe-with-payload/collInfo-c2.json +42 -0
  301. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/qe-with-payload/key-doc.json +30 -0
  302. data/ext/libmongocrypt/libmongocrypt/test/data/lookup/qe-with-payload/reply-from-mongocryptd.json +78 -0
  303. data/ext/libmongocrypt/libmongocrypt/test/data/{fle2-create/mongocryptd-ismaster.json → mongocryptd-ismaster-17.json} +1 -1
  304. data/ext/libmongocrypt/libmongocrypt/test/data/mongocryptd-ismaster-26.json +12 -0
  305. data/ext/libmongocrypt/libmongocrypt/test/data/schema-broker/collinfo-encryptedFields.json +42 -0
  306. data/ext/libmongocrypt/libmongocrypt/test/data/schema-broker/collinfo-encryptedFields2.json +42 -0
  307. data/ext/libmongocrypt/libmongocrypt/test/data/schema-broker/collinfo-jsonSchema.json +43 -0
  308. data/ext/libmongocrypt/libmongocrypt/test/data/schema-broker/collinfo-noSchema.json +21 -0
  309. data/ext/libmongocrypt/libmongocrypt/test/data/schema-broker/create-with-jsonSchema.json +24 -0
  310. data/ext/libmongocrypt/libmongocrypt/test/data/schema-broker/encryptedFields.json +20 -0
  311. data/ext/libmongocrypt/libmongocrypt/test/data/schema-broker/encryptedFields2.json +20 -0
  312. data/ext/libmongocrypt/libmongocrypt/test/data/schema-broker/encryptedFieldsMap.json +42 -0
  313. data/ext/libmongocrypt/libmongocrypt/test/data/schema-broker/jsonSchema.json +19 -0
  314. data/ext/libmongocrypt/libmongocrypt/test/data/schema-broker/jsonSchema2.json +19 -0
  315. data/ext/libmongocrypt/libmongocrypt/test/data/schema-broker/schemaMap.json +40 -0
  316. data/ext/libmongocrypt/libmongocrypt/test/data/tokens/mc.json +28 -2
  317. data/ext/libmongocrypt/libmongocrypt/test/data/tokens/server.json +28 -2
  318. data/ext/libmongocrypt/libmongocrypt/test/test-mc-efc.c +70 -0
  319. data/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-encryption-placeholder.c +468 -0
  320. data/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-find-equality-payload-v2.c +20 -1
  321. data/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-payload-iev-v2.c +286 -24
  322. data/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-payload-iev.c +1 -1
  323. data/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-payload-iup-v2.c +23 -1
  324. data/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-payload-iup.c +24 -1
  325. data/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-payload-uev.c +2 -2
  326. data/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-rfds.c +2 -2
  327. data/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-tag-and-encrypted-metadata-block.c +36 -1
  328. data/ext/libmongocrypt/libmongocrypt/test/test-mc-range-edge-generation.c +6 -7
  329. data/ext/libmongocrypt/libmongocrypt/test/test-mc-range-encoding.c +32 -33
  330. data/ext/libmongocrypt/libmongocrypt/test/test-mc-range-mincover.c +58 -66
  331. data/ext/libmongocrypt/libmongocrypt/test/test-mc-rangeopts.c +2 -2
  332. data/ext/libmongocrypt/libmongocrypt/test/test-mc-schema-broker.c +1124 -0
  333. data/ext/libmongocrypt/libmongocrypt/test/test-mc-text-search-str-encode.c +1207 -0
  334. data/ext/libmongocrypt/libmongocrypt/test/test-mc-tokens.c +144 -37
  335. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-assert-match-bson.c +13 -14
  336. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-assert.h +21 -4
  337. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-buffer.c +25 -0
  338. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-cache.c +3 -2
  339. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-crypto-hooks.c +1 -1
  340. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-crypto.c +37 -7
  341. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-csfle-lib.c +21 -0
  342. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-ctx-decrypt.c +226 -146
  343. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-ctx-encrypt.c +1330 -1200
  344. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-kek.c +1 -1
  345. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-key-cache.c +6 -6
  346. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-kms-responses.c +2 -2
  347. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-marking.c +744 -106
  348. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt.c +119 -33
  349. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt.h +27 -4
  350. data/ext/libmongocrypt/libmongocrypt/test/test-unicode-fold.c +97 -0
  351. data/lib/libmongocrypt_helper/version.rb +2 -2
  352. metadata +207 -157
  353. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/README.md +0 -36
  354. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/benchmarks/build.gradle.kts +0 -28
  355. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/benchmarks/src/main/java/com/mongodb/crypt/benchmark/BenchmarkRunner.java +0 -217
  356. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/benchmarks/src/main/resources/keyDocument.json +0 -24
  357. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/build.gradle.kts +0 -354
  358. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/gradle/wrapper/gradle-wrapper.jar +0 -0
  359. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/gradle/wrapper/gradle-wrapper.properties +0 -5
  360. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/gradlew +0 -234
  361. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/gradlew.bat +0 -89
  362. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/settings.gradle.kts +0 -1
  363. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/BinaryHolder.java +0 -45
  364. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/CAPI.java +0 -1165
  365. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/CAPIHelper.java +0 -96
  366. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/CipherCallback.java +0 -92
  367. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/DisposableMemory.java +0 -31
  368. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/JULLogger.java +0 -130
  369. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/Logger.java +0 -144
  370. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/Loggers.java +0 -50
  371. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/MacCallback.java +0 -60
  372. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/MessageDigestCallback.java +0 -55
  373. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/MongoAwsKmsProviderOptions.java +0 -104
  374. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/MongoCrypt.java +0 -100
  375. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/MongoCryptContext.java +0 -137
  376. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/MongoCryptContextImpl.java +0 -164
  377. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/MongoCryptException.java +0 -67
  378. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/MongoCryptImpl.java +0 -423
  379. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/MongoCryptOptions.java +0 -284
  380. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/MongoCrypts.java +0 -38
  381. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/MongoDataKeyOptions.java +0 -125
  382. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/MongoExplicitEncryptOptions.java +0 -227
  383. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/MongoKeyDecryptor.java +0 -76
  384. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/MongoKeyDecryptorImpl.java +0 -105
  385. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/MongoLocalKmsProviderOptions.java +0 -83
  386. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/MongoRewrapManyDataKeyOptions.java +0 -104
  387. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/SLF4JLogger.java +0 -110
  388. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/SecureRandomCallback.java +0 -51
  389. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/SigningRSAESPKCSCallback.java +0 -76
  390. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/package-info.java +0 -18
  391. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/resources/META-INF/native-image/jni-config.json +0 -180
  392. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/resources/META-INF/native-image/reflect-config.json +0 -134
  393. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/test/java/com/mongodb/crypt/capi/MongoCryptTest.java +0 -389
  394. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/test/resources/command-reply.json +0 -13
  395. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/test/resources/command.json +0 -6
  396. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/test/resources/encrypted-command-reply.json +0 -16
  397. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/test/resources/encrypted-command.json +0 -11
  398. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/test/resources/encrypted-value.json +0 -6
  399. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/test/resources/fle2-find-range-explicit-v2/int32/encrypted-payload.json +0 -26
  400. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/test/resources/fle2-find-range-explicit-v2/int32/key-filter.json +0 -19
  401. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/test/resources/fle2-find-range-explicit-v2/int32/rangeopts.json +0 -14
  402. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/test/resources/fle2-find-range-explicit-v2/int32/value-to-encrypt.json +0 -20
  403. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/test/resources/json-schema.json +0 -15
  404. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/test/resources/key-document.json +0 -36
  405. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/test/resources/key-filter-keyAltName.json +0 -14
  406. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/test/resources/key-filter.json +0 -19
  407. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/test/resources/kms-reply.txt +0 -6
  408. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/test/resources/list-collections-filter.json +0 -3
  409. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/test/resources/mongocryptd-command.json +0 -22
  410. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/test/resources/mongocryptd-reply.json +0 -18
  411. data/ext/libmongocrypt/libmongocrypt/etc/silk-create-asset-group.sh +0 -70
  412. data/ext/libmongocrypt/libmongocrypt/test/data/bulkWrite/jsonSchema/cmd.json +0 -20
  413. data/ext/libmongocrypt/libmongocrypt/test/data/collection-info-no-schema.json +0 -19
  414. data/ext/libmongocrypt/libmongocrypt/test/data/compact/no-range/encrypted-field-config-map.json +0 -47
  415. data/ext/libmongocrypt/libmongocrypt/test/data/fle1-collMod/insert/cmd.json +0 -8
  416. data/ext/libmongocrypt/libmongocrypt/test/data/fle1-collMod/insert/collinfo.json +0 -9
  417. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-create/ismaster-to-mongocryptd.json +0 -3
  418. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-delete/empty/encrypted-payload.json +0 -91
  419. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-delete/success/encrypted-payload.json +0 -98
  420. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-explicit/find-indexed-contentionFactor1.json +0 -8
  421. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-explicit/insert-indexed-contentionFactor1.json +0 -8
  422. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-explicit/insert-indexed-same-user-and-index-key.json +0 -8
  423. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-equality/cmd.json +0 -6
  424. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-equality/encrypted-payload.json +0 -41
  425. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-equality/mongocryptd-reply.json +0 -19
  426. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/date/cmd.json +0 -10
  427. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/date/encrypted-payload.json +0 -42
  428. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/date/mongocryptd-reply.json +0 -50
  429. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128/cmd.json +0 -6
  430. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128/encrypted-field-map.json +0 -28
  431. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128/encrypted-payload.json +0 -42
  432. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128/mongocryptd-reply.json +0 -50
  433. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128-precision/cmd.json +0 -6
  434. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128-precision/encrypted-field-map.json +0 -31
  435. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128-precision/encrypted-payload.json +0 -51
  436. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/decimal128-precision/mongocryptd-reply.json +0 -59
  437. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/double/cmd.json +0 -8
  438. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/double/encrypted-payload.json +0 -42
  439. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/double/mongocryptd-reply.json +0 -50
  440. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/double-precision/cmd.json +0 -8
  441. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/double-precision/encrypted-field-map.json +0 -31
  442. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/double-precision/encrypted-payload.json +0 -45
  443. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/double-precision/mongocryptd-reply.json +0 -53
  444. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int32/cmd.json +0 -8
  445. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int32/encrypted-payload.json +0 -42
  446. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int32/mongocryptd-reply.json +0 -50
  447. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int64/cmd.json +0 -8
  448. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int64/encrypted-field-map.json +0 -28
  449. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int64/encrypted-payload.json +0 -42
  450. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range/int64/mongocryptd-reply.json +0 -50
  451. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range-explicit/double/encrypted-payload.json +0 -26
  452. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range-explicit/double-precision/encrypted-payload.json +0 -26
  453. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range-explicit/int32/encrypted-payload.json +0 -26
  454. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range-explicit/int32-nominmax/encrypted-payload-v2.json +0 -26
  455. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-find-range-explicit/int32-openinterval/encrypted-payload.json +0 -16
  456. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/date/cmd.json +0 -13
  457. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/date/encrypted-field-map.json +0 -28
  458. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/date/encrypted-payload.json +0 -45
  459. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/date/mongocryptd-reply.json +0 -53
  460. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128/cmd.json +0 -9
  461. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128/encrypted-field-map.json +0 -28
  462. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128/encrypted-payload.json +0 -45
  463. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128/mongocryptd-reply.json +0 -53
  464. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128-precision/cmd.json +0 -9
  465. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128-precision/encrypted-field-map.json +0 -31
  466. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128-precision/encrypted-payload.json +0 -54
  467. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/decimal128-precision/mongocryptd-reply.json +0 -62
  468. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/double/cmd.json +0 -11
  469. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/double/encrypted-field-map.json +0 -28
  470. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/double/encrypted-payload.json +0 -45
  471. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/double/mongocryptd-reply.json +0 -53
  472. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/double-precision/cmd.json +0 -11
  473. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/double-precision/encrypted-field-map.json +0 -31
  474. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/double-precision/encrypted-payload.json +0 -48
  475. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/double-precision/mongocryptd-reply.json +0 -56
  476. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int32/encrypted-payload.json +0 -45
  477. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int32/mongocryptd-reply.json +0 -53
  478. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int64/cmd.json +0 -11
  479. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int64/encrypted-field-map.json +0 -28
  480. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int64/encrypted-payload.json +0 -45
  481. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range/int64/mongocryptd-reply.json +0 -53
  482. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range-explicit/double/encrypted-payload.json +0 -8
  483. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range-explicit/double-precision/encrypted-payload.json +0 -8
  484. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range-explicit/int32-nominmax/encrypted-payload-v2.json +0 -8
  485. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-range-explicit/sparsity-2/encrypted-payload.json +0 -8
  486. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-unindexed/cmd.json +0 -9
  487. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-unindexed/encrypted-payload.json +0 -14
  488. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-insert-unindexed/mongocryptd-reply.json +0 -46
  489. data/ext/libmongocrypt/libmongocrypt/test/data/schema.json +0 -19
  490. /data/ext/libmongocrypt/libmongocrypt/test/data/{fle2-explicit/find-indexed.json → explicit-decrypt/FLE2FindEqualityPayload.json} +0 -0
  491. /data/ext/libmongocrypt/libmongocrypt/test/data/{fle2-insert → fle2-insert-text-search-with-str-encode-version}/cmd.json +0 -0
@@ -22,476 +22,30 @@
22
22
  #include "mongocrypt-ctx-private.h"
23
23
  #include "mongocrypt-key-broker-private.h"
24
24
  #include "mongocrypt-marking-private.h"
25
+ #include "mongocrypt-private.h"
25
26
  #include "mongocrypt-traverse-util-private.h"
26
27
  #include "mongocrypt-util-private.h" // mc_iter_document_as_bson
27
28
  #include "mongocrypt.h"
28
29
 
29
- /* _fle2_append_encryptedFieldConfig copies encryptedFieldConfig and applies
30
- * default state collection names for escCollection, eccCollection, and
31
- * ecocCollection if required. */
32
- static bool _fle2_append_encryptedFieldConfig(const mongocrypt_ctx_t *ctx,
33
- bson_t *dst,
34
- bson_t *encryptedFieldConfig,
35
- const char *target_coll,
36
- mongocrypt_status_t *status) {
37
- bson_iter_t iter;
38
- bool has_escCollection = false;
39
- bool has_eccCollection = false;
40
- bool has_ecocCollection = false;
41
-
42
- BSON_ASSERT_PARAM(dst);
43
- BSON_ASSERT_PARAM(encryptedFieldConfig);
44
- BSON_ASSERT_PARAM(target_coll);
45
-
46
- if (!bson_iter_init(&iter, encryptedFieldConfig)) {
47
- CLIENT_ERR("unable to iterate encryptedFieldConfig");
48
- return false;
49
- }
50
-
51
- while (bson_iter_next(&iter)) {
52
- if (strcmp(bson_iter_key(&iter), "escCollection") == 0) {
53
- has_escCollection = true;
54
- }
55
- if (strcmp(bson_iter_key(&iter), "eccCollection") == 0) {
56
- has_eccCollection = true;
57
- }
58
- if (strcmp(bson_iter_key(&iter), "ecocCollection") == 0) {
59
- has_ecocCollection = true;
60
- }
61
- if (!BSON_APPEND_VALUE(dst, bson_iter_key(&iter), bson_iter_value(&iter))) {
62
- CLIENT_ERR("unable to append field: %s", bson_iter_key(&iter));
63
- return false;
64
- }
65
- }
66
-
67
- if (!has_escCollection) {
68
- char *default_escCollection = bson_strdup_printf("enxcol_.%s.esc", target_coll);
69
- if (!BSON_APPEND_UTF8(dst, "escCollection", default_escCollection)) {
70
- CLIENT_ERR("unable to append escCollection");
71
- bson_free(default_escCollection);
72
- return false;
73
- }
74
- bson_free(default_escCollection);
75
- }
76
- if (!has_eccCollection && !ctx->crypt->opts.use_fle2_v2) {
77
- char *default_eccCollection = bson_strdup_printf("enxcol_.%s.ecc", target_coll);
78
- if (!BSON_APPEND_UTF8(dst, "eccCollection", default_eccCollection)) {
79
- CLIENT_ERR("unable to append eccCollection");
80
- bson_free(default_eccCollection);
81
- return false;
82
- }
83
- bson_free(default_eccCollection);
84
- }
85
- if (!has_ecocCollection) {
86
- char *default_ecocCollection = bson_strdup_printf("enxcol_.%s.ecoc", target_coll);
87
- if (!BSON_APPEND_UTF8(dst, "ecocCollection", default_ecocCollection)) {
88
- CLIENT_ERR("unable to append ecocCollection");
89
- bson_free(default_ecocCollection);
90
- return false;
91
- }
92
- bson_free(default_ecocCollection);
93
- }
94
- return true;
95
- }
96
-
97
- static bool _fle2_append_encryptionInformation(const mongocrypt_ctx_t *ctx,
98
- bson_t *dst,
99
- const char *target_ns,
100
- bson_t *encryptedFieldConfig,
101
- bson_t *deleteTokens,
102
- const char *target_coll,
103
- mongocrypt_status_t *status) {
104
- bson_t encryption_information_bson;
105
- bson_t schema_bson;
106
- bson_t encrypted_field_config_bson;
107
-
108
- BSON_ASSERT_PARAM(dst);
109
- BSON_ASSERT_PARAM(target_ns);
110
- BSON_ASSERT_PARAM(encryptedFieldConfig);
111
- /* deleteTokens may be NULL */
112
- BSON_ASSERT_PARAM(target_coll);
113
-
114
- if (!BSON_APPEND_DOCUMENT_BEGIN(dst, "encryptionInformation", &encryption_information_bson)) {
115
- CLIENT_ERR("unable to begin appending 'encryptionInformation'");
116
- return false;
117
- }
118
- if (!BSON_APPEND_INT32(&encryption_information_bson, "type", 1)) {
119
- CLIENT_ERR("unable to append type to 'encryptionInformation'");
120
- return false;
121
- }
122
- if (!BSON_APPEND_DOCUMENT_BEGIN(&encryption_information_bson, "schema", &schema_bson)) {
123
- CLIENT_ERR("unable to begin appending 'schema' to 'encryptionInformation'");
124
- return false;
125
- }
126
-
127
- if (!BSON_APPEND_DOCUMENT_BEGIN(&schema_bson, target_ns, &encrypted_field_config_bson)) {
128
- CLIENT_ERR("unable to begin appending 'encryptedFieldConfig' to "
129
- "'encryptionInformation'.'schema'");
130
- return false;
131
- }
132
-
133
- if (!_fle2_append_encryptedFieldConfig(ctx,
134
- &encrypted_field_config_bson,
135
- encryptedFieldConfig,
136
- target_coll,
137
- status)) {
138
- return false;
139
- }
140
-
141
- if (!bson_append_document_end(&schema_bson, &encrypted_field_config_bson)) {
142
- CLIENT_ERR("unable to end appending 'encryptedFieldConfig' to "
143
- "'encryptionInformation'.'schema'");
144
- return false;
145
- }
146
- if (!bson_append_document_end(&encryption_information_bson, &schema_bson)) {
147
- CLIENT_ERR("unable to end appending 'schema' to 'encryptionInformation'");
148
- return false;
149
- }
150
-
151
- if (deleteTokens != NULL) {
152
- bson_t delete_tokens_bson;
153
- if (!BSON_APPEND_DOCUMENT_BEGIN(&encryption_information_bson, "deleteTokens", &delete_tokens_bson)) {
154
- CLIENT_ERR("unable to begin appending 'deleteTokens' to "
155
- "'encryptionInformation'");
156
- return false;
157
- }
158
- if (!BSON_APPEND_DOCUMENT(&delete_tokens_bson, target_ns, deleteTokens)) {
159
- CLIENT_ERR("unable to append '%s' to 'deleteTokens'", target_ns);
160
- return false;
161
- }
162
- if (!bson_append_document_end(&encryption_information_bson, &delete_tokens_bson)) {
163
- CLIENT_ERR("unable to end appending 'deleteTokens' to "
164
- "'encryptionInformation'");
165
- return false;
166
- }
167
- }
168
-
169
- if (!bson_append_document_end(dst, &encryption_information_bson)) {
170
- CLIENT_ERR("unable to end appending 'encryptionInformation'");
171
- return false;
172
- }
173
- return true;
174
- }
175
-
176
- typedef enum { MC_TO_CSFLE, MC_TO_MONGOCRYPTD, MC_TO_MONGOD } mc_cmd_target_t;
177
-
178
- /**
179
- * @brief Add "encryptionInformation" to a command.
180
- *
181
- * @param cmd_name The name of the command.
182
- * @param cmd The command being rewritten. It is an input and output.
183
- * @param target_ns The <db>.<collection> namespace for the command.
184
- * @param encryptedFieldConfig The "encryptedFields" document for the
185
- * collection.
186
- * @param deleteTokens Delete tokens to append to "encryptionInformation". May
187
- * be NULL.
188
- * @param target_coll The collection name.
189
- * @param cmd_target The intended destination of the command. csfle,
190
- * mongocryptd, and mongod have different requirements for the location of
191
- * "encryptionInformation".
192
- * @param status Output status.
193
- * @return true On success
194
- * @return false Otherwise. Sets a failing status message in this case.
195
- */
196
- static bool _fle2_insert_encryptionInformation(const mongocrypt_ctx_t *ctx,
197
- const char *cmd_name,
198
- bson_t *cmd /* in and out */,
199
- const char *target_ns,
200
- bson_t *encryptedFieldConfig,
201
- bson_t *deleteTokens,
202
- const char *target_coll,
203
- mc_cmd_target_t cmd_target,
204
- mongocrypt_status_t *status) {
205
- bson_t out = BSON_INITIALIZER;
206
- bson_t explain = BSON_INITIALIZER;
207
- bson_iter_t iter;
208
- bool ok = false;
209
-
210
- BSON_ASSERT_PARAM(cmd_name);
211
- BSON_ASSERT_PARAM(cmd);
212
- BSON_ASSERT_PARAM(target_ns);
213
- BSON_ASSERT_PARAM(encryptedFieldConfig);
214
- /* deleteTokens may be NULL */
215
- BSON_ASSERT_PARAM(target_coll);
216
-
217
- // For `bulkWrite`, append `encryptionInformation` inside the `nsInfo.0` document.
218
- if (0 == strcmp(cmd_name, "bulkWrite")) {
219
- // Get the single `nsInfo` document from the input command.
220
- bson_t nsInfo; // Non-owning.
221
- {
222
- bson_iter_t nsInfo_iter;
223
- if (!bson_iter_init(&nsInfo_iter, cmd)) {
224
- CLIENT_ERR("failed to iterate command");
225
- goto fail;
226
- }
227
- if (!bson_iter_find_descendant(&nsInfo_iter, "nsInfo.0", &nsInfo_iter)) {
228
- CLIENT_ERR("expected one namespace in `bulkWrite`, but found zero.");
229
- goto fail;
230
- }
231
- if (bson_has_field(cmd, "nsInfo.1")) {
232
- CLIENT_ERR(
233
- "expected one namespace in `bulkWrite`, but found more than one. Only one namespace is supported.");
234
- goto fail;
235
- }
236
- if (!mc_iter_document_as_bson(&nsInfo_iter, &nsInfo, status)) {
237
- goto fail;
238
- }
239
- // Ensure `nsInfo` does not already have an `encryptionInformation` field.
240
- if (bson_has_field(&nsInfo, "encryptionInformation")) {
241
- CLIENT_ERR("unexpected `encryptionInformation` present in input `nsInfo`.");
242
- goto fail;
243
- }
244
- }
245
-
246
- // Copy input and append `encryptionInformation` to `nsInfo`.
247
- {
248
- // Append everything from input except `nsInfo`.
249
- bson_copy_to_excluding_noinit(cmd, &out, "nsInfo", NULL);
250
- // Append `nsInfo` array.
251
- bson_t nsInfo_array;
252
- if (!BSON_APPEND_ARRAY_BEGIN(&out, "nsInfo", &nsInfo_array)) {
253
- CLIENT_ERR("unable to begin appending 'nsInfo' array");
254
- goto fail;
255
- }
256
- bson_t nsInfo_array_0;
257
- if (!BSON_APPEND_DOCUMENT_BEGIN(&nsInfo_array, "0", &nsInfo_array_0)) {
258
- CLIENT_ERR("unable to append 'nsInfo.0' document");
259
- goto fail;
260
- }
261
- // Copy everything from input `nsInfo`.
262
- bson_concat(&nsInfo_array_0, &nsInfo);
263
- // And append `encryptionInformation`.
264
- if (!_fle2_append_encryptionInformation(ctx,
265
- &nsInfo_array_0,
266
- target_ns,
267
- encryptedFieldConfig,
268
- deleteTokens,
269
- target_coll,
270
- status)) {
271
- goto fail;
272
- }
273
- if (!bson_append_document_end(&nsInfo_array, &nsInfo_array_0)) {
274
- CLIENT_ERR("unable to end appending 'nsInfo' document in array");
275
- }
276
- if (!bson_append_array_end(&out, &nsInfo_array)) {
277
- CLIENT_ERR("unable to end appending 'nsInfo' array");
278
- goto fail;
279
- }
280
- // Overwrite `cmd`.
281
- bson_destroy(cmd);
282
- if (!bson_steal(cmd, &out)) {
283
- CLIENT_ERR("failed to steal BSON with encryptionInformation");
284
- goto fail;
285
- }
286
- }
287
-
288
- goto success;
289
- }
290
-
291
- if (0 != strcmp(cmd_name, "explain") || cmd_target == MC_TO_MONGOCRYPTD) {
292
- // All commands except "explain" and "bulkWrite" expect "encryptionInformation"
293
- // at top-level. "explain" sent to mongocryptd expects
294
- // "encryptionInformation" at top-level.
295
- if (!_fle2_append_encryptionInformation(ctx,
296
- cmd,
297
- target_ns,
298
- encryptedFieldConfig,
299
- deleteTokens,
300
- target_coll,
301
- status)) {
302
- goto fail;
303
- }
304
- bson_destroy(&out);
305
- goto success;
306
- }
307
-
308
- // The "explain" command for csfle is a special case.
309
- // mongocryptd expects "encryptionInformation" to be a sibling of the
310
- // "explain" document. Example:
311
- // {
312
- // "explain": { "find": "to-mongocryptd" },
313
- // "encryptionInformation": {}
314
- // }
315
- // csfle and mongod expect "encryptionInformation" to be nested in the
316
- // "explain" document. Example:
317
- // {
318
- // "explain": {
319
- // "find": "to-csfle-or-mongod"
320
- // "encryptionInformation": {}
321
- // }
322
- // }
323
- BSON_ASSERT(bson_iter_init_find(&iter, cmd, "explain"));
324
- if (!BSON_ITER_HOLDS_DOCUMENT(&iter)) {
325
- CLIENT_ERR("expected 'explain' to be document");
326
- goto fail;
327
- }
328
-
329
- {
330
- bson_t tmp;
331
- if (!mc_iter_document_as_bson(&iter, &tmp, status)) {
332
- goto fail;
333
- }
334
- bson_destroy(&explain);
335
- bson_copy_to(&tmp, &explain);
336
- }
337
-
338
- if (!_fle2_append_encryptionInformation(ctx,
339
- &explain,
340
- target_ns,
341
- encryptedFieldConfig,
342
- deleteTokens,
343
- target_coll,
344
- status)) {
345
- goto fail;
346
- }
347
-
348
- if (!BSON_APPEND_DOCUMENT(&out, "explain", &explain)) {
349
- CLIENT_ERR("unable to append 'explain' document");
350
- goto fail;
351
- }
352
-
353
- bson_copy_to_excluding_noinit(cmd, &out, "explain", NULL);
354
- bson_destroy(cmd);
355
- if (!bson_steal(cmd, &out)) {
356
- CLIENT_ERR("failed to steal BSON with encryptionInformation");
357
- goto fail;
358
- }
359
-
360
- success:
361
- ok = true;
362
- fail:
363
- bson_destroy(&explain);
364
- if (!ok) {
365
- bson_destroy(&out);
366
- }
367
- return ok;
368
- }
369
-
370
30
  /* Construct the list collections command to send. */
371
31
  static bool _mongo_op_collinfo(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *out) {
372
32
  _mongocrypt_ctx_encrypt_t *ectx;
373
- bson_t *cmd;
374
33
 
375
34
  BSON_ASSERT_PARAM(ctx);
376
35
  BSON_ASSERT_PARAM(out);
377
36
 
378
37
  ectx = (_mongocrypt_ctx_encrypt_t *)ctx;
379
- cmd = BCON_NEW("name", BCON_UTF8(ectx->target_coll));
380
- CRYPT_TRACEF(&ectx->parent.crypt->log, "constructed: %s\n", tmp_json(cmd));
381
- _mongocrypt_buffer_steal_from_bson(&ectx->list_collections_filter, cmd);
38
+ bson_t filter = BSON_INITIALIZER;
39
+ if (!mc_schema_broker_append_listCollections_filter(ectx->sb, &filter, ctx->status)) {
40
+ _mongocrypt_ctx_fail(ctx);
41
+ return false;
42
+ }
43
+ _mongocrypt_buffer_steal_from_bson(&ectx->list_collections_filter, &filter);
382
44
  out->data = ectx->list_collections_filter.data;
383
45
  out->len = ectx->list_collections_filter.len;
384
46
  return true;
385
47
  }
386
48
 
387
- static bool _set_schema_from_collinfo(mongocrypt_ctx_t *ctx, bson_t *collinfo) {
388
- bson_iter_t iter;
389
- _mongocrypt_ctx_encrypt_t *ectx;
390
- bool found_jsonschema = false;
391
-
392
- BSON_ASSERT_PARAM(ctx);
393
- BSON_ASSERT_PARAM(collinfo);
394
-
395
- /* Parse out the schema. */
396
- ectx = (_mongocrypt_ctx_encrypt_t *)ctx;
397
-
398
- /* Disallow views. */
399
- if (bson_iter_init_find(&iter, collinfo, "type") && BSON_ITER_HOLDS_UTF8(&iter) && bson_iter_utf8(&iter, NULL)
400
- && 0 == strcmp("view", bson_iter_utf8(&iter, NULL))) {
401
- return _mongocrypt_ctx_fail_w_msg(ctx, "cannot auto encrypt a view");
402
- }
403
-
404
- if (!bson_iter_init(&iter, collinfo)) {
405
- return _mongocrypt_ctx_fail_w_msg(ctx, "BSON malformed");
406
- }
407
-
408
- if (bson_iter_find_descendant(&iter, "options.encryptedFields", &iter)) {
409
- if (!BSON_ITER_HOLDS_DOCUMENT(&iter)) {
410
- return _mongocrypt_ctx_fail_w_msg(ctx, "options.encryptedFields is not a BSON document");
411
- }
412
- if (!_mongocrypt_buffer_copy_from_document_iter(&ectx->encrypted_field_config, &iter)) {
413
- return _mongocrypt_ctx_fail_w_msg(ctx, "unable to copy options.encryptedFields");
414
- }
415
- bson_t efc_bson;
416
- if (!_mongocrypt_buffer_to_bson(&ectx->encrypted_field_config, &efc_bson)) {
417
- return _mongocrypt_ctx_fail_w_msg(ctx, "unable to create BSON from encrypted_field_config");
418
- }
419
- if (!mc_EncryptedFieldConfig_parse(&ectx->efc, &efc_bson, ctx->status, ctx->crypt->opts.use_range_v2)) {
420
- _mongocrypt_ctx_fail(ctx);
421
- return false;
422
- }
423
- } else if (0 == strcmp(ectx->cmd_name, "bulkWrite")) {
424
- ectx->used_empty_encryptedFields = true;
425
- // `bulkWrite` is a special case. Sending `bulkWrite` with `jsonSchema` to query analysis results in an error:
426
- // `The bulkWrite command only supports Queryable Encryption`
427
- //
428
- // Add an empty encryptedFields (rather than an empty JSON schema) to ensure `bulkWrite` can be sent to query
429
- // analysis.
430
- bson_t empty_encryptedFields = BSON_INITIALIZER;
431
- {
432
- char *escCollection = bson_strdup_printf("enxcol_.%s.esc", ectx->target_coll);
433
- char *ecocCollection = bson_strdup_printf("enxcol_.%s.ecoc", ectx->target_coll);
434
- bson_t empty_array = BSON_INITIALIZER;
435
- if (!BSON_APPEND_UTF8(&empty_encryptedFields, "escCollection", escCollection)) {
436
- return _mongocrypt_ctx_fail_w_msg(ctx, "failed to append `escCollection`");
437
- }
438
- if (!BSON_APPEND_UTF8(&empty_encryptedFields, "ecocCollection", ecocCollection)) {
439
- return _mongocrypt_ctx_fail_w_msg(ctx, "failed to append `ecocCollection`");
440
- }
441
- if (!BSON_APPEND_ARRAY(&empty_encryptedFields, "fields", &empty_array)) {
442
- return _mongocrypt_ctx_fail_w_msg(ctx, "failed to append `fields`");
443
- }
444
-
445
- bson_destroy(&empty_array);
446
- bson_free(escCollection);
447
- bson_free(ecocCollection);
448
- }
449
-
450
- if (!mc_EncryptedFieldConfig_parse(&ectx->efc,
451
- &empty_encryptedFields,
452
- ctx->status,
453
- ctx->crypt->opts.use_range_v2)) {
454
- bson_destroy(&empty_encryptedFields);
455
- _mongocrypt_ctx_fail(ctx);
456
- return false;
457
- }
458
- _mongocrypt_buffer_steal_from_bson(&ectx->encrypted_field_config, &empty_encryptedFields);
459
- }
460
-
461
- BSON_ASSERT(bson_iter_init(&iter, collinfo));
462
-
463
- if (bson_iter_find_descendant(&iter, "options.validator", &iter) && BSON_ITER_HOLDS_DOCUMENT(&iter)) {
464
- if (!bson_iter_recurse(&iter, &iter)) {
465
- return _mongocrypt_ctx_fail_w_msg(ctx, "BSON malformed");
466
- }
467
- while (bson_iter_next(&iter)) {
468
- const char *key;
469
-
470
- key = bson_iter_key(&iter);
471
- BSON_ASSERT(key);
472
- if (0 == strcmp("$jsonSchema", key)) {
473
- if (found_jsonschema) {
474
- return _mongocrypt_ctx_fail_w_msg(ctx, "duplicate $jsonSchema fields found");
475
- }
476
- if (!_mongocrypt_buffer_copy_from_document_iter(&ectx->schema, &iter)) {
477
- return _mongocrypt_ctx_fail_w_msg(ctx, "malformed $jsonSchema");
478
- }
479
- found_jsonschema = true;
480
- } else {
481
- ectx->collinfo_has_siblings = true;
482
- }
483
- }
484
- }
485
-
486
- if (!found_jsonschema) {
487
- bson_t empty = BSON_INITIALIZER;
488
-
489
- _mongocrypt_buffer_steal_from_bson(&ectx->schema, &empty);
490
- }
491
-
492
- return true;
493
- }
494
-
495
49
  /* get_command_name returns the name of a command. The command name is the first
496
50
  * field. For example, the command name of: {"find": "foo", "filter": {"bar":
497
51
  * 1}} is "find". */
@@ -526,29 +80,6 @@ static const char *get_command_name(_mongocrypt_buffer_t *cmd, mongocrypt_status
526
80
  return cmd_name;
527
81
  }
528
82
 
529
- static bool command_needs_deleteTokens(mongocrypt_ctx_t *ctx, const char *command_name) {
530
- BSON_ASSERT_PARAM(ctx);
531
- BSON_ASSERT_PARAM(command_name);
532
- BSON_ASSERT(ctx->kb.crypt);
533
-
534
- if (ctx->crypt->opts.use_fle2_v2) {
535
- return false;
536
- }
537
-
538
- const char *cmds_needing_deleteTokens[] = {"delete", "update", "findAndModify"};
539
-
540
- BSON_ASSERT_PARAM(command_name);
541
-
542
- size_t i;
543
- for (i = 0; i < sizeof(cmds_needing_deleteTokens) / sizeof(cmds_needing_deleteTokens[0]); i++) {
544
- if (0 == strcmp(cmds_needing_deleteTokens[i], command_name)) {
545
- return true;
546
- }
547
- }
548
-
549
- return false;
550
- }
551
-
552
83
  /* context_uses_fle2 returns true if the context uses FLE 2 behavior.
553
84
  * If a collection has an encryptedFields document, it uses FLE 2.
554
85
  */
@@ -557,40 +88,7 @@ static bool context_uses_fle2(mongocrypt_ctx_t *ctx) {
557
88
 
558
89
  BSON_ASSERT_PARAM(ctx);
559
90
 
560
- return !_mongocrypt_buffer_empty(&ectx->encrypted_field_config);
561
- }
562
-
563
- /* _fle2_collect_keys_for_deleteTokens requests keys required to produce
564
- * deleteTokens. deleteTokens is only applicable to FLE 2. */
565
- static bool _fle2_collect_keys_for_deleteTokens(mongocrypt_ctx_t *ctx) {
566
- _mongocrypt_ctx_encrypt_t *ectx = (_mongocrypt_ctx_encrypt_t *)ctx;
567
-
568
- BSON_ASSERT_PARAM(ctx);
569
-
570
- /* deleteTokens are only appended for FLE 2. */
571
- if (!context_uses_fle2(ctx)) {
572
- return true;
573
- }
574
-
575
- const char *cmd_name = ectx->cmd_name;
576
-
577
- if (!command_needs_deleteTokens(ctx, cmd_name)) {
578
- /* Command does not require deleteTokens. */
579
- return true;
580
- }
581
-
582
- mc_EncryptedField_t *field;
583
-
584
- for (field = ectx->efc.fields; field != NULL; field = field->next) {
585
- if (field->supported_queries) {
586
- if (!_mongocrypt_key_broker_request_id(&ctx->kb, &field->keyId)) {
587
- _mongocrypt_key_broker_status(&ctx->kb, ctx->status);
588
- _mongocrypt_ctx_fail(ctx);
589
- return false;
590
- }
591
- }
592
- }
593
- return true;
91
+ return mc_schema_broker_has_any_qe_schemas(ectx->sb);
594
92
  }
595
93
 
596
94
  /* _fle2_collect_keys_for_compaction requests keys required to produce
@@ -616,15 +114,20 @@ static bool _fle2_collect_keys_for_compaction(mongocrypt_ctx_t *ctx) {
616
114
  /* (compact/cleanup)StructuredEncryptionData must not be sent to mongocryptd. */
617
115
  ectx->bypass_query_analysis = true;
618
116
 
619
- mc_EncryptedField_t *field;
117
+ const mc_EncryptedFieldConfig_t *efc =
118
+ mc_schema_broker_get_encryptedFields(ectx->sb, ectx->target_coll, ctx->status);
119
+ if (!efc) {
120
+ return _mongocrypt_ctx_fail(ctx);
121
+ }
620
122
 
621
- for (field = ectx->efc.fields; field != NULL; field = field->next) {
123
+ for (const mc_EncryptedField_t *field = efc->fields; field != NULL; field = field->next) {
622
124
  if (!_mongocrypt_key_broker_request_id(&ctx->kb, &field->keyId)) {
623
125
  _mongocrypt_key_broker_status(&ctx->kb, ctx->status);
624
126
  _mongocrypt_ctx_fail(ctx);
625
127
  return false;
626
128
  }
627
129
  }
130
+
628
131
  return true;
629
132
  }
630
133
 
@@ -641,15 +144,10 @@ static bool _mongo_feed_collinfo(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *in)
641
144
  return _mongocrypt_ctx_fail_w_msg(ctx, "BSON malformed");
642
145
  }
643
146
 
644
- /* Cache the received collinfo. */
645
- if (!_mongocrypt_cache_add_copy(&ctx->crypt->cache_collinfo, ectx->target_ns, &as_bson, ctx->status)) {
147
+ if (!mc_schema_broker_satisfy_from_collinfo(ectx->sb, &as_bson, &ctx->crypt->cache_collinfo, ctx->status)) {
646
148
  return _mongocrypt_ctx_fail(ctx);
647
149
  }
648
150
 
649
- if (!_set_schema_from_collinfo(ctx, &as_bson)) {
650
- return false;
651
- }
652
-
653
151
  return true;
654
152
  }
655
153
 
@@ -661,23 +159,10 @@ static bool _mongo_done_collinfo(mongocrypt_ctx_t *ctx) {
661
159
  BSON_ASSERT_PARAM(ctx);
662
160
 
663
161
  ectx = (_mongocrypt_ctx_encrypt_t *)ctx;
664
- if (_mongocrypt_buffer_empty(&ectx->schema)) {
665
- bson_t empty_collinfo = BSON_INITIALIZER;
666
-
667
- /* If no collinfo was fed, apply and cache an empty collinfo. */
668
- if (!_set_schema_from_collinfo(ctx, &empty_collinfo)) {
669
- bson_destroy(&empty_collinfo);
670
- return false;
671
- }
672
- if (!_mongocrypt_cache_add_copy(&ctx->crypt->cache_collinfo, ectx->target_ns, &empty_collinfo, ctx->status)) {
673
- bson_destroy(&empty_collinfo);
674
- return _mongocrypt_ctx_fail(ctx);
675
- }
676
- bson_destroy(&empty_collinfo);
677
- }
678
162
 
679
- if (!_fle2_collect_keys_for_deleteTokens(ctx)) {
680
- return false;
163
+ // If there are collections still needing schemas, assume no schema exists.
164
+ if (!mc_schema_broker_satisfy_remaining_with_empty_schemas(ectx->sb, &ctx->crypt->cache_collinfo, ctx->status)) {
165
+ return _mongocrypt_ctx_fail(ctx);
681
166
  }
682
167
 
683
168
  if (!_fle2_collect_keys_for_compaction(ctx)) {
@@ -685,67 +170,26 @@ static bool _mongo_done_collinfo(mongocrypt_ctx_t *ctx) {
685
170
  }
686
171
 
687
172
  if (ectx->bypass_query_analysis) {
688
- /* Keys may have been requested for deleteTokens or compactionTokens.
173
+ /* Keys may have been requested for compactionTokens.
689
174
  * Finish key requests. */
690
175
  _mongocrypt_key_broker_requests_done(&ctx->kb);
691
176
  return _mongocrypt_ctx_state_from_key_broker(ctx);
692
177
  }
693
- ectx->parent.state = MONGOCRYPT_CTX_NEED_MONGO_MARKINGS;
694
- return _try_run_csfle_marking(ctx);
695
- }
696
-
697
- static const char *_mongo_db_collinfo(mongocrypt_ctx_t *ctx) {
698
- _mongocrypt_ctx_encrypt_t *ectx;
699
-
700
- BSON_ASSERT_PARAM(ctx);
701
-
702
- ectx = (_mongocrypt_ctx_encrypt_t *)ctx;
703
- if (!ectx->target_db) {
704
- _mongocrypt_ctx_fail_w_msg(ctx, "Expected target database for `listCollections`, but none exists.");
705
- return NULL;
706
- }
707
- return ectx->target_db;
708
- }
709
-
710
- static bool _fle2_mongo_op_markings(mongocrypt_ctx_t *ctx, bson_t *out) {
711
- _mongocrypt_ctx_encrypt_t *ectx;
712
- bson_t cmd_bson = BSON_INITIALIZER, encrypted_field_config_bson = BSON_INITIALIZER;
713
-
714
- BSON_ASSERT_PARAM(ctx);
715
- BSON_ASSERT_PARAM(out);
716
-
717
- ectx = (_mongocrypt_ctx_encrypt_t *)ctx;
718
-
719
- BSON_ASSERT(ctx->state == MONGOCRYPT_CTX_NEED_MONGO_MARKINGS);
720
- BSON_ASSERT(context_uses_fle2(ctx));
721
-
722
- if (!_mongocrypt_buffer_to_bson(&ectx->original_cmd, &cmd_bson)) {
723
- return _mongocrypt_ctx_fail_w_msg(ctx, "unable to convert original_cmd to BSON");
724
- }
178
+ ectx->parent.state = MONGOCRYPT_CTX_NEED_MONGO_MARKINGS;
179
+ return _try_run_csfle_marking(ctx);
180
+ }
725
181
 
726
- if (!_mongocrypt_buffer_to_bson(&ectx->encrypted_field_config, &encrypted_field_config_bson)) {
727
- return _mongocrypt_ctx_fail_w_msg(ctx, "unable to convert encrypted_field_config to BSON");
728
- }
182
+ static const char *_mongo_db_collinfo(mongocrypt_ctx_t *ctx) {
183
+ _mongocrypt_ctx_encrypt_t *ectx;
729
184
 
730
- const char *cmd_name = ectx->cmd_name;
185
+ BSON_ASSERT_PARAM(ctx);
731
186
 
732
- // If input command included $db, do not include it in the command to
733
- // mongocryptd. Drivers are expected to append $db in the RunCommand helper
734
- // used to send the command.
735
- bson_init(out);
736
- bson_copy_to_excluding_noinit(&cmd_bson, out, "$db", NULL);
737
- if (!_fle2_insert_encryptionInformation(ctx,
738
- cmd_name,
739
- out,
740
- ectx->target_ns,
741
- &encrypted_field_config_bson,
742
- NULL /* deleteTokens */,
743
- ectx->target_coll,
744
- ctx->crypt->csfle.okay ? MC_TO_CSFLE : MC_TO_MONGOCRYPTD,
745
- ctx->status)) {
746
- return _mongocrypt_ctx_fail(ctx);
187
+ ectx = (_mongocrypt_ctx_encrypt_t *)ctx;
188
+ if (!ectx->target_db) {
189
+ _mongocrypt_ctx_fail_w_msg(ctx, "Expected target database for `listCollections`, but none exists.");
190
+ return NULL;
747
191
  }
748
- return true;
192
+ return ectx->target_db;
749
193
  }
750
194
 
751
195
  /**
@@ -763,41 +207,23 @@ static bool _create_markings_cmd_bson(mongocrypt_ctx_t *ctx, bson_t *out) {
763
207
  BSON_ASSERT_PARAM(ctx);
764
208
  BSON_ASSERT_PARAM(out);
765
209
 
766
- if (context_uses_fle2(ctx)) {
767
- // Defer to FLE2 to generate the markings command
768
- return _fle2_mongo_op_markings(ctx, out);
769
- }
770
-
771
- // For FLE1:
772
- // Get the original command document
773
210
  bson_t bson_view = BSON_INITIALIZER;
774
211
  if (!_mongocrypt_buffer_to_bson(&ectx->original_cmd, &bson_view)) {
775
212
  _mongocrypt_ctx_fail_w_msg(ctx, "invalid BSON cmd");
776
213
  return false;
777
214
  }
778
-
779
- // Copy the command to the output
780
215
  // If input command included $db, do not include it in the command to
781
216
  // mongocryptd. Drivers are expected to append $db in the RunCommand helper
782
217
  // used to send the command.
783
- bson_init(out);
784
218
  bson_copy_to_excluding_noinit(&bson_view, out, "$db", NULL);
785
-
786
- if (!_mongocrypt_buffer_empty(&ectx->schema)) {
787
- // We have a schema buffer. View it as BSON:
788
- if (!_mongocrypt_buffer_to_bson(&ectx->schema, &bson_view)) {
789
- _mongocrypt_ctx_fail_w_msg(ctx, "invalid BSON schema");
790
- return false;
791
- }
792
- // Append the jsonSchema to the output command
793
- BSON_APPEND_DOCUMENT(out, "jsonSchema", &bson_view);
794
- } else {
795
- bson_t empty = BSON_INITIALIZER;
796
- BSON_APPEND_DOCUMENT(out, "jsonSchema", &empty);
219
+ if (!mc_schema_broker_add_schemas_to_cmd(ectx->sb,
220
+ out,
221
+ ctx->crypt->csfle.okay ? MC_CMD_SCHEMAS_FOR_CRYPT_SHARED
222
+ : MC_CMD_SCHEMAS_FOR_MONGOCRYPTD,
223
+ ctx->status)) {
224
+ return _mongocrypt_ctx_fail(ctx);
797
225
  }
798
226
 
799
- // if a local schema was not set, set isRemoteSchema=true
800
- BSON_APPEND_BOOL(out, "isRemoteSchema", !ectx->used_local_schema);
801
227
  return true;
802
228
  }
803
229
 
@@ -904,23 +330,8 @@ static bool _mongo_feed_markings(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *in)
904
330
 
905
331
  if (bson_iter_init_find(&iter, &as_bson, "schemaRequiresEncryption") && !bson_iter_as_bool(&iter)) {
906
332
  /* TODO: update cache: this schema does not require encryption. */
907
-
908
- /* If using a local schema, warn if there are no encrypted fields. */
909
- if (ectx->used_local_schema) {
910
- _mongocrypt_log(&ctx->crypt->log,
911
- MONGOCRYPT_LOG_LEVEL_WARNING,
912
- "local schema used but does not have encryption specifiers");
913
- }
333
+ // Schema does not require encryption. Skip copying the `result`.
914
334
  return true;
915
- } else {
916
- /* if the schema requires encryption, but has sibling validators, error.
917
- */
918
- if (ectx->collinfo_has_siblings) {
919
- return _mongocrypt_ctx_fail_w_msg(ctx,
920
- "schema requires encryption, "
921
- "but collection JSON schema "
922
- "validator has siblings");
923
- }
924
335
  }
925
336
 
926
337
  if (bson_iter_init_find(&iter, &as_bson, "hasEncryptedPlaceholders") && !bson_iter_as_bool(&iter)) {
@@ -1230,116 +641,6 @@ _replace_marking_with_ciphertext(void *ctx, _mongocrypt_buffer_t *in, bson_value
1230
641
  return ret;
1231
642
  }
1232
643
 
1233
- /* generate_delete_tokens generates the 'deleteTokens' document to be appended
1234
- * to 'encryptionInformation'. */
1235
- static bson_t *generate_delete_tokens(_mongocrypt_crypto_t *crypto,
1236
- _mongocrypt_key_broker_t *kb,
1237
- mc_EncryptedFieldConfig_t *efc,
1238
- mongocrypt_status_t *status) {
1239
- bool ret = false;
1240
- bson_t *out = bson_new();
1241
- mc_EncryptedField_t *ef;
1242
-
1243
- BSON_ASSERT_PARAM(crypto);
1244
- BSON_ASSERT_PARAM(kb);
1245
- BSON_ASSERT_PARAM(efc);
1246
-
1247
- for (ef = efc->fields; ef != NULL; ef = ef->next) {
1248
- _mongocrypt_buffer_t IndexKey = {0};
1249
- _mongocrypt_buffer_t TokenKey = {0};
1250
- mc_ServerDataEncryptionLevel1Token_t *sdel1t = NULL;
1251
- mc_CollectionsLevel1Token_t *cl1t = NULL;
1252
- mc_ECOCToken_t *ecoc = NULL;
1253
- bool loop_ok = false;
1254
- /* deleteTokens are only necessary for indexed fields. */
1255
- if (!ef->supported_queries) {
1256
- goto loop_continue;
1257
- }
1258
-
1259
- if (!_mongocrypt_key_broker_decrypted_key_by_id(kb, &ef->keyId, &IndexKey)) {
1260
- _mongocrypt_key_broker_status(kb, status);
1261
- goto loop_fail;
1262
- }
1263
-
1264
- /* Get the TokenKey from the last 32 bytes of IndexKey */
1265
- if (IndexKey.len < MONGOCRYPT_TOKEN_KEY_LEN) {
1266
- CLIENT_ERR("IndexKey too short");
1267
- goto loop_fail;
1268
- }
1269
- if (!_mongocrypt_buffer_from_subrange(&TokenKey,
1270
- &IndexKey,
1271
- IndexKey.len - MONGOCRYPT_TOKEN_KEY_LEN,
1272
- MONGOCRYPT_TOKEN_KEY_LEN)) {
1273
- CLIENT_ERR("generate_delete_tokens unable to parse TokenKey from IndexKey");
1274
- goto loop_fail;
1275
- }
1276
-
1277
- sdel1t = mc_ServerDataEncryptionLevel1Token_new(crypto, &TokenKey, status);
1278
- if (!sdel1t) {
1279
- goto loop_fail;
1280
- }
1281
-
1282
- cl1t = mc_CollectionsLevel1Token_new(crypto, &TokenKey, status);
1283
- if (!cl1t) {
1284
- goto loop_fail;
1285
- }
1286
-
1287
- ecoc = mc_ECOCToken_new(crypto, cl1t, status);
1288
- if (!ecoc) {
1289
- goto loop_fail;
1290
- }
1291
-
1292
- bson_t field_bson;
1293
- if (!BSON_APPEND_DOCUMENT_BEGIN(out, ef->path, &field_bson)) {
1294
- CLIENT_ERR("failed to begin document for 'deleteTokens.%s'", ef->path);
1295
- goto loop_fail;
1296
- }
1297
-
1298
- if (!BSON_APPEND_BINARY(&field_bson,
1299
- "e",
1300
- BSON_SUBTYPE_BINARY,
1301
- mc_ServerDataEncryptionLevel1Token_get(sdel1t)->data,
1302
- mc_ServerDataEncryptionLevel1Token_get(sdel1t)->len)) {
1303
- CLIENT_ERR("failed to append ServerDataEncryptionLevel1Token for %s", ef->path);
1304
- goto loop_fail;
1305
- }
1306
-
1307
- if (!BSON_APPEND_BINARY(&field_bson,
1308
- "o",
1309
- BSON_SUBTYPE_BINARY,
1310
- mc_ECOCToken_get(ecoc)->data,
1311
- mc_ECOCToken_get(ecoc)->len)) {
1312
- CLIENT_ERR("failed to append ECOCToken for %s", ef->path);
1313
- goto loop_fail;
1314
- }
1315
-
1316
- if (!bson_append_document_end(out, &field_bson)) {
1317
- CLIENT_ERR("failed to end document for 'deleteTokens.%s'", ef->path);
1318
- goto loop_fail;
1319
- }
1320
-
1321
- loop_continue:
1322
- loop_ok = true;
1323
- loop_fail:
1324
- _mongocrypt_buffer_cleanup(&IndexKey);
1325
- _mongocrypt_buffer_cleanup(&TokenKey);
1326
- mc_ServerDataEncryptionLevel1Token_destroy(sdel1t);
1327
- mc_CollectionsLevel1Token_destroy(cl1t);
1328
- mc_ECOCToken_destroy(ecoc);
1329
- if (!loop_ok) {
1330
- goto fail;
1331
- }
1332
- }
1333
-
1334
- ret = true;
1335
- fail:
1336
- if (!ret) {
1337
- bson_destroy(out);
1338
- return NULL;
1339
- }
1340
- return out;
1341
- }
1342
-
1343
644
  static bool
1344
645
  _check_for_payload_requiring_encryptionInformation(void *ctx, _mongocrypt_buffer_t *in, mongocrypt_status_t *status) {
1345
646
  bool *out = (bool *)ctx;
@@ -1384,9 +685,12 @@ static moe_result must_omit_encryptionInformation(const char *command_name,
1384
685
 
1385
686
  BSON_ASSERT_PARAM(command_name);
1386
687
  BSON_ASSERT_PARAM(command);
1387
- BSON_ASSERT_PARAM(efc);
1388
688
 
1389
689
  if (0 == strcmp("compactStructuredEncryptionData", command_name)) {
690
+ if (!efc) {
691
+ CLIENT_ERR("expected to have encryptedFields for compactStructuredEncryptionData command but have none");
692
+ return (moe_result){.ok = false};
693
+ }
1390
694
  // `compactStructuredEncryptionData` is a special case:
1391
695
  // - Server 7.0 prohibits `encryptionInformation`.
1392
696
  // - Server 8.0 requires `encryptionInformation` if "range" fields are referenced. Otherwise ignores.
@@ -1445,7 +749,7 @@ static moe_result must_omit_encryptionInformation(const char *command_name,
1445
749
  */
1446
750
  static bool _fle2_append_compactionTokens(mongocrypt_t *crypt,
1447
751
  _mongocrypt_key_broker_t *kb,
1448
- mc_EncryptedFieldConfig_t *efc,
752
+ const mc_EncryptedFieldConfig_t *efc,
1449
753
  const char *command_name,
1450
754
  bson_t *out,
1451
755
  mongocrypt_status_t *status) {
@@ -1454,7 +758,6 @@ static bool _fle2_append_compactionTokens(mongocrypt_t *crypt,
1454
758
 
1455
759
  BSON_ASSERT_PARAM(crypt);
1456
760
  BSON_ASSERT_PARAM(kb);
1457
- BSON_ASSERT_PARAM(efc);
1458
761
  BSON_ASSERT_PARAM(command_name);
1459
762
  BSON_ASSERT_PARAM(out);
1460
763
  _mongocrypt_crypto_t *crypto = crypt->crypto;
@@ -1465,13 +768,18 @@ static bool _fle2_append_compactionTokens(mongocrypt_t *crypt,
1465
768
  return true;
1466
769
  }
1467
770
 
771
+ if (!efc) {
772
+ CLIENT_ERR("expected to have encryptedFields for %s command but have none", command_name);
773
+ return false;
774
+ }
775
+
1468
776
  if (cleanup) {
1469
777
  BSON_APPEND_DOCUMENT_BEGIN(out, "cleanupTokens", &result_compactionTokens);
1470
778
  } else {
1471
779
  BSON_APPEND_DOCUMENT_BEGIN(out, "compactionTokens", &result_compactionTokens);
1472
780
  }
1473
781
 
1474
- mc_EncryptedField_t *ptr;
782
+ const mc_EncryptedField_t *ptr;
1475
783
  for (ptr = efc->fields; ptr != NULL; ptr = ptr->next) {
1476
784
  /* Append tokens. */
1477
785
  _mongocrypt_buffer_t key = {0};
@@ -1671,12 +979,108 @@ fail:
1671
979
  return ok;
1672
980
  }
1673
981
 
982
+ /*
983
+ * Checks the "encryptedFields.strEncodeVersion" field for "create" commands for validity, and sets it to the default if
984
+ * it does not exist.
985
+ */
986
+ static bool _fle2_fixup_encryptedFields_strEncodeVersion(const char *cmd_name,
987
+ bson_t *cmd /* in and out */,
988
+ const mc_EncryptedFieldConfig_t *efc,
989
+ mongocrypt_status_t *status) {
990
+ BSON_ASSERT_PARAM(cmd_name);
991
+ BSON_ASSERT_PARAM(cmd);
992
+
993
+ if (0 == strcmp(cmd_name, "create")) {
994
+ if (!efc) {
995
+ CLIENT_ERR("expected to have encryptedFields for create command but have none");
996
+ return false;
997
+ }
998
+ bson_iter_t ef_iter;
999
+ if (!bson_iter_init_find(&ef_iter, cmd, "encryptedFields")) {
1000
+ // No encryptedFields, nothing to check or fix
1001
+ return true;
1002
+ }
1003
+ if (!BSON_ITER_HOLDS_DOCUMENT(&ef_iter)) {
1004
+ CLIENT_ERR("_fle2_fixup_encryptedFields_strEncodeVersion: Expected encryptedFields to be type obj, got: %s",
1005
+ mc_bson_type_to_string(bson_iter_type(&ef_iter)));
1006
+ return false;
1007
+ }
1008
+ bson_iter_t sev_iter;
1009
+ if (!bson_iter_recurse(&ef_iter, &sev_iter)) {
1010
+ CLIENT_ERR("_fle2_fixup_encryptedFields_strEncodeVersion: Failed to recurse bson_iter");
1011
+ return false;
1012
+ }
1013
+ if (!bson_iter_find(&sev_iter, "strEncodeVersion")) {
1014
+ if (efc->str_encode_version == 0) {
1015
+ // Unset StrEncodeVersion matches the EFC, nothing to fix.
1016
+ return true;
1017
+ }
1018
+
1019
+ // No strEncodeVersion and the EFC has a nonzero strEncodeVersion, add it.
1020
+ // Initialize the new cmd object from the old one, excluding encryptedFields.
1021
+ bson_t fixed = BSON_INITIALIZER;
1022
+ bson_copy_to_excluding_noinit(cmd, &fixed, "encryptedFields", NULL);
1023
+
1024
+ // Recurse the original encryptedFields and copy everything over.
1025
+ bson_iter_t copy_iter;
1026
+ if (!bson_iter_recurse(&ef_iter, &copy_iter)) {
1027
+ CLIENT_ERR("_fle2_fixup_encryptedFields_strEncodeVersion: Failed to recurse bson_iter");
1028
+ goto fail;
1029
+ }
1030
+ bson_t fixed_ef;
1031
+ if (!BSON_APPEND_DOCUMENT_BEGIN(&fixed, "encryptedFields", &fixed_ef)) {
1032
+ CLIENT_ERR("_fle2_fixup_encryptedFields_strEncodeVersion: Failed to start appending encryptedFields");
1033
+ goto fail;
1034
+ }
1035
+ while (bson_iter_next(&copy_iter)) {
1036
+ if (!bson_append_iter(&fixed_ef, NULL, 0, &copy_iter)) {
1037
+ CLIENT_ERR("_fle2_fixup_encryptedFields_strEncodeVersion: Failed to copy element");
1038
+ goto fail;
1039
+ }
1040
+ }
1041
+
1042
+ // Add the EFC's strEncodeVersion to encryptedFields.
1043
+ if (!BSON_APPEND_INT32(&fixed_ef, "strEncodeVersion", efc->str_encode_version)) {
1044
+ CLIENT_ERR("_fle2_fixup_encryptedFields_strEncodeVersion: Failed to append strEncodeVersion");
1045
+ goto fail;
1046
+ }
1047
+ if (!bson_append_document_end(&fixed, &fixed_ef)) {
1048
+ CLIENT_ERR("_fle2_fixup_encryptedFields_strEncodeVersion: Failed to finish appending encryptedFields");
1049
+ goto fail;
1050
+ }
1051
+
1052
+ bson_destroy(cmd);
1053
+ if (!bson_steal(cmd, &fixed)) {
1054
+ CLIENT_ERR("_fle2_fixup_encryptedFields_strEncodeVersion: Failed to steal BSON");
1055
+ goto fail;
1056
+ }
1057
+ return true;
1058
+ fail:
1059
+ bson_destroy(&fixed);
1060
+ return false;
1061
+ } else {
1062
+ // Check strEncodeVersion for match against EFC
1063
+ if (!BSON_ITER_HOLDS_INT32(&sev_iter)) {
1064
+ CLIENT_ERR("expected 'strEncodeVersion' to be type int32, got: %d", bson_iter_type(&sev_iter));
1065
+ return false;
1066
+ }
1067
+ int32_t version = bson_iter_int32(&sev_iter);
1068
+ if (version != efc->str_encode_version) {
1069
+ CLIENT_ERR("'strEncodeVersion' of %d does not match efc->str_encode_version of %d",
1070
+ version,
1071
+ efc->str_encode_version);
1072
+ return false;
1073
+ }
1074
+ }
1075
+ }
1076
+ return true;
1077
+ }
1078
+
1674
1079
  /* Process a call to mongocrypt_ctx_finalize when an encryptedFieldConfig is
1675
1080
  * associated with the command. */
1676
1081
  static bool _fle2_finalize(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *out) {
1677
1082
  bson_t converted;
1678
1083
  _mongocrypt_ctx_encrypt_t *ectx;
1679
- bson_t encrypted_field_config_bson;
1680
1084
  bson_t original_cmd_bson;
1681
1085
 
1682
1086
  BSON_ASSERT_PARAM(ctx);
@@ -1691,10 +1095,6 @@ static bool _fle2_finalize(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *out) {
1691
1095
  return _mongocrypt_ctx_fail_w_msg(ctx, "explicit encryption is not yet supported. See MONGOCRYPT-409.");
1692
1096
  }
1693
1097
 
1694
- if (!_mongocrypt_buffer_to_bson(&ectx->encrypted_field_config, &encrypted_field_config_bson)) {
1695
- return _mongocrypt_ctx_fail_w_msg(ctx, "malformed bson in encrypted_field_config_bson");
1696
- }
1697
-
1698
1098
  if (!_mongocrypt_buffer_to_bson(&ectx->original_cmd, &original_cmd_bson)) {
1699
1099
  return _mongocrypt_ctx_fail_w_msg(ctx, "malformed bson in original_cmd");
1700
1100
  }
@@ -1733,45 +1133,38 @@ static bool _fle2_finalize(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *out) {
1733
1133
  return _mongocrypt_ctx_fail(ctx);
1734
1134
  }
1735
1135
 
1736
- bson_t *deleteTokens = NULL;
1737
- if (command_needs_deleteTokens(ctx, command_name)) {
1738
- deleteTokens = generate_delete_tokens(ctx->crypt->crypto, &ctx->kb, &ectx->efc, ctx->status);
1739
- if (!deleteTokens) {
1740
- bson_destroy(&converted);
1741
- return _mongocrypt_ctx_fail(ctx);
1742
- }
1743
- }
1136
+ // Defer error handling for potentially missing encryptedFields to command-specific routines below.
1137
+ // For create/cleanupStructuredEncryptionData/compactStructuredEncryptionData, get encryptedFields for the
1138
+ // single target collection. For other commands, encryptedFields may not be on the target collection.
1139
+ const mc_EncryptedFieldConfig_t *target_efc =
1140
+ mc_schema_broker_get_encryptedFields(ectx->sb, ectx->target_coll, NULL);
1744
1141
 
1745
1142
  moe_result result = must_omit_encryptionInformation(command_name,
1746
1143
  &converted,
1747
1144
  ctx->crypt->opts.use_range_v2,
1748
- &ectx->efc,
1145
+ target_efc,
1749
1146
  ctx->status);
1750
1147
  if (!result.ok) {
1751
1148
  bson_destroy(&converted);
1752
- bson_destroy(deleteTokens);
1149
+ return _mongocrypt_ctx_fail(ctx);
1150
+ }
1151
+
1152
+ /* If this is a create command, append the encryptedFields.strEncodeVersion field if it's necessary. If the field
1153
+ * already exists, check it against the EFC for correctness. */
1154
+ if (!_fle2_fixup_encryptedFields_strEncodeVersion(command_name, &converted, target_efc, ctx->status)) {
1155
+ bson_destroy(&converted);
1753
1156
  return _mongocrypt_ctx_fail(ctx);
1754
1157
  }
1755
1158
 
1756
1159
  /* Append a new 'encryptionInformation'. */
1757
- if (!result.must_omit && !ectx->used_empty_encryptedFields) {
1758
- if (!_fle2_insert_encryptionInformation(ctx,
1759
- command_name,
1760
- &converted,
1761
- ectx->target_ns,
1762
- &encrypted_field_config_bson,
1763
- deleteTokens,
1764
- ectx->target_coll,
1765
- MC_TO_MONGOD,
1766
- ctx->status)) {
1160
+ if (!result.must_omit) {
1161
+ if (!mc_schema_broker_add_schemas_to_cmd(ectx->sb, &converted, MC_CMD_SCHEMAS_FOR_SERVER, ctx->status)) {
1767
1162
  bson_destroy(&converted);
1768
- bson_destroy(deleteTokens);
1769
1163
  return _mongocrypt_ctx_fail(ctx);
1770
1164
  }
1771
1165
  }
1772
- bson_destroy(deleteTokens);
1773
1166
 
1774
- if (!_fle2_append_compactionTokens(ctx->crypt, &ctx->kb, &ectx->efc, command_name, &converted, ctx->status)) {
1167
+ if (!_fle2_append_compactionTokens(ctx->crypt, &ctx->kb, target_efc, command_name, &converted, ctx->status)) {
1775
1168
  bson_destroy(&converted);
1776
1169
  return _mongocrypt_ctx_fail(ctx);
1777
1170
  }
@@ -2139,26 +1532,23 @@ static void _cleanup(mongocrypt_ctx_t *ctx) {
2139
1532
  }
2140
1533
 
2141
1534
  ectx = (_mongocrypt_ctx_encrypt_t *)ctx;
1535
+ mc_schema_broker_destroy(ectx->sb);
2142
1536
  bson_free(ectx->target_ns);
2143
1537
  bson_free(ectx->cmd_db);
2144
1538
  bson_free(ectx->target_db);
2145
1539
  bson_free(ectx->target_coll);
2146
1540
  _mongocrypt_buffer_cleanup(&ectx->list_collections_filter);
2147
- _mongocrypt_buffer_cleanup(&ectx->schema);
2148
- _mongocrypt_buffer_cleanup(&ectx->encrypted_field_config);
2149
1541
  _mongocrypt_buffer_cleanup(&ectx->original_cmd);
2150
1542
  _mongocrypt_buffer_cleanup(&ectx->mongocryptd_cmd);
2151
1543
  _mongocrypt_buffer_cleanup(&ectx->marked_cmd);
2152
1544
  _mongocrypt_buffer_cleanup(&ectx->encrypted_cmd);
2153
1545
  _mongocrypt_buffer_cleanup(&ectx->ismaster.cmd);
2154
- mc_EncryptedFieldConfig_cleanup(&ectx->efc);
2155
1546
  }
2156
1547
 
2157
1548
  static bool _try_schema_from_schema_map(mongocrypt_ctx_t *ctx) {
2158
1549
  mongocrypt_t *crypt;
2159
1550
  _mongocrypt_ctx_encrypt_t *ectx;
2160
1551
  bson_t schema_map;
2161
- bson_iter_t iter;
2162
1552
 
2163
1553
  BSON_ASSERT_PARAM(ctx);
2164
1554
 
@@ -2174,15 +1564,13 @@ static bool _try_schema_from_schema_map(mongocrypt_ctx_t *ctx) {
2174
1564
  return _mongocrypt_ctx_fail_w_msg(ctx, "malformed schema map");
2175
1565
  }
2176
1566
 
2177
- if (bson_iter_init_find(&iter, &schema_map, ectx->target_ns)) {
2178
- if (!_mongocrypt_buffer_copy_from_document_iter(&ectx->schema, &iter)) {
2179
- return _mongocrypt_ctx_fail_w_msg(ctx, "malformed schema map");
2180
- }
2181
- ectx->used_local_schema = true;
1567
+ if (!mc_schema_broker_satisfy_from_schemaMap(ectx->sb, &schema_map, ctx->status)) {
1568
+ return _mongocrypt_ctx_fail(ctx);
1569
+ }
1570
+ if (!mc_schema_broker_need_more_schemas(ectx->sb)) {
1571
+ // Have all needed schemas. Proceed to next state.
2182
1572
  ctx->state = MONGOCRYPT_CTX_NEED_MONGO_MARKINGS;
2183
1573
  }
2184
-
2185
- /* No schema found in map. */
2186
1574
  return true;
2187
1575
  }
2188
1576
 
@@ -2194,7 +1582,6 @@ static bool _fle2_try_encrypted_field_config_from_map(mongocrypt_ctx_t *ctx) {
2194
1582
  mongocrypt_t *crypt;
2195
1583
  _mongocrypt_ctx_encrypt_t *ectx;
2196
1584
  bson_t encrypted_field_config_map;
2197
- bson_iter_t iter;
2198
1585
 
2199
1586
  BSON_ASSERT_PARAM(ctx);
2200
1587
 
@@ -2210,51 +1597,31 @@ static bool _fle2_try_encrypted_field_config_from_map(mongocrypt_ctx_t *ctx) {
2210
1597
  return _mongocrypt_ctx_fail_w_msg(ctx, "unable to convert encrypted_field_config_map to BSON");
2211
1598
  }
2212
1599
 
2213
- if (bson_iter_init_find(&iter, &encrypted_field_config_map, ectx->target_ns)) {
2214
- if (!_mongocrypt_buffer_copy_from_document_iter(&ectx->encrypted_field_config, &iter)) {
2215
- return _mongocrypt_ctx_fail_w_msg(ctx,
2216
- "unable to copy encrypted_field_config from "
2217
- "encrypted_field_config_map");
2218
- }
2219
- bson_t efc_bson;
2220
- if (!_mongocrypt_buffer_to_bson(&ectx->encrypted_field_config, &efc_bson)) {
2221
- return _mongocrypt_ctx_fail_w_msg(ctx, "unable to create BSON from encrypted_field_config");
2222
- }
2223
- if (!mc_EncryptedFieldConfig_parse(&ectx->efc, &efc_bson, ctx->status, ctx->crypt->opts.use_range_v2)) {
2224
- _mongocrypt_ctx_fail(ctx);
2225
- return false;
2226
- }
1600
+ if (!mc_schema_broker_satisfy_from_encryptedFieldsMap(ectx->sb, &encrypted_field_config_map, ctx->status)) {
1601
+ return _mongocrypt_ctx_fail(ctx);
1602
+ }
1603
+ if (!mc_schema_broker_need_more_schemas(ectx->sb)) {
1604
+ // Have all needed schemas. Proceed to next state.
2227
1605
  ctx->state = MONGOCRYPT_CTX_NEED_MONGO_MARKINGS;
2228
1606
  }
2229
-
2230
- /* No encrypted_field_config found in map. */
2231
1607
  return true;
2232
1608
  }
2233
1609
 
2234
1610
  static bool _try_schema_from_cache(mongocrypt_ctx_t *ctx) {
2235
1611
  _mongocrypt_ctx_encrypt_t *ectx;
2236
- bson_t *collinfo = NULL;
2237
1612
 
2238
1613
  BSON_ASSERT_PARAM(ctx);
2239
1614
 
2240
1615
  ectx = (_mongocrypt_ctx_encrypt_t *)ctx;
2241
1616
 
2242
- /* Otherwise, we need a remote schema. Check if we have a response to
2243
- * listCollections cached. */
2244
- if (!_mongocrypt_cache_get(&ctx->crypt->cache_collinfo,
2245
- ectx->target_ns /* null terminated */,
2246
- (void **)&collinfo)) {
2247
- return _mongocrypt_ctx_fail_w_msg(ctx, "failed to retrieve from cache");
1617
+ if (!mc_schema_broker_satisfy_from_cache(ectx->sb, &ctx->crypt->cache_collinfo, ctx->status)) {
1618
+ return _mongocrypt_ctx_fail(ctx);
2248
1619
  }
2249
-
2250
- if (collinfo) {
2251
- if (!_set_schema_from_collinfo(ctx, collinfo)) {
2252
- bson_destroy(collinfo);
2253
- return _mongocrypt_ctx_fail(ctx);
2254
- }
1620
+ if (!mc_schema_broker_need_more_schemas(ectx->sb)) {
1621
+ // Have all needed schemas. Proceed to next state.
2255
1622
  ctx->state = MONGOCRYPT_CTX_NEED_MONGO_MARKINGS;
2256
1623
  } else {
2257
- /* we need to get it. */
1624
+ // Request a listCollections command to check for remote schemas.
2258
1625
  ctx->state = MONGOCRYPT_CTX_NEED_MONGO_COLLINFO;
2259
1626
  if (ectx->target_db) {
2260
1627
  if (!ctx->crypt->opts.use_need_mongo_collinfo_with_db_state) {
@@ -2264,12 +1631,10 @@ static bool _try_schema_from_cache(mongocrypt_ctx_t *ctx) {
2264
1631
  "upgrading driver, or specify a local schemaMap or encryptedFieldsMap.");
2265
1632
  return false;
2266
1633
  }
2267
- // Target database may differ from command database. Request collection info from target database.
1634
+ // Target database differs from command database. Request collection info from target database.
2268
1635
  ctx->state = MONGOCRYPT_CTX_NEED_MONGO_COLLINFO_WITH_DB;
2269
1636
  }
2270
1637
  }
2271
-
2272
- bson_destroy(collinfo);
2273
1638
  return true;
2274
1639
  }
2275
1640
 
@@ -2289,8 +1654,12 @@ static bool _try_empty_schema_for_create(mongocrypt_ctx_t *ctx) {
2289
1654
  return true;
2290
1655
  }
2291
1656
 
2292
- bson_t empty = BSON_INITIALIZER;
2293
- _mongocrypt_buffer_steal_from_bson(&ectx->schema, &empty);
1657
+ // Satisfy with an empty schema. Do not cache the entry.
1658
+ if (!mc_schema_broker_satisfy_remaining_with_empty_schemas(ectx->sb, NULL /* cache */, ctx->status)) {
1659
+ return _mongocrypt_ctx_fail(ctx);
1660
+ }
1661
+ BSON_ASSERT(!mc_schema_broker_need_more_schemas(ectx->sb));
1662
+ // Have all needed schemas. Proceed to next state.
2294
1663
  ctx->state = MONGOCRYPT_CTX_NEED_MONGO_MARKINGS;
2295
1664
  return true;
2296
1665
  }
@@ -2331,7 +1700,6 @@ static bool _try_schema_from_create_or_collMod_cmd(mongocrypt_ctx_t *ctx) {
2331
1700
  }
2332
1701
 
2333
1702
  bson_t cmd_bson;
2334
- bson_iter_t iter;
2335
1703
 
2336
1704
  if (!_mongocrypt_buffer_to_bson(&ectx->original_cmd, &cmd_bson)) {
2337
1705
  CLIENT_ERR("unable to convert command buffer to BSON");
@@ -2339,22 +1707,13 @@ static bool _try_schema_from_create_or_collMod_cmd(mongocrypt_ctx_t *ctx) {
2339
1707
  return false;
2340
1708
  }
2341
1709
 
2342
- if (!bson_iter_init(&iter, &cmd_bson)) {
2343
- CLIENT_ERR("unable to iterate over command BSON");
2344
- _mongocrypt_ctx_fail(ctx);
2345
- return false;
1710
+ if (!mc_schema_broker_satisfy_from_create_or_collMod(ectx->sb, &cmd_bson, ctx->status)) {
1711
+ return _mongocrypt_ctx_fail(ctx);
2346
1712
  }
2347
-
2348
- if (bson_iter_find_descendant(&iter, "validator.$jsonSchema", &iter)) {
2349
- if (!_mongocrypt_buffer_copy_from_document_iter(&ectx->schema, &iter)) {
2350
- CLIENT_ERR("failed to parse BSON document from create validator.$jsonSchema");
2351
- _mongocrypt_ctx_fail(ctx);
2352
- return false;
2353
- }
1713
+ if (!mc_schema_broker_need_more_schemas(ectx->sb)) {
1714
+ // Have all needed schemas. Proceed to next state.
2354
1715
  ctx->state = MONGOCRYPT_CTX_NEED_MONGO_MARKINGS;
2355
- return true;
2356
1716
  }
2357
-
2358
1717
  return true;
2359
1718
  }
2360
1719
 
@@ -2557,6 +1916,7 @@ static bool explicit_encrypt_init(mongocrypt_ctx_t *ctx, mongocrypt_binary_t *ms
2557
1916
  ectx = (_mongocrypt_ctx_encrypt_t *)ctx;
2558
1917
  ctx->type = _MONGOCRYPT_TYPE_ENCRYPT;
2559
1918
  ectx->explicit = true;
1919
+ ectx->sb = mc_schema_broker_new();
2560
1920
  ctx->vtable.finalize = _finalize;
2561
1921
  ctx->vtable.cleanup = _cleanup;
2562
1922
 
@@ -2859,9 +2219,161 @@ static bool needs_ismaster_check(mongocrypt_ctx_t *ctx) {
2859
2219
  BSON_ASSERT_PARAM(ctx);
2860
2220
 
2861
2221
  bool using_mongocryptd = !ectx->bypass_query_analysis && !ctx->crypt->csfle.okay;
2862
- // The "create" and "createIndexes" command require an isMaster check when
2863
- // using mongocryptd. See MONGOCRYPT-429.
2864
- return using_mongocryptd && (0 == strcmp(ectx->cmd_name, "create") || 0 == strcmp(ectx->cmd_name, "createIndexes"));
2222
+
2223
+ if (!using_mongocryptd) {
2224
+ return false;
2225
+ }
2226
+
2227
+ if (mc_schema_broker_has_multiple_requests(ectx->sb)) {
2228
+ // Only mongocryptd 8.1 (wire version 26) supports multiple schemas with csfleEncryptionSchemas.
2229
+ return true;
2230
+ }
2231
+ // MONGOCRYPT-429: The "create" and "createIndexes" command are only supported on mongocrypt 6.0 (wire version 17).
2232
+ if (0 == strcmp(ectx->cmd_name, "create") || 0 == strcmp(ectx->cmd_name, "createIndexes")) {
2233
+ return true;
2234
+ }
2235
+
2236
+ return false;
2237
+ }
2238
+
2239
+ // `find_collections_in_pipeline` finds other collection names in an aggregate pipeline that may need schemas.
2240
+ static bool find_collections_in_pipeline(mc_schema_broker_t *sb,
2241
+ bson_iter_t pipeline_iter,
2242
+ const char *db,
2243
+ mstr_view path,
2244
+ mongocrypt_status_t *status) {
2245
+ bson_iter_t array_iter;
2246
+ if (!BSON_ITER_HOLDS_ARRAY(&pipeline_iter) || !bson_iter_recurse(&pipeline_iter, &array_iter)) {
2247
+ CLIENT_ERR("failed to recurse pipeline at path: %s", path.data);
2248
+ return false;
2249
+ }
2250
+
2251
+ while (bson_iter_next(&array_iter)) {
2252
+ bson_iter_t stage_iter;
2253
+ const char *stage_key = bson_iter_key(&array_iter);
2254
+
2255
+ if (!BSON_ITER_HOLDS_DOCUMENT(&array_iter) || !bson_iter_recurse(&array_iter, &stage_iter)
2256
+ || !bson_iter_next(&stage_iter)) {
2257
+ CLIENT_ERR("failed to recurse stage at path: %s.%s", path.data, stage_key);
2258
+ return false;
2259
+ }
2260
+
2261
+ const char *stage = bson_iter_key(&stage_iter);
2262
+ // Check for $lookup.
2263
+ if (0 == strcmp(stage, "$lookup")) {
2264
+ bson_iter_t lookup_iter;
2265
+ if (!BSON_ITER_HOLDS_DOCUMENT(&stage_iter) || !bson_iter_recurse(&stage_iter, &lookup_iter)) {
2266
+ CLIENT_ERR("failed to recurse $lookup at path: %s.%s", path.data, stage_key);
2267
+ return false;
2268
+ }
2269
+
2270
+ while (bson_iter_next(&lookup_iter)) {
2271
+ const char *field = bson_iter_key(&lookup_iter);
2272
+ if (0 == strcmp(field, "from")) {
2273
+ if (!BSON_ITER_HOLDS_UTF8(&lookup_iter)) {
2274
+ CLIENT_ERR("expected string, but '%s' for 'from' field at path: %s.%s",
2275
+ mc_bson_type_to_string(bson_iter_type(&lookup_iter)),
2276
+ path.data,
2277
+ stage_key);
2278
+ return false;
2279
+ }
2280
+ const char *from = bson_iter_utf8(&lookup_iter, NULL);
2281
+ if (!mc_schema_broker_request(sb, db, from, status)) {
2282
+ return false;
2283
+ }
2284
+ }
2285
+
2286
+ if (0 == strcmp(field, "pipeline")) {
2287
+ mstr subpath = mstr_append(path, mstrv_lit("."));
2288
+ mstr_inplace_append(&subpath, mstrv_view_cstr(stage_key));
2289
+ mstr_inplace_append(&subpath, mstrv_lit(".$lookup.pipeline"));
2290
+ if (!find_collections_in_pipeline(sb, lookup_iter, db, subpath.view, status)) {
2291
+ mstr_free(subpath);
2292
+ return false;
2293
+ }
2294
+ mstr_free(subpath);
2295
+ }
2296
+ }
2297
+ }
2298
+
2299
+ // Check for $facet.
2300
+ if (0 == strcmp(stage, "$facet")) {
2301
+ bson_iter_t facet_iter;
2302
+ if (!BSON_ITER_HOLDS_DOCUMENT(&stage_iter) || !bson_iter_recurse(&stage_iter, &facet_iter)) {
2303
+ CLIENT_ERR("failed to recurse $facet at path: %s.%s", path.data, stage_key);
2304
+ return false;
2305
+ }
2306
+
2307
+ while (bson_iter_next(&facet_iter)) {
2308
+ const char *field = bson_iter_key(&facet_iter);
2309
+ mstr subpath = mstr_append(path, mstrv_lit("."));
2310
+ mstr_inplace_append(&subpath, mstrv_view_cstr(stage_key));
2311
+ mstr_inplace_append(&subpath, mstrv_lit(".$facet."));
2312
+ mstr_inplace_append(&subpath, mstrv_view_cstr(field));
2313
+ if (!find_collections_in_pipeline(sb, facet_iter, db, subpath.view, status)) {
2314
+ mstr_free(subpath);
2315
+ return false;
2316
+ }
2317
+ mstr_free(subpath);
2318
+ }
2319
+ }
2320
+
2321
+ // Check for $unionWith.
2322
+ if (0 == strcmp(stage, "$unionWith")) {
2323
+ bson_iter_t unionWith_iter;
2324
+ if (!BSON_ITER_HOLDS_DOCUMENT(&stage_iter) || !bson_iter_recurse(&stage_iter, &unionWith_iter)) {
2325
+ CLIENT_ERR("failed to recurse $unionWith at path: %s.%s", path.data, stage_key);
2326
+ return false;
2327
+ }
2328
+
2329
+ while (bson_iter_next(&unionWith_iter)) {
2330
+ const char *field = bson_iter_key(&unionWith_iter);
2331
+ if (0 == strcmp(field, "coll")) {
2332
+ if (!BSON_ITER_HOLDS_UTF8(&unionWith_iter)) {
2333
+ CLIENT_ERR("expected string, but got '%s' for 'coll' field at path: %s.%s",
2334
+ mc_bson_type_to_string(bson_iter_type(&unionWith_iter)),
2335
+ path.data,
2336
+ stage_key);
2337
+ return false;
2338
+ }
2339
+ const char *coll = bson_iter_utf8(&unionWith_iter, NULL);
2340
+ if (!mc_schema_broker_request(sb, db, coll, status)) {
2341
+ return false;
2342
+ }
2343
+ }
2344
+
2345
+ if (0 == strcmp(field, "pipeline")) {
2346
+ mstr subpath = mstr_append(path, mstrv_lit("."));
2347
+ mstr_inplace_append(&subpath, mstrv_view_cstr(stage_key));
2348
+ mstr_inplace_append(&subpath, mstrv_lit(".$unionWith.pipeline"));
2349
+ if (!find_collections_in_pipeline(sb, unionWith_iter, db, subpath.view, status)) {
2350
+ mstr_free(subpath);
2351
+ return false;
2352
+ }
2353
+ mstr_free(subpath);
2354
+ }
2355
+ }
2356
+ }
2357
+ }
2358
+
2359
+ return true;
2360
+ }
2361
+
2362
+ static bool
2363
+ find_collections_in_agg(mongocrypt_binary_t *cmd, mc_schema_broker_t *sb, const char *db, mongocrypt_status_t *status) {
2364
+ bson_t cmd_bson;
2365
+ if (!_mongocrypt_binary_to_bson(cmd, &cmd_bson)) {
2366
+ CLIENT_ERR("failed to convert command to BSON");
2367
+ return false;
2368
+ }
2369
+
2370
+ bson_iter_t iter;
2371
+ if (!bson_iter_init_find(&iter, &cmd_bson, "pipeline")) {
2372
+ // Command may be malformed. Let server error.
2373
+ return true;
2374
+ }
2375
+
2376
+ return find_collections_in_pipeline(sb, iter, db, mstrv_lit("aggregate.pipeline"), status);
2865
2377
  }
2866
2378
 
2867
2379
  bool mongocrypt_ctx_encrypt_init(mongocrypt_ctx_t *ctx, const char *db, int32_t db_len, mongocrypt_binary_t *cmd) {
@@ -2896,6 +2408,10 @@ bool mongocrypt_ctx_encrypt_init(mongocrypt_ctx_t *ctx, const char *db, int32_t
2896
2408
  ctx->vtable.finalize = _finalize;
2897
2409
  ctx->vtable.cleanup = _cleanup;
2898
2410
  ectx->bypass_query_analysis = ctx->crypt->opts.bypass_query_analysis;
2411
+ ectx->sb = mc_schema_broker_new();
2412
+ if (ctx->crypt->opts.use_range_v2) {
2413
+ mc_schema_broker_use_rangev2(ectx->sb);
2414
+ }
2899
2415
 
2900
2416
  if (!cmd || !cmd->data) {
2901
2417
  return _mongocrypt_ctx_fail_w_msg(ctx, "invalid command");
@@ -2921,6 +2437,10 @@ bool mongocrypt_ctx_encrypt_init(mongocrypt_ctx_t *ctx, const char *db, int32_t
2921
2437
  }
2922
2438
 
2923
2439
  ectx->target_ns = bson_strdup_printf("%s.%s", ectx->target_db, ectx->target_coll);
2440
+
2441
+ if (!mc_schema_broker_request(ectx->sb, ectx->target_db, ectx->target_coll, ctx->status)) {
2442
+ return _mongocrypt_ctx_fail(ctx);
2443
+ }
2924
2444
  } else {
2925
2445
  bool bypass;
2926
2446
  if (!_check_cmd_for_auto_encrypt(cmd, &bypass, &ectx->target_coll, ctx->status)) {
@@ -2939,6 +2459,25 @@ bool mongocrypt_ctx_encrypt_init(mongocrypt_ctx_t *ctx, const char *db, int32_t
2939
2459
  return _mongocrypt_ctx_fail_w_msg(ctx, "unexpected error: did not bypass or error but no collection name");
2940
2460
  }
2941
2461
  ectx->target_ns = bson_strdup_printf("%s.%s", ectx->cmd_db, ectx->target_coll);
2462
+ if (!mc_schema_broker_request(ectx->sb, ectx->cmd_db, ectx->target_coll, ctx->status)) {
2463
+ return _mongocrypt_ctx_fail(ctx);
2464
+ }
2465
+ }
2466
+
2467
+ if (0 == strcmp(ectx->cmd_name, "aggregate")) {
2468
+ if (!find_collections_in_agg(cmd, ectx->sb, ectx->cmd_db, ctx->status)) {
2469
+ _mongocrypt_ctx_fail(ctx);
2470
+ return false;
2471
+ }
2472
+
2473
+ if (mc_schema_broker_has_multiple_requests(ectx->sb)) {
2474
+ if (!ctx->crypt->multiple_collinfo_enabled) {
2475
+ return _mongocrypt_ctx_fail_w_msg(ctx,
2476
+ "aggregate includes a $lookup stage, but libmongocrypt is not "
2477
+ "configured to support encrypting a "
2478
+ "command with multiple collections");
2479
+ }
2480
+ }
2942
2481
  }
2943
2482
 
2944
2483
  if (ctx->opts.kek.provider.aws.region || ctx->opts.kek.provider.aws.cmk) {
@@ -2969,11 +2508,8 @@ bool mongocrypt_ctx_encrypt_init(mongocrypt_ctx_t *ctx, const char *db, int32_t
2969
2508
  bson_free(cmd_val);
2970
2509
  }
2971
2510
 
2972
- /* The "create" and "createIndexes" command require sending an isMaster
2973
- * request to mongocryptd. */
2511
+ // Check if an isMaster request to mongocryptd is needed to detect feature support:
2974
2512
  if (needs_ismaster_check(ctx)) {
2975
- /* We are using mongocryptd. We need to ensure that mongocryptd
2976
- * maxWireVersion >= 17. */
2977
2513
  ectx->ismaster.needed = true;
2978
2514
  ctx->state = MONGOCRYPT_CTX_NEED_MONGO_MARKINGS;
2979
2515
  return true;
@@ -2983,6 +2519,10 @@ bool mongocrypt_ctx_encrypt_init(mongocrypt_ctx_t *ctx, const char *db, int32_t
2983
2519
  }
2984
2520
 
2985
2521
  #define WIRE_VERSION_SERVER_6 17
2522
+ #define WIRE_VERSION_SERVER_8_1 26
2523
+ // The crypt_shared version format is defined in mongo_crypt-v1.h.
2524
+ // Example: server 6.2.1 is encoded as 0x0006000200010000
2525
+ #define CRYPT_SHARED_8_1 0x0008000100000000ull
2986
2526
 
2987
2527
  /* mongocrypt_ctx_encrypt_ismaster_done is called when:
2988
2528
  * 1. The max wire version of mongocryptd is known.
@@ -2995,36 +2535,72 @@ static bool mongocrypt_ctx_encrypt_ismaster_done(mongocrypt_ctx_t *ctx) {
2995
2535
 
2996
2536
  ectx->ismaster.needed = false;
2997
2537
 
2998
- /* The "create" and "createIndexes" command require bypassing on mongocryptd
2999
- * older than version 6.0. */
3000
2538
  if (needs_ismaster_check(ctx)) {
3001
- if (ectx->ismaster.maxwireversion < WIRE_VERSION_SERVER_6) {
3002
- /* Bypass. */
3003
- ctx->nothing_to_do = true;
3004
- ctx->state = MONGOCRYPT_CTX_READY;
3005
- return true;
2539
+ // MONGOCRYPT-429: "create" and "createIndexes" require bypassing on mongocryptd older than version 6.0.
2540
+ if (0 == strcmp(ectx->cmd_name, "create") || 0 == strcmp(ectx->cmd_name, "createIndexes")) {
2541
+ if (ectx->ismaster.maxwireversion < WIRE_VERSION_SERVER_6) {
2542
+ // Bypass auto encryption.
2543
+ // Satisfy schema request with an empty schema.
2544
+ if (!mc_schema_broker_satisfy_remaining_with_empty_schemas(ectx->sb,
2545
+ NULL /* do not cache */,
2546
+ ctx->status)) {
2547
+ return _mongocrypt_ctx_fail(ctx);
2548
+ }
2549
+ ctx->nothing_to_do = true;
2550
+ ctx->state = MONGOCRYPT_CTX_READY;
2551
+ return true;
2552
+ }
2553
+ }
2554
+
2555
+ if (mc_schema_broker_has_multiple_requests(ectx->sb)) {
2556
+ // Ensure mongocryptd supports multiple schemas.
2557
+ if (ectx->ismaster.maxwireversion < WIRE_VERSION_SERVER_8_1) {
2558
+ mongocrypt_status_t *status = ctx->status;
2559
+ CLIENT_ERR("Encrypting '%s' requires multiple schemas. Detected mongocryptd with wire version %" PRId32
2560
+ ", but need %" PRId32 ". Upgrade mongocryptd to 8.1 or newer.",
2561
+ ectx->cmd_name,
2562
+ ectx->ismaster.maxwireversion,
2563
+ WIRE_VERSION_SERVER_8_1);
2564
+ _mongocrypt_ctx_fail(ctx);
2565
+ return false;
2566
+ }
2567
+ }
2568
+ }
2569
+
2570
+ if (ctx->crypt->csfle.okay) {
2571
+ if (mc_schema_broker_has_multiple_requests(ectx->sb)) {
2572
+ // Ensure crypt_shared supports multiple schemas.
2573
+ uint64_t version = ctx->crypt->csfle.get_version();
2574
+ const char *version_str = ctx->crypt->csfle.get_version_str();
2575
+ if (version < CRYPT_SHARED_8_1) {
2576
+ mongocrypt_status_t *status = ctx->status;
2577
+ CLIENT_ERR("Encrypting '%s' requires multiple schemas. Detected crypt_shared with version %s, but "
2578
+ "need 8.1. Upgrade crypt_shared to 8.1 or newer.",
2579
+ ectx->cmd_name,
2580
+ version_str);
2581
+ _mongocrypt_ctx_fail(ctx);
2582
+ return false;
2583
+ }
3006
2584
  }
3007
2585
  }
3008
2586
 
3009
- /* Check if there is an encrypted field config in encrypted_field_config_map
3010
- */
3011
2587
  if (!_fle2_try_encrypted_field_config_from_map(ctx)) {
3012
2588
  return false;
3013
2589
  }
3014
- if (_mongocrypt_buffer_empty(&ectx->encrypted_field_config)) {
2590
+ if (mc_schema_broker_need_more_schemas(ectx->sb)) {
3015
2591
  if (!_try_schema_from_create_or_collMod_cmd(ctx)) {
3016
2592
  return false;
3017
2593
  }
3018
2594
 
3019
2595
  /* Check if we have a local schema from schema_map */
3020
- if (_mongocrypt_buffer_empty(&ectx->schema)) {
2596
+ if (mc_schema_broker_need_more_schemas(ectx->sb)) {
3021
2597
  if (!_try_schema_from_schema_map(ctx)) {
3022
2598
  return false;
3023
2599
  }
3024
2600
  }
3025
2601
 
3026
2602
  /* If we didn't have a local schema, try the cache. */
3027
- if (_mongocrypt_buffer_empty(&ectx->schema)) {
2603
+ if (mc_schema_broker_need_more_schemas(ectx->sb)) {
3028
2604
  if (!_try_schema_from_cache(ctx)) {
3029
2605
  return false;
3030
2606
  }
@@ -3033,12 +2609,12 @@ static bool mongocrypt_ctx_encrypt_ismaster_done(mongocrypt_ctx_t *ctx) {
3033
2609
  /* If we did not have a local or cached schema, check if this is a
3034
2610
  * "create" command. If it is a "create" command, do not run
3035
2611
  * "listCollections" to get a server-side schema. */
3036
- if (_mongocrypt_buffer_empty(&ectx->schema) && !_try_empty_schema_for_create(ctx)) {
2612
+ if (mc_schema_broker_need_more_schemas(ectx->sb) && !_try_empty_schema_for_create(ctx)) {
3037
2613
  return false;
3038
2614
  }
3039
2615
 
3040
2616
  /* Otherwise, we need the the driver to fetch the schema. */
3041
- if (_mongocrypt_buffer_empty(&ectx->schema)) {
2617
+ if (mc_schema_broker_need_more_schemas(ectx->sb)) {
3042
2618
  ctx->state = MONGOCRYPT_CTX_NEED_MONGO_COLLINFO;
3043
2619
  if (ectx->target_db) {
3044
2620
  if (!ctx->crypt->opts.use_need_mongo_collinfo_with_db_state) {
@@ -3055,18 +2631,15 @@ static bool mongocrypt_ctx_encrypt_ismaster_done(mongocrypt_ctx_t *ctx) {
3055
2631
  }
3056
2632
 
3057
2633
  /* If an encrypted_field_config was set, check if keys are required for
3058
- * delete tokens. */
3059
- if (!_fle2_collect_keys_for_deleteTokens(ctx)) {
3060
- return false;
3061
- }
2634
+ * compactionTokens. */
3062
2635
 
3063
- if (!_fle2_collect_keys_for_compaction(ctx)) {
2636
+ if (!mc_schema_broker_need_more_schemas(ectx->sb) && !_fle2_collect_keys_for_compaction(ctx)) {
3064
2637
  return false;
3065
2638
  }
3066
2639
 
3067
2640
  if (ctx->state == MONGOCRYPT_CTX_NEED_MONGO_MARKINGS) {
3068
2641
  if (ectx->bypass_query_analysis) {
3069
- /* Keys may have been requested for deleteTokens or compactionTokens.
2642
+ /* Keys may have been requested for compactionTokens.
3070
2643
  * Finish key requests.
3071
2644
  */
3072
2645
  _mongocrypt_key_broker_requests_done(&ctx->kb);