libmongocrypt-helper 1.8.0.0.1001 → 1.11.0.0.1001

Sign up to get free protection for your applications and to get access to all the features.
Files changed (385) hide show
  1. checksums.yaml +4 -4
  2. data/ext/libmongocrypt/libmongocrypt/CHANGELOG.md +33 -0
  3. data/ext/libmongocrypt/libmongocrypt/CMakeLists.txt +12 -1
  4. data/ext/libmongocrypt/libmongocrypt/CODEOWNERS +1 -4
  5. data/ext/libmongocrypt/libmongocrypt/Earthfile +151 -3
  6. data/ext/libmongocrypt/libmongocrypt/README.md +36 -40
  7. data/ext/libmongocrypt/libmongocrypt/bindings/cs/CMakeLists.txt +1 -0
  8. data/ext/libmongocrypt/libmongocrypt/bindings/cs/MongoDB.Driver.snk +0 -0
  9. data/ext/libmongocrypt/libmongocrypt/bindings/cs/MongoDB.Libmongocrypt/AssemblyInfo.cs +2 -2
  10. data/ext/libmongocrypt/libmongocrypt/bindings/cs/MongoDB.Libmongocrypt/Binary.cs +16 -2
  11. data/ext/libmongocrypt/libmongocrypt/bindings/cs/MongoDB.Libmongocrypt/CryptClientFactory.cs +8 -4
  12. data/ext/libmongocrypt/libmongocrypt/bindings/cs/MongoDB.Libmongocrypt/Library.cs +10 -0
  13. data/ext/libmongocrypt/libmongocrypt/bindings/cs/MongoDB.Libmongocrypt/LibraryLoader.cs +81 -44
  14. data/ext/libmongocrypt/libmongocrypt/bindings/cs/MongoDB.Libmongocrypt/MongoDB.Libmongocrypt.csproj +2 -1
  15. data/ext/libmongocrypt/libmongocrypt/bindings/cs/MongoDB.Libmongocrypt.Test/MongoDB.Libmongocrypt.Test.csproj +2 -0
  16. data/ext/libmongocrypt/libmongocrypt/bindings/cs/MongoDB.Libmongocrypt.Test32/MongoDB.Libmongocrypt.Test32.csproj +2 -0
  17. data/ext/libmongocrypt/libmongocrypt/bindings/cs/README.md +3 -0
  18. data/ext/libmongocrypt/libmongocrypt/bindings/cs/Scripts/build.cake +21 -26
  19. data/ext/libmongocrypt/libmongocrypt/bindings/cs/Scripts/build.config +3 -0
  20. data/ext/libmongocrypt/libmongocrypt/bindings/cs/Scripts/build.sh +0 -0
  21. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/benchmarks/build.gradle.kts +28 -0
  22. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/benchmarks/src/main/java/com/mongodb/crypt/benchmark/BenchmarkRunner.java +217 -0
  23. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/benchmarks/src/main/resources/keyDocument.json +24 -0
  24. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/build.gradle.kts +21 -6
  25. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/gradle/wrapper/gradle-wrapper.jar +0 -0
  26. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/gradle/wrapper/gradle-wrapper.properties +1 -1
  27. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/gradlew +154 -108
  28. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/gradlew.bat +7 -18
  29. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/settings.gradle.kts +1 -0
  30. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/CAPI.java +41 -6
  31. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/CAPIHelper.java +5 -5
  32. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/CipherCallback.java +27 -1
  33. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/MongoCryptImpl.java +34 -19
  34. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/MongoExplicitEncryptOptions.java +6 -4
  35. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/resources/META-INF/native-image/jni-config.json +180 -0
  36. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/main/resources/META-INF/native-image/reflect-config.json +134 -0
  37. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/test/java/com/mongodb/crypt/capi/MongoCryptTest.java +44 -2
  38. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/test/resources/fle2-find-range-explicit-v2/int32/encrypted-payload.json +1 -1
  39. data/ext/libmongocrypt/libmongocrypt/bindings/java/mongocrypt/src/test/resources/fle2-find-range-explicit-v2/int32/rangeopts.json +3 -0
  40. data/ext/libmongocrypt/libmongocrypt/bindings/node/README.md +4 -900
  41. data/ext/libmongocrypt/libmongocrypt/bindings/python/CHANGELOG.rst +60 -0
  42. data/ext/libmongocrypt/libmongocrypt/bindings/python/README.rst +41 -20
  43. data/ext/libmongocrypt/libmongocrypt/bindings/python/RELEASE.rst +6 -24
  44. data/ext/libmongocrypt/libmongocrypt/bindings/python/build-manylinux-wheel.sh +4 -13
  45. data/ext/libmongocrypt/libmongocrypt/bindings/python/hatch_build.py +36 -0
  46. data/ext/libmongocrypt/libmongocrypt/bindings/python/libmongocrypt-version.txt +1 -0
  47. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/__init__.py +2 -2
  48. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/asynchronous/auto_encrypter.py +61 -0
  49. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/asynchronous/credentials.py +156 -0
  50. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/asynchronous/explicit_encrypter.py +156 -0
  51. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/asynchronous/state_machine.py +149 -0
  52. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/auto_encrypter.py +2 -46
  53. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/binary.py +14 -17
  54. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/binding.py +107 -61
  55. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/compat.py +6 -4
  56. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/credentials.py +2 -121
  57. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/crypto.py +31 -20
  58. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/errors.py +2 -2
  59. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/explicit_encrypter.py +2 -233
  60. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/mongocrypt.py +168 -238
  61. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/options.py +265 -0
  62. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/state_machine.py +2 -141
  63. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/synchronous/auto_encrypter.py +61 -0
  64. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/synchronous/credentials.py +156 -0
  65. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/synchronous/explicit_encrypter.py +156 -0
  66. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/synchronous/state_machine.py +149 -0
  67. data/ext/libmongocrypt/libmongocrypt/bindings/python/pymongocrypt/version.py +2 -2
  68. data/ext/libmongocrypt/libmongocrypt/bindings/python/pyproject.toml +118 -0
  69. data/ext/libmongocrypt/libmongocrypt/bindings/python/release.sh +97 -61
  70. data/ext/libmongocrypt/libmongocrypt/bindings/python/{test-requirements.txt → requirements-test.txt} +4 -1
  71. data/ext/libmongocrypt/libmongocrypt/bindings/python/requirements.txt +4 -0
  72. data/ext/libmongocrypt/libmongocrypt/bindings/python/sbom.json +76 -0
  73. data/ext/libmongocrypt/libmongocrypt/bindings/python/strip_header.py +6 -7
  74. data/ext/libmongocrypt/libmongocrypt/bindings/python/synchro.py +64 -0
  75. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/__init__.py +1 -0
  76. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/collection-info.json +1 -1
  77. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/command.json +1 -1
  78. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/compact/success/encrypted-payload.json +21 -21
  79. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/encrypted-command-reply.json +1 -1
  80. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/encrypted-field-config-map.json +1 -1
  81. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/fle2-find-range-explicit-v2/int32/encrypted-payload.json +1 -1
  82. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/fle2-find-range-explicit-v2/int32/rangeopts.json +3 -0
  83. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/fle2-find-rangePreview-explicit/int32/rangeopts.json +11 -0
  84. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/fle2-find-rangePreview-explicit/int32/value-to-encrypt.json +20 -0
  85. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/key-document-azure.json +1 -1
  86. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/key-document-gcp.json +1 -1
  87. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/key-document.json +1 -1
  88. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/key-filter.json +1 -1
  89. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/list-collections-filter.json +1 -1
  90. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/mongocryptd-command.json +1 -1
  91. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/mongocryptd-reply.json +1 -1
  92. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/data/schema-map.json +1 -1
  93. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/performance/keyDocument.json +24 -0
  94. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/performance/perf_test.py +165 -0
  95. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/test_binding.py +8 -12
  96. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/test_crypto.py +9 -11
  97. data/ext/libmongocrypt/libmongocrypt/bindings/python/test/test_mongocrypt.py +988 -340
  98. data/ext/libmongocrypt/libmongocrypt/bindings/python/update-sbom.sh +14 -0
  99. data/ext/libmongocrypt/libmongocrypt/cmake/FetchMongoC.cmake +19 -1
  100. data/ext/libmongocrypt/libmongocrypt/cmake/ImportBSON.cmake +23 -0
  101. data/ext/libmongocrypt/libmongocrypt/cmake/IntelDFP.cmake +19 -227
  102. data/ext/libmongocrypt/libmongocrypt/cmake/Patch.cmake +54 -0
  103. data/ext/libmongocrypt/libmongocrypt/doc/img/cli-icon.png +0 -0
  104. data/ext/libmongocrypt/libmongocrypt/doc/img/reference-targets.png +0 -0
  105. data/ext/libmongocrypt/libmongocrypt/doc/releasing.md +153 -0
  106. data/ext/libmongocrypt/libmongocrypt/etc/calc_release_version.py +61 -28
  107. data/ext/libmongocrypt/libmongocrypt/etc/calc_release_version_selftest.sh +73 -0
  108. data/ext/libmongocrypt/libmongocrypt/etc/cyclonedx.sbom.json +108 -0
  109. data/ext/libmongocrypt/libmongocrypt/etc/format.sh +1 -1
  110. data/ext/libmongocrypt/libmongocrypt/etc/libbson-remove-GCC-diagnostic-pragma.patch +27 -0
  111. data/ext/libmongocrypt/libmongocrypt/etc/mongo-inteldfp-alpine-arm-fix.patch +17 -0
  112. data/ext/libmongocrypt/libmongocrypt/etc/packager.py +120 -91
  113. data/ext/libmongocrypt/libmongocrypt/etc/purls.txt +14 -0
  114. data/ext/libmongocrypt/libmongocrypt/etc/repo_config.yaml +56 -0
  115. data/ext/libmongocrypt/libmongocrypt/etc/silk-create-asset-group.sh +70 -0
  116. data/ext/libmongocrypt/libmongocrypt/etc/ssdlc_compliance_report.md +37 -0
  117. data/ext/libmongocrypt/libmongocrypt/etc/third_party_vulnerabilities.md +42 -0
  118. data/ext/libmongocrypt/libmongocrypt/integrating.md +18 -1
  119. data/ext/libmongocrypt/libmongocrypt/kms-message/CMakeLists.txt +11 -3
  120. data/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_gcp_request.c +1 -1
  121. data/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_kmip_reader_writer.c +17 -0
  122. data/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_kmip_reader_writer_private.h +6 -0
  123. data/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_kmip_request.c +211 -1
  124. data/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_kmip_response.c +163 -0
  125. data/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_kmip_tag_type_private.h +2 -1
  126. data/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_message/kms_kmip_request.h +17 -0
  127. data/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_message/kms_kmip_response.h +6 -0
  128. data/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_port.c +3 -2
  129. data/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_request.c +4 -2
  130. data/ext/libmongocrypt/libmongocrypt/kms-message/src/kms_request_str.c +2 -2
  131. data/ext/libmongocrypt/libmongocrypt/kms-message/test/test_kmip_reader_writer.c +23 -2
  132. data/ext/libmongocrypt/libmongocrypt/src/crypto/libcrypto.c +13 -10
  133. data/ext/libmongocrypt/libmongocrypt/src/mc-dec128.h +1 -1
  134. data/ext/libmongocrypt/libmongocrypt/src/mc-efc-private.h +16 -2
  135. data/ext/libmongocrypt/libmongocrypt/src/mc-efc.c +94 -6
  136. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-encryption-placeholder-private.h +15 -5
  137. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-encryption-placeholder.c +114 -53
  138. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-equality-payload-private-v2.h +1 -1
  139. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-equality-payload-private.h +1 -1
  140. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-equality-payload-v2.c +2 -2
  141. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-equality-payload.c +2 -2
  142. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-range-payload-private-v2.h +21 -6
  143. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-range-payload-private.h +5 -5
  144. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-range-payload-v2.c +38 -2
  145. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-find-range-payload.c +1 -1
  146. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-insert-update-payload-private-v2.h +20 -7
  147. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-insert-update-payload-private.h +8 -8
  148. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-insert-update-payload-v2.c +89 -1
  149. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-payload-iev-v2.c +3 -3
  150. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-payload-iev.c +1 -23
  151. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-rfds-private.h +4 -3
  152. data/ext/libmongocrypt/libmongocrypt/src/mc-fle2-rfds.c +15 -12
  153. data/ext/libmongocrypt/libmongocrypt/src/mc-optional-private.h +11 -0
  154. data/ext/libmongocrypt/libmongocrypt/src/mc-range-edge-generation-private.h +16 -6
  155. data/ext/libmongocrypt/libmongocrypt/src/mc-range-edge-generation.c +64 -22
  156. data/ext/libmongocrypt/libmongocrypt/src/mc-range-encoding-private.h +23 -4
  157. data/ext/libmongocrypt/libmongocrypt/src/mc-range-encoding.c +359 -65
  158. data/ext/libmongocrypt/libmongocrypt/src/mc-range-mincover-generator.template.h +26 -14
  159. data/ext/libmongocrypt/libmongocrypt/src/mc-range-mincover-private.h +17 -6
  160. data/ext/libmongocrypt/libmongocrypt/src/mc-range-mincover.c +31 -13
  161. data/ext/libmongocrypt/libmongocrypt/src/mc-rangeopts-private.h +16 -3
  162. data/ext/libmongocrypt/libmongocrypt/src/mc-rangeopts.c +259 -63
  163. data/ext/libmongocrypt/libmongocrypt/src/mc-tokens-private.h +40 -24
  164. data/ext/libmongocrypt/libmongocrypt/src/mc-tokens.c +57 -13
  165. data/ext/libmongocrypt/libmongocrypt/src/mlib/int128.h +17 -0
  166. data/ext/libmongocrypt/libmongocrypt/src/mlib/int128.test.cpp +5 -0
  167. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-binary-private.h +0 -5
  168. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-buffer.c +5 -7
  169. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-cache-key.c +1 -0
  170. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-cache-oauth-private.h +16 -18
  171. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-cache-oauth.c +105 -76
  172. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-crypto.c +9 -3
  173. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ctx-datakey.c +170 -89
  174. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ctx-decrypt.c +5 -5
  175. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ctx-encrypt.c +505 -124
  176. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ctx-private.h +31 -6
  177. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-ctx.c +81 -13
  178. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-dll-private.h +7 -0
  179. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-kek-private.h +5 -1
  180. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-kek.c +161 -103
  181. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-key-broker-private.h +2 -7
  182. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-key-broker.c +191 -69
  183. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-key.c +1 -1
  184. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-kms-ctx-private.h +50 -15
  185. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-kms-ctx.c +365 -69
  186. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-marking-private.h +2 -1
  187. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-marking.c +200 -107
  188. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-opts-private.h +50 -5
  189. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-opts.c +591 -15
  190. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-private.h +6 -13
  191. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt-util.c +3 -2
  192. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt.c +47 -234
  193. data/ext/libmongocrypt/libmongocrypt/src/mongocrypt.h +75 -24
  194. data/ext/libmongocrypt/libmongocrypt/src/os_posix/os_dll.c +18 -2
  195. data/ext/libmongocrypt/libmongocrypt/src/os_win/os_dll.c +4 -0
  196. data/ext/libmongocrypt/libmongocrypt/test/data/bulkWrite/bypassQueryAnalysis/payload.json +53 -0
  197. data/ext/libmongocrypt/libmongocrypt/test/data/bulkWrite/jsonSchema/cmd-to-mongocryptd.json +23 -0
  198. data/ext/libmongocrypt/libmongocrypt/test/data/bulkWrite/jsonSchema/cmd.json +20 -0
  199. data/ext/libmongocrypt/libmongocrypt/test/data/bulkWrite/simple/cmd-to-mongocryptd.json +50 -0
  200. data/ext/libmongocrypt/libmongocrypt/test/data/bulkWrite/simple/cmd.json +20 -0
  201. data/ext/libmongocrypt/libmongocrypt/test/data/bulkWrite/simple/collinfo.json +44 -0
  202. data/ext/libmongocrypt/libmongocrypt/test/data/bulkWrite/simple/encrypted-field-map.json +24 -0
  203. data/ext/libmongocrypt/libmongocrypt/test/data/bulkWrite/simple/encrypted-payload-pattern.json +53 -0
  204. data/ext/libmongocrypt/libmongocrypt/test/data/bulkWrite/simple/mongocryptd-reply.json +62 -0
  205. data/ext/libmongocrypt/libmongocrypt/test/data/bulkWrite/unencrypted/cmd-to-mongocryptd.json +30 -0
  206. data/ext/libmongocrypt/libmongocrypt/test/data/bulkWrite/unencrypted/cmd.json +17 -0
  207. data/ext/libmongocrypt/libmongocrypt/test/data/bulkWrite/unencrypted/mongocryptd-reply.json +39 -0
  208. data/ext/libmongocrypt/libmongocrypt/test/data/bulkWrite/unencrypted/payload.json +21 -0
  209. data/ext/libmongocrypt/libmongocrypt/test/data/cleanup/missing-key-id/collinfo.json +20 -0
  210. data/ext/libmongocrypt/libmongocrypt/test/data/cleanup/no-fields/collinfo.json +9 -0
  211. data/ext/libmongocrypt/libmongocrypt/test/data/cleanup/no-fields/encrypted-payload.json +4 -0
  212. data/ext/libmongocrypt/libmongocrypt/test/data/cleanup/success/cmd.json +1 -0
  213. data/ext/libmongocrypt/libmongocrypt/test/data/cleanup/success/collinfo.json +63 -0
  214. data/ext/libmongocrypt/libmongocrypt/test/data/cleanup/success/encrypted-field-config-map.json +61 -0
  215. data/ext/libmongocrypt/libmongocrypt/test/data/cleanup/success/encrypted-payload-range-v2.json +37 -0
  216. data/ext/libmongocrypt/libmongocrypt/test/data/cleanup/success/encrypted-payload.json +29 -0
  217. data/ext/libmongocrypt/libmongocrypt/test/data/compact/anchor-pad/cmd.json +1 -0
  218. data/ext/libmongocrypt/libmongocrypt/test/data/compact/anchor-pad/collinfo.json +64 -0
  219. data/ext/libmongocrypt/libmongocrypt/test/data/compact/anchor-pad/encrypted-payload-range-v2.json +105 -0
  220. data/ext/libmongocrypt/libmongocrypt/test/data/compact/anchor-pad/encrypted-payload.json +30 -0
  221. data/ext/libmongocrypt/libmongocrypt/test/data/compact/no-range/cmd.json +1 -0
  222. data/ext/libmongocrypt/libmongocrypt/test/data/compact/no-range/collinfo.json +49 -0
  223. data/ext/libmongocrypt/libmongocrypt/test/data/compact/no-range/encrypted-field-config-map.json +47 -0
  224. data/ext/libmongocrypt/libmongocrypt/test/data/compact/no-range/encrypted-payload.json +23 -0
  225. data/ext/libmongocrypt/libmongocrypt/test/data/compact/success/collinfo.json +15 -0
  226. data/ext/libmongocrypt/libmongocrypt/test/data/compact/success/encrypted-field-config-map.json +10 -0
  227. data/ext/libmongocrypt/libmongocrypt/test/data/compact/success/encrypted-payload-range-v2.json +104 -0
  228. data/ext/libmongocrypt/libmongocrypt/test/data/compact/success/encrypted-payload.json +6 -0
  229. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-explain/with-csfle/collinfo.json +4 -4
  230. data/ext/libmongocrypt/libmongocrypt/test/data/fle2-explain/with-csfle/encrypted-payload.json +3 -3
  231. data/ext/libmongocrypt/libmongocrypt/test/data/kms-azure/decrypt-response.txt +16 -0
  232. data/ext/libmongocrypt/libmongocrypt/test/data/kms-azure/encrypt-response.txt +16 -0
  233. data/ext/libmongocrypt/libmongocrypt/test/data/kms-azure/oauth-response.txt +19 -0
  234. data/ext/libmongocrypt/libmongocrypt/test/data/no-trimFactor/find/cmd.json +9 -0
  235. data/ext/libmongocrypt/libmongocrypt/test/data/no-trimFactor/find/encrypted-field-map.json +19 -0
  236. data/ext/libmongocrypt/libmongocrypt/test/data/no-trimFactor/find/encrypted-payload.json +62 -0
  237. data/ext/libmongocrypt/libmongocrypt/test/data/no-trimFactor/find/mongocryptd-reply.json +69 -0
  238. data/ext/libmongocrypt/libmongocrypt/test/data/no-trimFactor/insert/cmd.json +11 -0
  239. data/ext/libmongocrypt/libmongocrypt/test/data/no-trimFactor/insert/encrypted-field-map.json +19 -0
  240. data/ext/libmongocrypt/libmongocrypt/test/data/no-trimFactor/insert/encrypted-payload.json +40 -0
  241. data/ext/libmongocrypt/libmongocrypt/test/data/no-trimFactor/insert/mongocryptd-reply.json +47 -0
  242. data/ext/libmongocrypt/libmongocrypt/test/data/range-edge-generation/edges_decimal128.cstruct +1 -1
  243. data/ext/libmongocrypt/libmongocrypt/test/data/range-edge-generation/edges_double.cstruct +8637 -7958
  244. data/ext/libmongocrypt/libmongocrypt/test/data/range-edge-generation/edges_int32.cstruct +5522 -1382
  245. data/ext/libmongocrypt/libmongocrypt/test/data/range-edge-generation/edges_int64.cstruct +5042 -1262
  246. data/ext/libmongocrypt/libmongocrypt/test/data/range-min-cover/mincover_decimal128.cstruct +1 -1
  247. data/ext/libmongocrypt/libmongocrypt/test/data/range-min-cover/mincover_decimal128_precision.cstruct +1 -1
  248. data/ext/libmongocrypt/libmongocrypt/test/data/range-min-cover/mincover_double.cstruct +1 -1
  249. data/ext/libmongocrypt/libmongocrypt/test/data/range-min-cover/mincover_double_precision.cstruct +2 -2
  250. data/ext/libmongocrypt/libmongocrypt/test/data/range-min-cover/mincover_int32.cstruct +1 -1
  251. data/ext/libmongocrypt/libmongocrypt/test/data/range-min-cover/mincover_int64.cstruct +1 -1
  252. data/ext/libmongocrypt/libmongocrypt/test/data/range-sends-cryptoParams/auto-find-int32/cmd.json +8 -0
  253. data/ext/libmongocrypt/libmongocrypt/test/data/range-sends-cryptoParams/auto-find-int32/encrypted-field-map.json +19 -0
  254. data/ext/libmongocrypt/libmongocrypt/test/data/range-sends-cryptoParams/auto-find-int32/encrypted-payload.json +53 -0
  255. data/ext/libmongocrypt/libmongocrypt/test/data/range-sends-cryptoParams/auto-find-int32/mongocryptd-reply.json +58 -0
  256. data/ext/libmongocrypt/libmongocrypt/test/data/range-sends-cryptoParams/auto-insert-int32/cmd.json +11 -0
  257. data/ext/libmongocrypt/libmongocrypt/test/data/range-sends-cryptoParams/auto-insert-int32/encrypted-field-map.json +19 -0
  258. data/ext/libmongocrypt/libmongocrypt/test/data/range-sends-cryptoParams/auto-insert-int32/encrypted-payload.json +40 -0
  259. data/ext/libmongocrypt/libmongocrypt/test/data/range-sends-cryptoParams/auto-insert-int32/mongocryptd-reply.json +45 -0
  260. data/ext/libmongocrypt/libmongocrypt/test/data/range-sends-cryptoParams/explicit-find-int32/expected.json +26 -0
  261. data/ext/libmongocrypt/libmongocrypt/test/data/range-sends-cryptoParams/explicit-find-int32/to-encrypt.json +20 -0
  262. data/ext/libmongocrypt/libmongocrypt/test/data/range-sends-cryptoParams/explicit-find-int32-defaults/expected.json +26 -0
  263. data/ext/libmongocrypt/libmongocrypt/test/data/range-sends-cryptoParams/explicit-find-int32-defaults/to-encrypt.json +20 -0
  264. data/ext/libmongocrypt/libmongocrypt/test/data/range-sends-cryptoParams/explicit-insert-double/expected.json +8 -0
  265. data/ext/libmongocrypt/libmongocrypt/test/data/range-sends-cryptoParams/explicit-insert-int32/expected.json +8 -0
  266. data/ext/libmongocrypt/libmongocrypt/test/data/range-sends-cryptoParams/explicit-insert-int32-defaults/expected.json +8 -0
  267. data/ext/libmongocrypt/libmongocrypt/test/data/tokens/README.md +7 -4
  268. data/ext/libmongocrypt/libmongocrypt/test/data/tokens/mc.json +9 -5
  269. data/ext/libmongocrypt/libmongocrypt/test/data/tokens/server.json +9 -5
  270. data/ext/libmongocrypt/libmongocrypt/test/example-state-machine.c +1 -0
  271. data/ext/libmongocrypt/libmongocrypt/test/test-gcp-auth.c +8 -8
  272. data/ext/libmongocrypt/libmongocrypt/test/test-mc-efc.c +6 -4
  273. data/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-find-range-payload-v2.c +43 -3
  274. data/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-payload-iup-v2.c +76 -0
  275. data/ext/libmongocrypt/libmongocrypt/test/test-mc-fle2-rfds.c +5 -5
  276. data/ext/libmongocrypt/libmongocrypt/test/test-mc-range-edge-generation.c +89 -14
  277. data/ext/libmongocrypt/libmongocrypt/test/test-mc-range-encoding.c +342 -76
  278. data/ext/libmongocrypt/libmongocrypt/test/test-mc-range-mincover.c +94 -12
  279. data/ext/libmongocrypt/libmongocrypt/test/test-mc-rangeopts.c +205 -7
  280. data/ext/libmongocrypt/libmongocrypt/test/test-mc-tokens.c +49 -23
  281. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-assert-match-bson.c +16 -19
  282. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-assert-match-bson.h +22 -1
  283. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-cache-oauth.c +94 -11
  284. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-cleanup.c +374 -0
  285. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-compact.c +121 -42
  286. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-crypto-hooks.c +134 -4
  287. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-crypto-std-hooks.c +40 -0
  288. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-crypto-std-hooks.h +16 -0
  289. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-csfle-lib.c +11 -11
  290. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-ctx-decrypt.c +8 -5
  291. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-ctx-encrypt.c +922 -92
  292. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-ctx-rewrap-many-datakey.c +2 -2
  293. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-ctx-setopt.c +114 -12
  294. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-datakey.c +14 -9
  295. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-kms-ctx.c +424 -3
  296. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-log.c +1 -1
  297. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-marking.c +447 -28
  298. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-opts.c +42 -0
  299. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-traverse-util.c +30 -26
  300. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-util.c +7 -0
  301. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt-util.h +3 -0
  302. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt.c +66 -14
  303. data/ext/libmongocrypt/libmongocrypt/test/test-mongocrypt.h +11 -0
  304. data/ext/libmongocrypt/libmongocrypt/test/test-named-kms-providers.c +2381 -0
  305. data/ext/libmongocrypt/libmongocrypt/test/util/HELP.autogen +3 -1
  306. data/ext/libmongocrypt/libmongocrypt/test/util/README.md +1 -0
  307. data/ext/libmongocrypt/libmongocrypt/test/util/csfle.c +4 -0
  308. data/ext/libmongocrypt/libmongocrypt/test/util/make_includes.py +1 -1
  309. data/ext/libmongocrypt/libmongocrypt/test/util/util.c +38 -3
  310. data/lib/libmongocrypt_helper/version.rb +2 -2
  311. metadata +112 -106
  312. checksums.yaml.gz.sig +0 -0
  313. data/ext/libmongocrypt/libmongocrypt/VERSION_CURRENT +0 -1
  314. data/ext/libmongocrypt/libmongocrypt/bindings/cs/cs.sln +0 -79
  315. data/ext/libmongocrypt/libmongocrypt/bindings/node/CHANGELOG.md +0 -105
  316. data/ext/libmongocrypt/libmongocrypt/bindings/node/LICENSE +0 -201
  317. data/ext/libmongocrypt/libmongocrypt/bindings/node/binding.gyp +0 -79
  318. data/ext/libmongocrypt/libmongocrypt/bindings/node/etc/README.hbs +0 -44
  319. data/ext/libmongocrypt/libmongocrypt/bindings/node/etc/build-static.sh +0 -36
  320. data/ext/libmongocrypt/libmongocrypt/bindings/node/index.d.ts +0 -641
  321. data/ext/libmongocrypt/libmongocrypt/bindings/node/lib/autoEncrypter.js +0 -420
  322. data/ext/libmongocrypt/libmongocrypt/bindings/node/lib/buffer_pool.js +0 -123
  323. data/ext/libmongocrypt/libmongocrypt/bindings/node/lib/clientEncryption.js +0 -821
  324. data/ext/libmongocrypt/libmongocrypt/bindings/node/lib/common.js +0 -98
  325. data/ext/libmongocrypt/libmongocrypt/bindings/node/lib/cryptoCallbacks.js +0 -87
  326. data/ext/libmongocrypt/libmongocrypt/bindings/node/lib/errors.js +0 -75
  327. data/ext/libmongocrypt/libmongocrypt/bindings/node/lib/index.js +0 -73
  328. data/ext/libmongocrypt/libmongocrypt/bindings/node/lib/mongocryptdManager.js +0 -66
  329. data/ext/libmongocrypt/libmongocrypt/bindings/node/lib/providers/aws.js +0 -26
  330. data/ext/libmongocrypt/libmongocrypt/bindings/node/lib/providers/azure.js +0 -178
  331. data/ext/libmongocrypt/libmongocrypt/bindings/node/lib/providers/gcp.js +0 -24
  332. data/ext/libmongocrypt/libmongocrypt/bindings/node/lib/providers/index.js +0 -54
  333. data/ext/libmongocrypt/libmongocrypt/bindings/node/lib/providers/utils.js +0 -39
  334. data/ext/libmongocrypt/libmongocrypt/bindings/node/lib/stateMachine.js +0 -492
  335. data/ext/libmongocrypt/libmongocrypt/bindings/node/package-lock.json +0 -15302
  336. data/ext/libmongocrypt/libmongocrypt/bindings/node/package.json +0 -100
  337. data/ext/libmongocrypt/libmongocrypt/bindings/node/src/mongocrypt.cc +0 -956
  338. data/ext/libmongocrypt/libmongocrypt/bindings/node/src/mongocrypt.h +0 -114
  339. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/autoEncrypter.test.js +0 -950
  340. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/buffer_pool.test.js +0 -91
  341. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/clientEncryption.test.js +0 -1093
  342. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/common.test.js +0 -94
  343. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/cryptoCallbacks.test.js +0 -240
  344. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/data/README.md +0 -5
  345. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/data/cmd.json +0 -6
  346. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/data/collection-info.json +0 -37
  347. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/data/encrypted-document-nested.json +0 -8
  348. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/data/encrypted-document.json +0 -11
  349. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/data/encryptedFields.json +0 -30
  350. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/data/key-document.json +0 -32
  351. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/data/key1-document.json +0 -30
  352. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/data/mongocryptd-reply.json +0 -18
  353. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/index.test.js +0 -45
  354. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/mongocryptdManager.test.js +0 -48
  355. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/providers/credentialsProvider.test.js +0 -551
  356. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/release.test.js +0 -66
  357. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/requirements.helper.js +0 -51
  358. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/stateMachine.test.js +0 -331
  359. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/tools/chai-addons.js +0 -8
  360. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/tools/mongodb_reporter.js +0 -325
  361. data/ext/libmongocrypt/libmongocrypt/bindings/node/test/types/index.test-d.ts +0 -63
  362. data/ext/libmongocrypt/libmongocrypt/bindings/python/setup.py +0 -89
  363. data/ext/libmongocrypt/libmongocrypt/debian/build_snapshot.sh +0 -79
  364. data/ext/libmongocrypt/libmongocrypt/debian/changelog +0 -105
  365. data/ext/libmongocrypt/libmongocrypt/debian/compat +0 -1
  366. data/ext/libmongocrypt/libmongocrypt/debian/control +0 -41
  367. data/ext/libmongocrypt/libmongocrypt/debian/copyright +0 -129
  368. data/ext/libmongocrypt/libmongocrypt/debian/gbp.conf +0 -23
  369. data/ext/libmongocrypt/libmongocrypt/debian/libmongocrypt-dev.dirs +0 -2
  370. data/ext/libmongocrypt/libmongocrypt/debian/libmongocrypt-dev.install +0 -5
  371. data/ext/libmongocrypt/libmongocrypt/debian/libmongocrypt0.dirs +0 -1
  372. data/ext/libmongocrypt/libmongocrypt/debian/libmongocrypt0.install +0 -1
  373. data/ext/libmongocrypt/libmongocrypt/debian/rules +0 -46
  374. data/ext/libmongocrypt/libmongocrypt/debian/source/format +0 -1
  375. data/ext/libmongocrypt/libmongocrypt/debian/source/lintian-overrides +0 -3
  376. data/ext/libmongocrypt/libmongocrypt/debian/source/options +0 -1
  377. data/ext/libmongocrypt/libmongocrypt/debian/watch +0 -3
  378. data/ext/libmongocrypt/libmongocrypt/test/data/compact/success/mongocryptd-reply.json +0 -72
  379. data.tar.gz.sig +0 -1
  380. metadata.gz.sig +0 -0
  381. /data/ext/libmongocrypt/libmongocrypt/{bindings/node/test/data/kms-decrypt-reply.txt → test/data/kms-aws/decrypt-response.txt} +0 -0
  382. /data/ext/libmongocrypt/libmongocrypt/{bindings/node/test/data/kms-encrypt-reply.txt → test/data/kms-aws/encrypt-response.txt} +0 -0
  383. /data/ext/libmongocrypt/libmongocrypt/test/data/{gcp-auth → kms-gcp}/decrypt-response.txt +0 -0
  384. /data/ext/libmongocrypt/libmongocrypt/test/data/{gcp-auth → kms-gcp}/encrypt-response.txt +0 -0
  385. /data/ext/libmongocrypt/libmongocrypt/test/data/{gcp-auth → kms-gcp}/oauth-response.txt +0 -0
@@ -0,0 +1,2381 @@
1
+ /*
2
+ * Copyright 2023-present MongoDB, Inc.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ #include <mongocrypt-opts-private.h>
18
+
19
+ #include <test-mongocrypt-assert-match-bson.h>
20
+ #include <test-mongocrypt.h>
21
+
22
+ #define LOCAL_KEK1_BASE64 \
23
+ "+ol0TFyLuVvKFSqGzOFGuaOGQnnyfAqalhOv3II/VSxQTCORCGhOmw/IxhthGx0r" \
24
+ "2R/NpMWc91qQ8Ieho4QuE9ucToTnpJ4OquFpdZv2IcO4gey3ecZGCl9jPDig8F+a"
25
+
26
+ #define LOCAL_KEK2_BASE64 \
27
+ "yPSpsO8FoVkmt+qdTDnw/pJaKriwfI6NLD1yse3BZLd3ZcXb3rAVJEA+/yu/vPzE" \
28
+ "8ju7OYTV63AwfLor8Hg9qzo8lyYC6H3RSfdJ9g9aXdCRfGZJgpbpchJUjR06JMLR"
29
+
30
+ // clang-format off
31
+ // GCP_PRIVATEKEY1 was generated with: `openssl genrsa -out private-key.pem 2048`
32
+ #define GCP_PRIVATEKEY1 "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCaqoCoH23dVS8see2DPOpHF3VHtKrXED2zcTkr+C15dDsw3hEl7123xwby/nSg08TMN9uzWkTaIP/CRNhN/VO3dmlCoRy/1Tyx8r3P7mELNPv7X6FP3MgcRMwSesvp7RYnTsImxQ6c48yTd2a4KnjFkJ9HkbOdxjoK2FENwPMdKNgU66XdzqIJBTeqSmx4FuTKdjQm3wi6vHYZgkZ1CKn90oDzpUwwIk3O4614Hxw8Gq40HgpwuTxKLFmfEgqyTHn54pw7plVivwwaUE2tXv3T4TIb0C8J9qquRtWSJuBVBM7yNucsNuWIXzW9jOT6PGcK30OIpkmf6n0Ib2pgY+WhAgMBAAECggEADypgDGwtg4YEZsPrX0KYNcGV90KevFEMPcXAvYAbpGS6X5WswIeerMQkGSxMbw8oxT4GackUhn91GJ1TyNzpyivfESCXXzOHXKsAw+xbwWOwABNdz8UGLahsyrSV/VFpKlBJjw/kOYvILd8HuE/40OV4CsZdgn9TBmh01SiJ5h5JtRP+kZycYluiUo0zLBReI8bpFPnWlCBDJJPE+UpFUCcifw/2xTkACJChtLmDDJ3NkUYACWQZ8HDf3UG3yE+OAGtP27srn1DYs6aNsr/dGfVU6Lu1mO8HswlSm4XHckdVdEmPaj/g5+TGBidnli8yMOhaPk5oDyD0DSltz4Ss2QKBgQDQ8xkFOCPQxnj6eO0s/8SXfoLQyCpHLqXNF7rw5H6VHo+5iyOt146XeLJNQeTYi/JX6bAlyPfc51ESZsjG1NucyLToJf7+Q+o/w/dNq3eNvGH1rxfYdalD4woQL+JQcgnelnMInyTCPS7drXbugl2AH2JzbwwyBHMB5KeW9paXSQKBgQC9fjo9G/ULae+w27aGSOYCnaFb0LlOJ5merjaZF3GkZPE3RhGIY19C2HRcjre4qRZbrPqyLkF8hoiLMTEd+n+vn8jUQaw/A67tVS1egnJlhut8BcFxW/jhmE80fIzRfxtRQhB/mevxTAIhhLUks3I7CZAjUabx9F+RAYLg3ZCjmQKBgBaj0Hk1TQQpDSCui5xNlkKH7aqrlZEi58oiIRpK18BWkGIdRl9mtMeKx18Bnccs2rRV2MUvUlP4KFujEWwh0i3ZvWhN/aQVPcNs+1XKF2kfGUoij6XfkdiOOB/q4E2xHYqlqI8tlzEIqhRQ4EsViwX/4I37YUnmG4P//3ym+UgpAoGAUMAx4UjArBSA6EU5CxCVtBeoY5AW549Ij6595c9vxjad9IgPgKeYOMw1ChxnfnHP7VFRpAzCK2bJWUelPrk5IIZe9tTlqhTPvqPFqbi9Nza/syJgxQYEkV5uoldRSxV3drFIhpf5S+KwJch/yRwPWclBe0uYcRNKhmi2dUz2DkECgYB4MazvGlNzdAGGt9ah+Ytq0ZZLaJlZMjlNZdsmiWn3Lhxy/l3ibTb1vALo7rQoH3Fpb55B+aiEPMtWVx0yVeIBaHmxQ+Q1Qes8vkL0ONAc4ZUPN9IVu2l8TE+cM6qzoZjpJMwK/JiFmqkE/Gss7gBgCr5JEQrXj2VecBSAcZXMwA=="
33
+ // GCP_PRIVATEKEY2 was generated with: `openssl genrsa -out private-key.pem 2048`
34
+ #define GCP_PRIVATEKEY2 "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC4OWLdpC6AKXjskPiMa/oomIlT5RqeDvcDjQBKyhBTJ8cj3brB4xTBYVNAjBuHZeD8hKGs+6m4PPBxFEt5i7dPZNQZzDJ8Gk4xEkL4Ukgzx1rYwAI1f/Ef45gqUGZJC/kSCAUoGG5FUr+o23W6OCrx302ZVPGB+MbvO6cuTv6DlpHw3w9djpy4l6aMlj+JFCKnR7ai9yoAia8IYa0edMPi2HxdQZziHdlkw3wp+jBvN/706a24TzZKa1ewz2K2lQlc8G2iLy9+AcbHwYKo07ETKmu5azOr4yJ47aC2+SnXQzSFmDOJVTAq8/PXNQVscialqOdwMVpnWE5AFw/DxJibAgMBAAECgf9IZdgVXa7+XTg7lEWWkpdCZ9Xcdu44JJOiVwtcInRCexBzRoy5qv6w3+iIzzUzZXbyihHOhKCNkzm5uX6z1er1nP7OCV5xIEdpSEll60dUDH7gc6UurX3b/MPCauwT5CCphb63gyO9BNWkfk5Qt7HGyQ3/bVo/8u7TqJsYeeKA9B5j6LrnW/gITJGOSzq9j3PpWTMGbi0T57tMBZhRmncZ4jfDruXvPsZlXFnV2sfbtgCzpaOfAQ/CKa5PHz382b7sitEoKuwtYVBrTxLKTTUhRneGaK47lhBFsbEtqhicVYOUfplgE/wLrhmFcjRkmxAzPYq89QfaQ60LGiBrMUUCgYEA5NrMJgvife4DdhtFR2yiN3ufXJtqvMUtfZZAZoPD7fVz0VSwYEfkhuNCtt0U6CD3xjpWFOL372YycNI+apyhL3kL2Jnrpsh5mjjCnLoFqKVVgTWK9GFNSzVeO9LNjGJpR1nZDorZ2FHeUW4SAfMs5b1wek7xAnPrNHYEE8TgRx8CgYEAzhNgl++WWvj/pLKwLc/Gxz03rOoXYPnAnsfyO4g9F883Ps9uVgTro9EKeD9n+nPRbSRISZExe5P8EVUXrIpviO3oHE7fvdzoBfr2Vf5c/qQ0anD47RJODjJyKwrkuWxkxotPDWU/msZdyO7hf3v5BxevrP0Bzg2+zmbVE3dvKwUCgYEAt+Gdusw91hVSLqnGxpbg2Fe6OjyeTMLZxFjfsf8ZhK99uaqkdRgO5NrhlfCZhdJHg70HwYyEzpR83u3vPNZRJMXL4OP71myqWGJW7HsDZPhDdahB2A3+fvmIl+TPR4cjNDNbFjY2x3sweJlKWsq7PnUyVPPs7p2ZVPOmXwQHeN0CgYATslZxLz03xMTqgQnF1y4wrPE9XcKOSlDW3FWSyxrLw8qL/leVcTL0nW5av/S4Q4mo3Obr4SzRmvtkzLVOkIzIkbS1v/QyuYKTz8DrxzwsOpWn9tRUFIPRZ5Dx/ECQWIPpVjdgGGVT7dHY+rwi6z6KJwFrj2M0xquOHtYO3kOJ4QKBgQDDHjZTAyzMVWJiUDI6ENSKqTUDQh/UxI1zpMxp9qoHUwO8iHF4BLastquvK/sUuRbF6mI6z9/theDEqzP5Ytd5YrD2QOBJQhX8NDmO575+N7AldsxupVqjJWrivWo/cJMOwhLZ+OHLJjkfrZQSDjg70gS7AsFeLweLO3Aa9thVYw=="
35
+ // clang-format on
36
+
37
+ #define BSON_STR(...) #__VA_ARGS__
38
+
39
+ // `kmip_get_operation_type` returns a string representation of an Operation in a KMIP request.
40
+ // Useful for tests wanting to assert the type of KMIP request contained in a `mongocrypt_kms_ctx_t`.
41
+ static const char *kmip_get_operation_type(mongocrypt_binary_t *bin) {
42
+ // Convert to hex for easier searching with `strstr`.
43
+ char *as_hex = data_to_hex(mongocrypt_binary_data(bin), mongocrypt_binary_len(bin));
44
+ const char *needle = "42005c" // Tag=Operation
45
+ "05" // Type=Enum
46
+ "00000004" // Length
47
+ "000000"; // First three bytes of four byte value.
48
+ char *found = strstr(as_hex, needle);
49
+ if (!found) {
50
+ bson_free(as_hex);
51
+ return "Not found";
52
+ }
53
+ // Read the next two hex characters.
54
+ found += strlen(needle);
55
+ const char *got = "Unknown";
56
+ // Refer to section 9.1.3.2.26 of KMIP 1.0 specification for the Operation values.
57
+ if (0 == strncmp(found, "01", 2)) {
58
+ got = "Create";
59
+ } else if (0 == strncmp(found, "02", 2)) {
60
+ got = "Create_Key_Pair";
61
+ } else if (0 == strncmp(found, "03", 2)) {
62
+ got = "Register";
63
+ } else if (0 == strncmp(found, "04", 2)) {
64
+ got = "Rekey";
65
+ } else if (0 == strncmp(found, "05", 2)) {
66
+ got = "Derive_Key";
67
+ } else if (0 == strncmp(found, "06", 2)) {
68
+ got = "Certify";
69
+ } else if (0 == strncmp(found, "07", 2)) {
70
+ got = "Recertify";
71
+ } else if (0 == strncmp(found, "08", 2)) {
72
+ got = "Locate";
73
+ } else if (0 == strncmp(found, "09", 2)) {
74
+ got = "Check";
75
+ } else if (0 == strncmp(found, "0a", 2)) {
76
+ got = "Get";
77
+ } else if (0 == strncmp(found, "0b", 2)) {
78
+ got = "Get_Attributes";
79
+ } else if (0 == strncmp(found, "0c", 2)) {
80
+ got = "Get_Attribute_List";
81
+ } else if (0 == strncmp(found, "0d", 2)) {
82
+ got = "Add_Attribute";
83
+ } else if (0 == strncmp(found, "0e", 2)) {
84
+ got = "Modify_Attribute";
85
+ } else if (0 == strncmp(found, "0f", 2)) {
86
+ got = "Delete_Attribute";
87
+ } else if (0 == strncmp(found, "10", 2)) {
88
+ got = "Obtain_Lease";
89
+ } else if (0 == strncmp(found, "11", 2)) {
90
+ got = "Get_Usage_Allocation";
91
+ } else if (0 == strncmp(found, "12", 2)) {
92
+ got = "Activate";
93
+ } else if (0 == strncmp(found, "13", 2)) {
94
+ got = "Revoke";
95
+ } else if (0 == strncmp(found, "14", 2)) {
96
+ got = "Destroy";
97
+ } else if (0 == strncmp(found, "15", 2)) {
98
+ got = "Archive";
99
+ } else if (0 == strncmp(found, "16", 2)) {
100
+ got = "Recover";
101
+ } else if (0 == strncmp(found, "17", 2)) {
102
+ got = "Validate";
103
+ } else if (0 == strncmp(found, "18", 2)) {
104
+ got = "Query";
105
+ } else if (0 == strncmp(found, "19", 2)) {
106
+ got = "Cancel";
107
+ } else if (0 == strncmp(found, "1a", 2)) {
108
+ got = "Poll";
109
+ } else if (0 == strncmp(found, "1b", 2)) {
110
+ got = "Notify";
111
+ } else if (0 == strncmp(found, "1c", 2)) {
112
+ got = "Put";
113
+ }
114
+ bson_free(as_hex);
115
+ return got;
116
+ }
117
+
118
+ /*
119
+ clang-format off
120
+
121
+ `KMIP_REGISTER_RESPONSE` represents:
122
+
123
+ <ResponseMessage tag="0x42007b" type="Structure">
124
+ <ResponseHeader tag="0x42007a" type="Structure">
125
+ <ProtocolVersion tag="0x420069" type="Structure">
126
+ <ProtocolVersionMajor tag="0x42006a" type="Integer" value="1"/>
127
+ <ProtocolVersionMinor tag="0x42006b" type="Integer" value="0"/>
128
+ </ProtocolVersion>
129
+ <TimeStamp tag="0x420092" type="DateTime" value="2023-12-20T13:28:43-0500"/>
130
+ <BatchCount tag="0x42000d" type="Integer" value="1"/>
131
+ </ResponseHeader>
132
+ <BatchItem tag="0x42000f" type="Structure">
133
+ <Operation tag="0x42005c" type="Enumeration" value="3"/>
134
+ <ResultStatus tag="0x42007f" type="Enumeration" value="0"/>
135
+ <ResponsePayload tag="0x42007c" type="Structure">
136
+ <UniqueIdentifier tag="0x420094" type="TextString" value="12"/>
137
+ </ResponsePayload>
138
+ </BatchItem>
139
+ </ResponseMessage>
140
+
141
+ clang-format on
142
+ */
143
+ static const uint8_t KMIP_REGISTER_RESPONSE[] = {
144
+ 0x42, 0x00, 0x7b, 0x01, 0x00, 0x00, 0x00, 0x90, 0x42, 0x00, 0x7a, 0x01, 0x00, 0x00, 0x00, 0x48, 0x42, 0x00, 0x69,
145
+ 0x01, 0x00, 0x00, 0x00, 0x20, 0x42, 0x00, 0x6a, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
146
+ 0x00, 0x00, 0x42, 0x00, 0x6b, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
147
+ 0x00, 0x92, 0x09, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x65, 0x82, 0xec, 0x0b, 0x42, 0x00, 0x0d, 0x02,
148
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x0f, 0x01, 0x00, 0x00, 0x00,
149
+ 0x38, 0x42, 0x00, 0x5c, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00,
150
+ 0x7f, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x7c, 0x01, 0x00,
151
+ 0x00, 0x00, 0x10, 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x02, 0x31, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
152
+
153
+ /*
154
+ clang-format off
155
+
156
+ `KMIP_ACTIVATE_RESPONSE` represents:
157
+
158
+ <ResponseMessage tag="0x42007b" type="Structure">
159
+ <ResponseHeader tag="0x42007a" type="Structure">
160
+ <ProtocolVersion tag="0x420069" type="Structure">
161
+ <ProtocolVersionMajor tag="0x42006a" type="Integer" value="1"/>
162
+ <ProtocolVersionMinor tag="0x42006b" type="Integer" value="0"/>
163
+ </ProtocolVersion>
164
+ <TimeStamp tag="0x420092" type="DateTime" value="2023-12-20T13:28:43-0500"/>
165
+ <BatchCount tag="0x42000d" type="Integer" value="1"/>
166
+ </ResponseHeader>
167
+ <BatchItem tag="0x42000f" type="Structure">
168
+ <Operation tag="0x42005c" type="Enumeration" value="18"/>
169
+ <ResultStatus tag="0x42007f" type="Enumeration" value="0"/>
170
+ <ResponsePayload tag="0x42007c" type="Structure">
171
+ <UniqueIdentifier tag="0x420094" type="TextString" value="12"/>
172
+ </ResponsePayload>
173
+ </BatchItem>
174
+ </ResponseMessage>
175
+
176
+ clang-format on
177
+ */
178
+ static const uint8_t KMIP_ACTIVATE_RESPONSE[] = {
179
+ 0x42, 0x00, 0x7b, 0x01, 0x00, 0x00, 0x00, 0x90, 0x42, 0x00, 0x7a, 0x01, 0x00, 0x00, 0x00, 0x48, 0x42, 0x00, 0x69,
180
+ 0x01, 0x00, 0x00, 0x00, 0x20, 0x42, 0x00, 0x6a, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
181
+ 0x00, 0x00, 0x42, 0x00, 0x6b, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
182
+ 0x00, 0x92, 0x09, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x65, 0x82, 0xec, 0x0b, 0x42, 0x00, 0x0d, 0x02,
183
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x0f, 0x01, 0x00, 0x00, 0x00,
184
+ 0x38, 0x42, 0x00, 0x5c, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00,
185
+ 0x7f, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x7c, 0x01, 0x00,
186
+ 0x00, 0x00, 0x10, 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x02, 0x31, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
187
+
188
+ /*
189
+ clang-format off
190
+
191
+ `KMIP_GET_RESPONSE` represents:
192
+
193
+ <ResponseMessage tag="0x42007b" type="Structure">
194
+ <ResponseHeader tag="0x42007a" type="Structure">
195
+ <ProtocolVersion tag="0x420069" type="Structure">
196
+ <ProtocolVersionMajor tag="0x42006a" type="Integer" value="1"/>
197
+ <ProtocolVersionMinor tag="0x42006b" type="Integer" value="0"/>
198
+ </ProtocolVersion>
199
+ <TimeStamp tag="0x420092" type="DateTime" value="2023-12-20T13:28:43-0500"/>
200
+ <BatchCount tag="0x42000d" type="Integer" value="1"/>
201
+ </ResponseHeader>
202
+ <BatchItem tag="0x42000f" type="Structure">
203
+ <Operation tag="0x42005c" type="Enumeration" value="10"/>
204
+ <ResultStatus tag="0x42007f" type="Enumeration" value="0"/>
205
+ <ResponsePayload tag="0x42007c" type="Structure">
206
+ <ObjectType tag="0x420057" type="Enumeration" value="7"/>
207
+ <UniqueIdentifier tag="0x420094" type="TextString" value="12"/>
208
+ <SecretData tag="0x420085" type="Structure">
209
+ <SecretDataType tag="0x420086" type="Enumeration" value="2"/>
210
+ <KeyBlock tag="0x420040" type="Structure">
211
+ <KeyFormatType tag="0x420042" type="Enumeration" value="2"/>
212
+ <KeyValue tag="0x420045" type="Structure">
213
+ <KeyMaterial tag="0x420043" type="ByteString" value="e6e4b2504fc61c4e8e45691b1719d5d6618b749167100683f4f8e55df1f22ad3cbba2ab421ed9daeb73bc25c031ade820580a5c75518ab21379b3936effbcfcda146b21671f2cf9f8012b0e183d719166481075d6c3932a5aed5411f0c26e157"/>
214
+ </KeyValue>
215
+ </KeyBlock>
216
+ </SecretData>
217
+ </ResponsePayload>
218
+ </BatchItem>
219
+ </ResponseMessage>
220
+
221
+ clang-format on
222
+ */
223
+ static const uint8_t KMIP_GET_RESPONSE[] = {
224
+ 0x42, 0x00, 0x7b, 0x01, 0x00, 0x00, 0x01, 0x40, 0x42, 0x00, 0x7a, 0x01, 0x00, 0x00, 0x00, 0x48, 0x42, 0x00, 0x69,
225
+ 0x01, 0x00, 0x00, 0x00, 0x20, 0x42, 0x00, 0x6a, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
226
+ 0x00, 0x00, 0x42, 0x00, 0x6b, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
227
+ 0x00, 0x92, 0x09, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x65, 0x82, 0xec, 0x0b, 0x42, 0x00, 0x0d, 0x02,
228
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x0f, 0x01, 0x00, 0x00, 0x00,
229
+ 0xe8, 0x42, 0x00, 0x5c, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00,
230
+ 0x7f, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x7c, 0x01, 0x00,
231
+ 0x00, 0x00, 0xc0, 0x42, 0x00, 0x57, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00,
232
+ 0x42, 0x00, 0x94, 0x07, 0x00, 0x00, 0x00, 0x02, 0x31, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x85,
233
+ 0x01, 0x00, 0x00, 0x00, 0x98, 0x42, 0x00, 0x86, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
234
+ 0x00, 0x00, 0x42, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x80, 0x42, 0x00, 0x42, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00,
235
+ 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x45, 0x01, 0x00, 0x00, 0x00, 0x68, 0x42, 0x00, 0x43, 0x08,
236
+ 0x00, 0x00, 0x00, 0x60, 0xe6, 0xe4, 0xb2, 0x50, 0x4f, 0xc6, 0x1c, 0x4e, 0x8e, 0x45, 0x69, 0x1b, 0x17, 0x19, 0xd5,
237
+ 0xd6, 0x61, 0x8b, 0x74, 0x91, 0x67, 0x10, 0x06, 0x83, 0xf4, 0xf8, 0xe5, 0x5d, 0xf1, 0xf2, 0x2a, 0xd3, 0xcb, 0xba,
238
+ 0x2a, 0xb4, 0x21, 0xed, 0x9d, 0xae, 0xb7, 0x3b, 0xc2, 0x5c, 0x03, 0x1a, 0xde, 0x82, 0x05, 0x80, 0xa5, 0xc7, 0x55,
239
+ 0x18, 0xab, 0x21, 0x37, 0x9b, 0x39, 0x36, 0xef, 0xfb, 0xcf, 0xcd, 0xa1, 0x46, 0xb2, 0x16, 0x71, 0xf2, 0xcf, 0x9f,
240
+ 0x80, 0x12, 0xb0, 0xe1, 0x83, 0xd7, 0x19, 0x16, 0x64, 0x81, 0x07, 0x5d, 0x6c, 0x39, 0x32, 0xa5, 0xae, 0xd5, 0x41,
241
+ 0x1f, 0x0c, 0x26, 0xe1, 0x57};
242
+
243
+ static void test_configuring_named_kms_providers(_mongocrypt_tester_t *tester) {
244
+ // Test that a named KMS provider can be set.
245
+ {
246
+ mongocrypt_t *crypt = mongocrypt_new();
247
+ mongocrypt_binary_t *kms_providers =
248
+ TEST_BSON(BSON_STR({"local" : {"key" : "%s"}, "local:name1" : {"key" : "%s"}}),
249
+ LOCAL_KEK1_BASE64,
250
+ LOCAL_KEK2_BASE64);
251
+ bool ok = mongocrypt_setopt_kms_providers(crypt, kms_providers);
252
+ ASSERT_OK(ok, crypt);
253
+ ASSERT_OK(_mongocrypt_init_for_test(crypt), crypt);
254
+ mongocrypt_destroy(crypt);
255
+ }
256
+
257
+ // Test that an unrecognized named KMS provider errors.
258
+ {
259
+ mongocrypt_t *crypt = mongocrypt_new();
260
+ mongocrypt_binary_t *kms_providers = TEST_BSON(BSON_STR({"foo:bar" : {"key" : "%s"}}), LOCAL_KEK1_BASE64);
261
+ bool ok = mongocrypt_setopt_kms_providers(crypt, kms_providers);
262
+ ASSERT_FAILS(ok, crypt, "unrecognized type");
263
+ mongocrypt_destroy(crypt);
264
+ }
265
+
266
+ // Test character validation. Only valid characters are: [a-zA-Z0-9_]
267
+ {
268
+ mongocrypt_t *crypt = mongocrypt_new();
269
+ mongocrypt_binary_t *kms_providers =
270
+ TEST_BSON(BSON_STR({"local:name_with_invalid_character_?" : {"key" : "%s"}}), LOCAL_KEK1_BASE64);
271
+ bool ok = mongocrypt_setopt_kms_providers(crypt, kms_providers);
272
+ ASSERT_FAILS(ok, crypt, "unsupported character `?`");
273
+ mongocrypt_destroy(crypt);
274
+ }
275
+
276
+ // Test configuring a named KMS provider with an empty document is prohibited.
277
+ {
278
+ mongocrypt_t *crypt = mongocrypt_new();
279
+ mongocrypt_binary_t *kms_providers = TEST_BSON(BSON_STR({"local:name1" : {}}));
280
+ bool ok = mongocrypt_setopt_kms_providers(crypt, kms_providers);
281
+ ASSERT_FAILS(ok, crypt, "Unexpected empty document for named KMS provider");
282
+ mongocrypt_destroy(crypt);
283
+
284
+ // An empty document is allowed for a non-named KMS provider to configure on-demand credentials.
285
+ crypt = mongocrypt_new();
286
+ kms_providers = TEST_BSON(BSON_STR({"local" : {}}));
287
+ ASSERT_OK(mongocrypt_setopt_kms_providers(crypt, kms_providers), crypt);
288
+ mongocrypt_destroy(crypt);
289
+ }
290
+
291
+ // Test that duplicate named KMS providers is an error.
292
+ {
293
+ mongocrypt_t *crypt = mongocrypt_new();
294
+ mongocrypt_binary_t *kms_providers =
295
+ TEST_BSON(BSON_STR({"local:name1" : {"key" : "%s"}, "local:name1" : {"key" : "%s"}}),
296
+ LOCAL_KEK1_BASE64,
297
+ LOCAL_KEK2_BASE64);
298
+ ASSERT_FAILS(mongocrypt_setopt_kms_providers(crypt, kms_providers), crypt, "duplicate entry");
299
+ mongocrypt_destroy(crypt);
300
+ }
301
+
302
+ // Test that a named KMS provider can be set with Azure.
303
+ {
304
+ mongocrypt_t *crypt = mongocrypt_new();
305
+ mongocrypt_binary_t *kms_providers =
306
+ TEST_BSON(BSON_STR({
307
+ "local" : {"key" : "%s"},
308
+ "azure:name1" : {
309
+ "tenantId" : "placeholder1-tenantId",
310
+ "clientId" : "placeholder1-clientId",
311
+ "clientSecret" : "placeholder1-clientSecret",
312
+ "identityPlatformEndpoint" : "placeholder1-identityPlatformEndpoint.com"
313
+ }
314
+ }),
315
+ LOCAL_KEK1_BASE64);
316
+ bool ok = mongocrypt_setopt_kms_providers(crypt, kms_providers);
317
+ ASSERT_OK(ok, crypt);
318
+ ASSERT_OK(_mongocrypt_init_for_test(crypt), crypt);
319
+ mongocrypt_destroy(crypt);
320
+ }
321
+
322
+ // Test that only configuring named KMS provider is OK.
323
+ {
324
+ mongocrypt_t *crypt = mongocrypt_new();
325
+ mongocrypt_binary_t *kms_providers = TEST_BSON(BSON_STR({"local:name1" : {"key" : "%s"}}), LOCAL_KEK1_BASE64);
326
+ bool ok = mongocrypt_setopt_kms_providers(crypt, kms_providers);
327
+ ASSERT_OK(ok, crypt);
328
+ ASSERT_OK(_mongocrypt_init_for_test(crypt), crypt);
329
+ mongocrypt_destroy(crypt);
330
+ }
331
+
332
+ // Test configuring with an empty name is an error.
333
+ {
334
+ mongocrypt_t *crypt = mongocrypt_new();
335
+ mongocrypt_binary_t *kms_providers = TEST_BSON(BSON_STR({"local:" : {"key" : "%s"}}), LOCAL_KEK1_BASE64);
336
+ ASSERT_FAILS(mongocrypt_setopt_kms_providers(crypt, kms_providers), crypt, "empty name");
337
+ mongocrypt_destroy(crypt);
338
+ }
339
+ }
340
+
341
+ static void test_create_datakey_with_named_kms_provider(_mongocrypt_tester_t *tester) {
342
+ // Test creating with an unconfigured KMS provider.
343
+ {
344
+ mongocrypt_t *crypt = mongocrypt_new();
345
+ mongocrypt_binary_t *kms_providers = TEST_BSON(BSON_STR({"local:name1" : {"key" : "%s"}}), LOCAL_KEK1_BASE64);
346
+ ASSERT_OK(mongocrypt_setopt_kms_providers(crypt, kms_providers), crypt);
347
+ ASSERT_OK(_mongocrypt_init_for_test(crypt), crypt);
348
+
349
+ // Create with named KMS provider.
350
+ mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
351
+ ASSERT_OK(
352
+ mongocrypt_ctx_setopt_key_encryption_key(ctx, TEST_BSON(BSON_STR({"provider" : "local:not_configured"}))),
353
+ ctx);
354
+ ASSERT_FAILS(mongocrypt_ctx_datakey_init(ctx),
355
+ ctx,
356
+ "requested kms provider not configured: `local:not_configured`");
357
+
358
+ mongocrypt_ctx_destroy(ctx);
359
+ mongocrypt_destroy(crypt);
360
+ }
361
+
362
+ // Test creating with an unconfigured KMS provider, when provider of same type is configured.
363
+ {
364
+ mongocrypt_t *crypt = mongocrypt_new();
365
+ mongocrypt_binary_t *kms_providers =
366
+ TEST_BSON(BSON_STR({"local" : {"key" : "%s"}, "local:name1" : {"key" : "%s"}}),
367
+ LOCAL_KEK1_BASE64,
368
+ LOCAL_KEK2_BASE64);
369
+ ASSERT_OK(mongocrypt_setopt_kms_providers(crypt, kms_providers), crypt);
370
+ ASSERT_OK(_mongocrypt_init_for_test(crypt), crypt);
371
+
372
+ // Create with named KMS provider.
373
+ mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
374
+ ASSERT_OK(
375
+ mongocrypt_ctx_setopt_key_encryption_key(ctx, TEST_BSON(BSON_STR({"provider" : "local:not_configured"}))),
376
+ ctx);
377
+ ASSERT_FAILS(mongocrypt_ctx_datakey_init(ctx),
378
+ ctx,
379
+ "requested kms provider not configured: `local:not_configured`");
380
+
381
+ mongocrypt_ctx_destroy(ctx);
382
+ mongocrypt_destroy(crypt);
383
+ }
384
+
385
+ // Test creating with an unconfigured KMS provider, when provider of same type is configured with an
386
+ // empty document.
387
+ {
388
+ mongocrypt_t *crypt = mongocrypt_new();
389
+ mongocrypt_binary_t *kms_providers =
390
+ TEST_BSON(BSON_STR({"local" : {}, "local:name1" : {"key" : "%s"}}), LOCAL_KEK1_BASE64, LOCAL_KEK2_BASE64);
391
+ ASSERT_OK(mongocrypt_setopt_kms_providers(crypt, kms_providers), crypt);
392
+ mongocrypt_setopt_use_need_kms_credentials_state(crypt);
393
+ ASSERT_OK(_mongocrypt_init_for_test(crypt), crypt);
394
+
395
+ // Create with named KMS provider.
396
+ mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
397
+ ASSERT_OK(
398
+ mongocrypt_ctx_setopt_key_encryption_key(ctx, TEST_BSON(BSON_STR({"provider" : "local:not_configured"}))),
399
+ ctx);
400
+ ASSERT_FAILS(mongocrypt_ctx_datakey_init(ctx),
401
+ ctx,
402
+ "requested kms provider required by datakey is not configured: `local:not_configured`");
403
+
404
+ mongocrypt_ctx_destroy(ctx);
405
+ mongocrypt_destroy(crypt);
406
+ }
407
+
408
+ // Test successfully creating a local DEK with a named KMS provider.
409
+ {
410
+ mongocrypt_t *crypt = mongocrypt_new();
411
+ mongocrypt_binary_t *kms_providers = TEST_BSON(BSON_STR({"local:name1" : {"key" : "%s"}}), LOCAL_KEK1_BASE64);
412
+ ASSERT_OK(mongocrypt_setopt_kms_providers(crypt, kms_providers), crypt);
413
+ ASSERT_OK(_mongocrypt_init_for_test(crypt), crypt);
414
+
415
+ // Create with named KMS provider.
416
+ mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
417
+ ASSERT_OK(mongocrypt_ctx_setopt_key_encryption_key(ctx, TEST_BSON(BSON_STR({"provider" : "local:name1"}))),
418
+ ctx);
419
+ ASSERT_OK(mongocrypt_ctx_datakey_init(ctx), ctx);
420
+
421
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_READY);
422
+ mongocrypt_binary_t *out = mongocrypt_binary_new();
423
+ ASSERT_OK(mongocrypt_ctx_finalize(ctx, out), ctx);
424
+ // Check that `out` contains name.
425
+ bson_t out_bson;
426
+ ASSERT(_mongocrypt_binary_to_bson(out, &out_bson));
427
+ char *pattern = BSON_STR({"masterKey" : {"provider" : "local:name1"}});
428
+ _assert_match_bson(&out_bson, TMP_BSON(pattern));
429
+ bson_destroy(&out_bson);
430
+ mongocrypt_binary_destroy(out);
431
+ mongocrypt_ctx_destroy(ctx);
432
+ mongocrypt_destroy(crypt);
433
+ }
434
+
435
+ // Test successfully creating an Azure DEK with a named KMS provider
436
+ {
437
+ mongocrypt_t *crypt = mongocrypt_new();
438
+ mongocrypt_binary_t *kms_providers = TEST_BSON(BSON_STR({
439
+ "azure:name1" : {
440
+ "tenantId" : "placeholder1-tenantId",
441
+ "clientId" : "placeholder1-clientId",
442
+ "clientSecret" : "placeholder1-clientSecret",
443
+ "identityPlatformEndpoint" : "placeholder1-identityPlatformEndpoint.com"
444
+ }
445
+ }));
446
+ ASSERT_OK(mongocrypt_setopt_kms_providers(crypt, kms_providers), crypt);
447
+ ASSERT_OK(_mongocrypt_init_for_test(crypt), crypt);
448
+
449
+ // Create with named KMS provider.
450
+ mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
451
+ ASSERT_OK(mongocrypt_ctx_setopt_key_encryption_key(ctx, TEST_BSON(BSON_STR({
452
+ "provider" : "azure:name1",
453
+ "keyName" : "placeholder1-keyName",
454
+ "keyVaultEndpoint" : "placeholder1-keyVaultEndpoint.com"
455
+ }))),
456
+ ctx);
457
+ ASSERT_OK(mongocrypt_ctx_datakey_init(ctx), ctx);
458
+
459
+ // Needs KMS for oauth token.
460
+ {
461
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
462
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
463
+ ASSERT(kctx);
464
+ const char *endpoint;
465
+ ASSERT_OK(mongocrypt_kms_ctx_endpoint(kctx, &endpoint), kctx);
466
+ ASSERT_STREQUAL(endpoint, "placeholder1-identityPlatformEndpoint.com:443");
467
+ ASSERT_OK(mongocrypt_kms_ctx_feed(kctx, TEST_FILE("./test/data/kms-azure/oauth-response.txt")), kctx);
468
+ kctx = mongocrypt_ctx_next_kms_ctx(ctx);
469
+ ASSERT(!kctx);
470
+ ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
471
+ }
472
+
473
+ // Needs KMS to encrypt DEK.
474
+ {
475
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
476
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
477
+ ASSERT(kctx);
478
+ const char *endpoint;
479
+ ASSERT_OK(mongocrypt_kms_ctx_endpoint(kctx, &endpoint), kctx);
480
+ ASSERT_STREQUAL(endpoint, "placeholder1-keyVaultEndpoint.com:443");
481
+ ASSERT_OK(mongocrypt_kms_ctx_feed(kctx, TEST_FILE("./test/data/kms-azure/encrypt-response.txt")), kctx);
482
+ kctx = mongocrypt_ctx_next_kms_ctx(ctx);
483
+ ASSERT(!kctx);
484
+ ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
485
+ }
486
+
487
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_READY);
488
+ mongocrypt_binary_t *out = mongocrypt_binary_new();
489
+ ASSERT_OK(mongocrypt_ctx_finalize(ctx, out), ctx);
490
+ // Check that `out` contains name.
491
+ bson_t out_bson;
492
+ ASSERT(_mongocrypt_binary_to_bson(out, &out_bson));
493
+ char *pattern = BSON_STR({"masterKey" : {"provider" : "azure:name1"}});
494
+ _assert_match_bson(&out_bson, TMP_BSON(pattern));
495
+ bson_destroy(&out_bson);
496
+ mongocrypt_binary_destroy(out);
497
+ mongocrypt_ctx_destroy(ctx);
498
+ mongocrypt_destroy(crypt);
499
+ }
500
+
501
+ // Test successfully creating an Azure DEK when `accessToken` is passed.
502
+ {
503
+ mongocrypt_t *crypt = mongocrypt_new();
504
+ mongocrypt_binary_t *kms_providers = TEST_BSON(BSON_STR({"azure:name1" : {"accessToken" : "foo"}}));
505
+ ASSERT_OK(mongocrypt_setopt_kms_providers(crypt, kms_providers), crypt);
506
+ ASSERT_OK(_mongocrypt_init_for_test(crypt), crypt);
507
+
508
+ // Create with named KMS provider.
509
+ mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
510
+ ASSERT_OK(mongocrypt_ctx_setopt_key_encryption_key(ctx, TEST_BSON(BSON_STR({
511
+ "provider" : "azure:name1",
512
+ "keyName" : "placeholder1-keyName",
513
+ "keyVaultEndpoint" : "placeholder1-keyVaultEndpoint.com"
514
+ }))),
515
+ ctx);
516
+ ASSERT_OK(mongocrypt_ctx_datakey_init(ctx), ctx);
517
+
518
+ // Needs KMS to encrypt DEK.
519
+ {
520
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
521
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
522
+ ASSERT(kctx);
523
+ const char *endpoint;
524
+ ASSERT_OK(mongocrypt_kms_ctx_endpoint(kctx, &endpoint), kctx);
525
+ ASSERT_STREQUAL(endpoint, "placeholder1-keyVaultEndpoint.com:443");
526
+ ASSERT_OK(mongocrypt_kms_ctx_feed(kctx, TEST_FILE("./test/data/kms-azure/encrypt-response.txt")), kctx);
527
+ kctx = mongocrypt_ctx_next_kms_ctx(ctx);
528
+ ASSERT(!kctx);
529
+ ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
530
+ }
531
+
532
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_READY);
533
+ mongocrypt_binary_t *out = mongocrypt_binary_new();
534
+ ASSERT_OK(mongocrypt_ctx_finalize(ctx, out), ctx);
535
+ // Check that `out` contains name.
536
+ bson_t out_bson;
537
+ ASSERT(_mongocrypt_binary_to_bson(out, &out_bson));
538
+ char *pattern = BSON_STR({"masterKey" : {"provider" : "azure:name1"}});
539
+ _assert_match_bson(&out_bson, TMP_BSON(pattern));
540
+ bson_destroy(&out_bson);
541
+ mongocrypt_binary_destroy(out);
542
+ mongocrypt_ctx_destroy(ctx);
543
+ mongocrypt_destroy(crypt);
544
+ }
545
+
546
+ // Test creating two Azure keys with different named providers.
547
+ // This is intended to test that they do not share cache entries.
548
+ {
549
+ mongocrypt_t *crypt = mongocrypt_new();
550
+ mongocrypt_binary_t *kms_providers = TEST_BSON(BSON_STR({
551
+ "azure:name1" : {
552
+ "tenantId" : "placeholder1-tenantId",
553
+ "clientId" : "placeholder1-clientId",
554
+ "clientSecret" : "placeholder1-clientSecret",
555
+ "identityPlatformEndpoint" : "placeholder1-identityPlatformEndpoint.com"
556
+ },
557
+ "azure:name2" : {
558
+ "tenantId" : "placeholder2-tenantId",
559
+ "clientId" : "placeholder2-clientId",
560
+ "clientSecret" : "placeholder2-clientSecret",
561
+ "identityPlatformEndpoint" : "placeholder2-identityPlatformEndpoint.com"
562
+ }
563
+ }));
564
+ ASSERT_OK(mongocrypt_setopt_kms_providers(crypt, kms_providers), crypt);
565
+ ASSERT_OK(_mongocrypt_init_for_test(crypt), crypt);
566
+
567
+ // Create with `azure:name1`.
568
+ {
569
+ mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
570
+ ASSERT_OK(
571
+ mongocrypt_ctx_setopt_key_encryption_key(ctx, TEST_BSON(BSON_STR({
572
+ "provider" : "azure:name1",
573
+ "keyName" : "placeholder1-keyName",
574
+ "keyVaultEndpoint" : "placeholder1-keyVaultEndpoint.com"
575
+ }))),
576
+ ctx);
577
+ ASSERT_OK(mongocrypt_ctx_datakey_init(ctx), ctx);
578
+
579
+ // Needs KMS for oauth token.
580
+ {
581
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
582
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
583
+ ASSERT(kctx);
584
+ const char *endpoint;
585
+ ASSERT_OK(mongocrypt_kms_ctx_endpoint(kctx, &endpoint), kctx);
586
+ ASSERT_STREQUAL(endpoint, "placeholder1-identityPlatformEndpoint.com:443");
587
+ ASSERT_OK(mongocrypt_kms_ctx_feed(kctx, TEST_FILE("./test/data/kms-azure/oauth-response.txt")), kctx);
588
+ kctx = mongocrypt_ctx_next_kms_ctx(ctx);
589
+ ASSERT(!kctx);
590
+ ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
591
+ }
592
+
593
+ // Needs KMS to encrypt DEK.
594
+ {
595
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
596
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
597
+ ASSERT(kctx);
598
+ const char *endpoint;
599
+ ASSERT_OK(mongocrypt_kms_ctx_endpoint(kctx, &endpoint), kctx);
600
+ ASSERT_STREQUAL(endpoint, "placeholder1-keyVaultEndpoint.com:443");
601
+ ASSERT_OK(mongocrypt_kms_ctx_feed(kctx, TEST_FILE("./test/data/kms-azure/encrypt-response.txt")), kctx);
602
+ kctx = mongocrypt_ctx_next_kms_ctx(ctx);
603
+ ASSERT(!kctx);
604
+ ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
605
+ }
606
+
607
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_READY);
608
+ mongocrypt_binary_t *out = mongocrypt_binary_new();
609
+ ASSERT_OK(mongocrypt_ctx_finalize(ctx, out), ctx);
610
+ // Check that `out` contains name.
611
+ bson_t out_bson;
612
+ ASSERT(_mongocrypt_binary_to_bson(out, &out_bson));
613
+ char *pattern = BSON_STR({"masterKey" : {"provider" : "azure:name1"}});
614
+ _assert_match_bson(&out_bson, TMP_BSON(pattern));
615
+ bson_destroy(&out_bson);
616
+ mongocrypt_binary_destroy(out);
617
+ mongocrypt_ctx_destroy(ctx);
618
+ }
619
+
620
+ // Create with `azure:name2`. Expect a separate oauth token is needed.
621
+ {
622
+ mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
623
+ ASSERT_OK(
624
+ mongocrypt_ctx_setopt_key_encryption_key(ctx, TEST_BSON(BSON_STR({
625
+ "provider" : "azure:name2",
626
+ "keyName" : "placeholder2-keyName",
627
+ "keyVaultEndpoint" : "placeholder2-keyVaultEndpoint.com"
628
+ }))),
629
+ ctx);
630
+ ASSERT_OK(mongocrypt_ctx_datakey_init(ctx), ctx);
631
+
632
+ // Needs KMS for oauth token.
633
+ {
634
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
635
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
636
+ ASSERT(kctx);
637
+ const char *endpoint;
638
+ ASSERT_OK(mongocrypt_kms_ctx_endpoint(kctx, &endpoint), kctx);
639
+ ASSERT_STREQUAL(endpoint, "placeholder2-identityPlatformEndpoint.com:443");
640
+ ASSERT_OK(mongocrypt_kms_ctx_feed(kctx, TEST_FILE("./test/data/kms-azure/oauth-response.txt")), kctx);
641
+ kctx = mongocrypt_ctx_next_kms_ctx(ctx);
642
+ ASSERT(!kctx);
643
+ ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
644
+ }
645
+
646
+ // Needs KMS to encrypt DEK.
647
+ {
648
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
649
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
650
+ ASSERT(kctx);
651
+ const char *endpoint;
652
+ ASSERT_OK(mongocrypt_kms_ctx_endpoint(kctx, &endpoint), kctx);
653
+ ASSERT_STREQUAL(endpoint, "placeholder2-keyVaultEndpoint.com:443");
654
+ ASSERT_OK(mongocrypt_kms_ctx_feed(kctx, TEST_FILE("./test/data/kms-azure/encrypt-response.txt")), kctx);
655
+ kctx = mongocrypt_ctx_next_kms_ctx(ctx);
656
+ ASSERT(!kctx);
657
+ ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
658
+ }
659
+
660
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_READY);
661
+ mongocrypt_binary_t *out = mongocrypt_binary_new();
662
+ ASSERT_OK(mongocrypt_ctx_finalize(ctx, out), ctx);
663
+ // Check that `out` contains name.
664
+ bson_t out_bson;
665
+ ASSERT(_mongocrypt_binary_to_bson(out, &out_bson));
666
+ char *pattern = BSON_STR({"masterKey" : {"provider" : "azure:name2"}});
667
+ _assert_match_bson(&out_bson, TMP_BSON(pattern));
668
+ bson_destroy(&out_bson);
669
+ mongocrypt_binary_destroy(out);
670
+ mongocrypt_ctx_destroy(ctx);
671
+ }
672
+ mongocrypt_destroy(crypt);
673
+ }
674
+
675
+ // Test successfully creating an KMIP DEK with a named KMS provider
676
+ {
677
+ mongocrypt_t *crypt = mongocrypt_new();
678
+ mongocrypt_binary_t *kms_providers =
679
+ TEST_BSON(BSON_STR({"kmip:name1" : {"endpoint" : "placeholder1-endpoint.com"}}));
680
+ ASSERT_OK(mongocrypt_setopt_kms_providers(crypt, kms_providers), crypt);
681
+ ASSERT_OK(_mongocrypt_init_for_test(crypt), crypt);
682
+
683
+ // Create with named KMS provider.
684
+ mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
685
+ ASSERT_OK(
686
+ mongocrypt_ctx_setopt_key_encryption_key(ctx,
687
+ TEST_BSON(BSON_STR({"provider" : "kmip:name1", "keyId" : "12"}))),
688
+ ctx);
689
+ ASSERT_OK(mongocrypt_ctx_datakey_init(ctx), ctx);
690
+
691
+ // Needs KMS to Get KEK.
692
+ {
693
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
694
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
695
+ ASSERT(kctx);
696
+ const char *endpoint;
697
+ ASSERT_OK(mongocrypt_kms_ctx_endpoint(kctx, &endpoint), kctx);
698
+ ASSERT_STREQUAL(endpoint, "placeholder1-endpoint.com:5696");
699
+ // Assert request is a Get.
700
+ {
701
+ mongocrypt_binary_t *request = mongocrypt_binary_new();
702
+ ASSERT_OK(mongocrypt_kms_ctx_message(kctx, request), kctx);
703
+ ASSERT_STREQUAL(kmip_get_operation_type(request), "Get");
704
+ mongocrypt_binary_destroy(request);
705
+ }
706
+ // Feed response to Get.
707
+ ASSERT_OK(kms_ctx_feed_all(kctx, KMIP_GET_RESPONSE, (uint32_t)(sizeof(KMIP_GET_RESPONSE))), kctx);
708
+ kctx = mongocrypt_ctx_next_kms_ctx(ctx);
709
+ ASSERT(!kctx);
710
+ ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
711
+ }
712
+
713
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_READY);
714
+ mongocrypt_binary_t *out = mongocrypt_binary_new();
715
+ ASSERT_OK(mongocrypt_ctx_finalize(ctx, out), ctx);
716
+ // Check that `out` contains name.
717
+ bson_t out_bson;
718
+ ASSERT(_mongocrypt_binary_to_bson(out, &out_bson));
719
+ char *pattern = BSON_STR({"masterKey" : {"provider" : "kmip:name1"}});
720
+ _assert_match_bson(&out_bson, TMP_BSON(pattern));
721
+ bson_destroy(&out_bson);
722
+ mongocrypt_binary_destroy(out);
723
+ mongocrypt_ctx_destroy(ctx);
724
+ mongocrypt_destroy(crypt);
725
+ }
726
+
727
+ // Test creating a KMIP key when `keyId` is not passed.
728
+ {
729
+ mongocrypt_t *crypt = mongocrypt_new();
730
+ mongocrypt_binary_t *kms_providers =
731
+ TEST_BSON(BSON_STR({"kmip:name1" : {"endpoint" : "placeholder1-endpoint.com"}}));
732
+ ASSERT_OK(mongocrypt_setopt_kms_providers(crypt, kms_providers), crypt);
733
+ ASSERT_OK(_mongocrypt_init_for_test(crypt), crypt);
734
+
735
+ // Create with named KMS provider.
736
+ mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
737
+ ASSERT_OK(mongocrypt_ctx_setopt_key_encryption_key(ctx, TEST_BSON(BSON_STR({"provider" : "kmip:name1"}))), ctx);
738
+ ASSERT_OK(mongocrypt_ctx_datakey_init(ctx), ctx);
739
+
740
+ // Needs KMS to Register KEK.
741
+ {
742
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
743
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
744
+ ASSERT(kctx);
745
+ const char *endpoint;
746
+ ASSERT_OK(mongocrypt_kms_ctx_endpoint(kctx, &endpoint), kctx);
747
+ ASSERT_STREQUAL(endpoint, "placeholder1-endpoint.com:5696");
748
+ // Assert request is a Register.
749
+ {
750
+ mongocrypt_binary_t *request = mongocrypt_binary_new();
751
+ ASSERT_OK(mongocrypt_kms_ctx_message(kctx, request), kctx);
752
+ ASSERT_STREQUAL(kmip_get_operation_type(request), "Register");
753
+ mongocrypt_binary_destroy(request);
754
+ }
755
+ // Feed response to Register.
756
+ ASSERT_OK(kms_ctx_feed_all(kctx, KMIP_REGISTER_RESPONSE, (uint32_t)(sizeof(KMIP_REGISTER_RESPONSE))), kctx);
757
+ kctx = mongocrypt_ctx_next_kms_ctx(ctx);
758
+ ASSERT(!kctx);
759
+ ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
760
+ }
761
+
762
+ // Needs KMS to Activate KEK.
763
+ {
764
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
765
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
766
+ ASSERT(kctx);
767
+ const char *endpoint;
768
+ ASSERT_OK(mongocrypt_kms_ctx_endpoint(kctx, &endpoint), kctx);
769
+ ASSERT_STREQUAL(endpoint, "placeholder1-endpoint.com:5696");
770
+ // Assert request is a Activate.
771
+ {
772
+ mongocrypt_binary_t *request = mongocrypt_binary_new();
773
+ ASSERT_OK(mongocrypt_kms_ctx_message(kctx, request), kctx);
774
+ ASSERT_STREQUAL(kmip_get_operation_type(request), "Activate");
775
+ mongocrypt_binary_destroy(request);
776
+ }
777
+ // Feed response to Activate.
778
+ ASSERT_OK(kms_ctx_feed_all(kctx, KMIP_ACTIVATE_RESPONSE, (uint32_t)(sizeof(KMIP_ACTIVATE_RESPONSE))), kctx);
779
+ kctx = mongocrypt_ctx_next_kms_ctx(ctx);
780
+ ASSERT(!kctx);
781
+ ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
782
+ }
783
+
784
+ // Needs KMS to Get KEK.
785
+ {
786
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
787
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
788
+ ASSERT(kctx);
789
+ const char *endpoint;
790
+ ASSERT_OK(mongocrypt_kms_ctx_endpoint(kctx, &endpoint), kctx);
791
+ ASSERT_STREQUAL(endpoint, "placeholder1-endpoint.com:5696");
792
+ // Assert request is a Get.
793
+ {
794
+ mongocrypt_binary_t *request = mongocrypt_binary_new();
795
+ ASSERT_OK(mongocrypt_kms_ctx_message(kctx, request), kctx);
796
+ ASSERT_STREQUAL(kmip_get_operation_type(request), "Get");
797
+ mongocrypt_binary_destroy(request);
798
+ }
799
+ // Feed response to Get.
800
+ ASSERT_OK(kms_ctx_feed_all(kctx, KMIP_GET_RESPONSE, (uint32_t)(sizeof(KMIP_GET_RESPONSE))), kctx);
801
+ kctx = mongocrypt_ctx_next_kms_ctx(ctx);
802
+ ASSERT(!kctx);
803
+ ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
804
+ }
805
+
806
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_READY);
807
+ mongocrypt_binary_t *out = mongocrypt_binary_new();
808
+ ASSERT_OK(mongocrypt_ctx_finalize(ctx, out), ctx);
809
+ // Check that `out` contains name.
810
+ bson_t out_bson;
811
+ ASSERT(_mongocrypt_binary_to_bson(out, &out_bson));
812
+ char *pattern = BSON_STR({"masterKey" : {"provider" : "kmip:name1"}});
813
+ _assert_match_bson(&out_bson, TMP_BSON(pattern));
814
+ bson_destroy(&out_bson);
815
+ mongocrypt_binary_destroy(out);
816
+ mongocrypt_ctx_destroy(ctx);
817
+ mongocrypt_destroy(crypt);
818
+ }
819
+ }
820
+
821
+ typedef struct {
822
+ mongocrypt_binary_t *kms_providers;
823
+ const char *key_alt_name;
824
+ mongocrypt_binary_t *kek;
825
+ mongocrypt_binary_t *kms_response_1;
826
+ mongocrypt_binary_t *kms_response_2;
827
+ } create_dek_args;
828
+
829
+ // `create_dek` is a test helper to create a Data Encryption Key (DEK).
830
+ static void create_dek(_mongocrypt_tester_t *tester, create_dek_args args, _mongocrypt_buffer_t *dek) {
831
+ BSON_ASSERT_PARAM(args.kms_providers);
832
+ BSON_ASSERT_PARAM(args.key_alt_name);
833
+ BSON_ASSERT_PARAM(args.kek);
834
+ // kms_response_1 and kms_response_2 may be NULL.
835
+
836
+ mongocrypt_t *crypt = mongocrypt_new();
837
+ ASSERT_OK(mongocrypt_setopt_kms_providers(crypt, args.kms_providers), crypt);
838
+ ASSERT_OK(_mongocrypt_init_for_test(crypt), crypt);
839
+
840
+ mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
841
+ ASSERT_OK(mongocrypt_ctx_setopt_key_encryption_key(ctx, args.kek), ctx);
842
+ ASSERT_OK(mongocrypt_ctx_setopt_key_alt_name(ctx, TEST_BSON(BSON_STR({"keyAltName" : "%s"}), args.key_alt_name)),
843
+ ctx);
844
+ ASSERT_OK(mongocrypt_ctx_datakey_init(ctx), ctx);
845
+
846
+ if (args.kms_response_1) {
847
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
848
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
849
+ ASSERT(kctx);
850
+ ASSERT_OK(kms_ctx_feed_all(kctx,
851
+ mongocrypt_binary_data(args.kms_response_1),
852
+ mongocrypt_binary_len(args.kms_response_1)),
853
+ kctx);
854
+ kctx = mongocrypt_ctx_next_kms_ctx(ctx);
855
+ ASSERT(!kctx);
856
+ ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
857
+ }
858
+
859
+ if (args.kms_response_2) {
860
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
861
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
862
+ ASSERT(kctx);
863
+ ASSERT_OK(kms_ctx_feed_all(kctx,
864
+ mongocrypt_binary_data(args.kms_response_2),
865
+ mongocrypt_binary_len(args.kms_response_2)),
866
+ kctx);
867
+ kctx = mongocrypt_ctx_next_kms_ctx(ctx);
868
+ ASSERT(!kctx);
869
+ ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
870
+ }
871
+
872
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_READY);
873
+ mongocrypt_binary_t *bin = mongocrypt_binary_new();
874
+ ASSERT_OK(mongocrypt_ctx_finalize(ctx, bin), ctx);
875
+ _mongocrypt_buffer_copy_from_binary(dek, bin);
876
+ mongocrypt_binary_destroy(bin);
877
+ mongocrypt_ctx_destroy(ctx);
878
+ mongocrypt_destroy(crypt);
879
+ }
880
+
881
+ static void test_explicit_with_named_kms_provider_for_azure(_mongocrypt_tester_t *tester) {
882
+ mongocrypt_binary_t *kms_providers = TEST_BSON(BSON_STR({
883
+ "azure:name1" : {
884
+ "tenantId" : "placeholder1-tenantId",
885
+ "clientId" : "placeholder1-clientId",
886
+ "clientSecret" : "placeholder1-clientSecret",
887
+ "identityPlatformEndpoint" : "placeholder1-identityPlatformEndpoint.com"
888
+ },
889
+ "azure:name2" : {
890
+ "tenantId" : "placeholder2-tenantId",
891
+ "clientId" : "placeholder2-clientId",
892
+ "clientSecret" : "placeholder2-clientSecret",
893
+ "identityPlatformEndpoint" : "placeholder2-identityPlatformEndpoint.com"
894
+ }
895
+ }));
896
+
897
+ // Create `dek1` from `azure:name1`
898
+ _mongocrypt_buffer_t dek1;
899
+ create_dek(tester,
900
+ (create_dek_args){.kms_providers = kms_providers,
901
+ .key_alt_name = "azure1",
902
+ .kek = TEST_BSON(BSON_STR({
903
+ "provider" : "azure:name1",
904
+ "keyName" : "placeholder1-keyName",
905
+ "keyVaultEndpoint" : "placeholder1-keyVaultEndpoint.com"
906
+ })),
907
+ .kms_response_1 = TEST_FILE("./test/data/kms-azure/oauth-response.txt"),
908
+ .kms_response_2 = TEST_FILE("./test/data/kms-azure/encrypt-response.txt")},
909
+ &dek1);
910
+
911
+ // Create `dek2` from `azure:name2`
912
+ _mongocrypt_buffer_t dek2;
913
+ create_dek(tester,
914
+ (create_dek_args){.kms_providers = kms_providers,
915
+ .key_alt_name = "azure2",
916
+ .kek = TEST_BSON(BSON_STR({
917
+ "provider" : "azure:name2",
918
+ "keyName" : "placeholder2-keyName",
919
+ "keyVaultEndpoint" : "placeholder2-keyVaultEndpoint.com"
920
+ })),
921
+ .kms_response_1 = TEST_FILE("./test/data/kms-azure/oauth-response.txt"),
922
+ .kms_response_2 = TEST_FILE("./test/data/kms-azure/encrypt-response.txt")},
923
+ &dek2);
924
+
925
+ // Test encrypting.
926
+ _mongocrypt_buffer_t ciphertext;
927
+ {
928
+ mongocrypt_t *crypt = mongocrypt_new();
929
+ ASSERT_OK(mongocrypt_setopt_kms_providers(crypt, kms_providers), crypt);
930
+ ASSERT_OK(_mongocrypt_init_for_test(crypt), crypt);
931
+
932
+ // Test encrypting without cached DEK. Store result for later decryption.
933
+ {
934
+ mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
935
+ ASSERT_OK(mongocrypt_ctx_setopt_key_alt_name(ctx, TEST_BSON(BSON_STR({"keyAltName" : "azure1"}))), ctx);
936
+ ASSERT_OK(mongocrypt_ctx_setopt_algorithm(ctx, MONGOCRYPT_ALGORITHM_DETERMINISTIC_STR, -1), ctx);
937
+ ASSERT_OK(mongocrypt_ctx_explicit_encrypt_init(ctx, TEST_BSON(BSON_STR({"v" : "foo"}))), ctx);
938
+
939
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_KEYS);
940
+ ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, _mongocrypt_buffer_as_binary(&dek1)), ctx);
941
+ ASSERT_OK(mongocrypt_ctx_mongo_done(ctx), ctx);
942
+
943
+ // Needs KMS for oauth token.
944
+ {
945
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
946
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
947
+ ASSERT(kctx);
948
+ const char *endpoint;
949
+ ASSERT_OK(mongocrypt_kms_ctx_endpoint(kctx, &endpoint), kctx);
950
+ ASSERT_STREQUAL(endpoint, "placeholder1-identityPlatformEndpoint.com:443");
951
+ ASSERT_OK(mongocrypt_kms_ctx_feed(kctx, TEST_FILE("./test/data/kms-azure/oauth-response.txt")), kctx);
952
+ kctx = mongocrypt_ctx_next_kms_ctx(ctx);
953
+ ASSERT(!kctx);
954
+ ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
955
+ }
956
+
957
+ // Needs KMS to decrypt DEK.
958
+ {
959
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
960
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
961
+ ASSERT(kctx);
962
+ const char *endpoint;
963
+ ASSERT_OK(mongocrypt_kms_ctx_endpoint(kctx, &endpoint), kctx);
964
+ ASSERT_STREQUAL(endpoint, "placeholder1-keyVaultEndpoint.com:443");
965
+ ASSERT_OK(mongocrypt_kms_ctx_feed(kctx, TEST_FILE("./test/data/kms-azure/decrypt-response.txt")), kctx);
966
+ kctx = mongocrypt_ctx_next_kms_ctx(ctx);
967
+ ASSERT(!kctx);
968
+ ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
969
+ }
970
+
971
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_READY);
972
+ mongocrypt_binary_t *bin = mongocrypt_binary_new();
973
+ ASSERT_OK(mongocrypt_ctx_finalize(ctx, bin), ctx);
974
+ _mongocrypt_buffer_copy_from_binary(&ciphertext, bin);
975
+ mongocrypt_binary_destroy(bin);
976
+ mongocrypt_ctx_destroy(ctx);
977
+ }
978
+
979
+ // Test encrypting with cached DEK.
980
+ {
981
+ mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
982
+ ASSERT_OK(mongocrypt_ctx_setopt_key_alt_name(ctx, TEST_BSON(BSON_STR({"keyAltName" : "azure1"}))), ctx);
983
+ ASSERT_OK(mongocrypt_ctx_setopt_algorithm(ctx, MONGOCRYPT_ALGORITHM_DETERMINISTIC_STR, -1), ctx);
984
+ ASSERT_OK(mongocrypt_ctx_explicit_encrypt_init(ctx, TEST_BSON(BSON_STR({"v" : "foo"}))), ctx);
985
+ // DEK is already cached. State transitions directly to ready.
986
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_READY);
987
+ mongocrypt_binary_t *bin = mongocrypt_binary_new();
988
+ ASSERT_OK(mongocrypt_ctx_finalize(ctx, bin), ctx);
989
+ mongocrypt_binary_destroy(bin);
990
+ mongocrypt_ctx_destroy(ctx);
991
+ }
992
+
993
+ mongocrypt_destroy(crypt);
994
+ }
995
+
996
+ // Test decrypting.
997
+ {
998
+ mongocrypt_t *crypt = mongocrypt_new();
999
+ ASSERT_OK(mongocrypt_setopt_kms_providers(crypt, kms_providers), crypt);
1000
+ ASSERT_OK(_mongocrypt_init_for_test(crypt), crypt);
1001
+
1002
+ // Test decrypting without cached DEK.
1003
+ {
1004
+ mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
1005
+ ASSERT_OK(mongocrypt_ctx_explicit_decrypt_init(ctx, _mongocrypt_buffer_as_binary(&ciphertext)), ctx);
1006
+
1007
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_KEYS);
1008
+ ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, _mongocrypt_buffer_as_binary(&dek1)), ctx);
1009
+ ASSERT_OK(mongocrypt_ctx_mongo_done(ctx), ctx);
1010
+
1011
+ // Needs KMS for oauth token.
1012
+ {
1013
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
1014
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1015
+ ASSERT(kctx);
1016
+ const char *endpoint;
1017
+ ASSERT_OK(mongocrypt_kms_ctx_endpoint(kctx, &endpoint), kctx);
1018
+ ASSERT_STREQUAL(endpoint, "placeholder1-identityPlatformEndpoint.com:443");
1019
+ ASSERT_OK(mongocrypt_kms_ctx_feed(kctx, TEST_FILE("./test/data/kms-azure/oauth-response.txt")), kctx);
1020
+ kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1021
+ ASSERT(!kctx);
1022
+ ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
1023
+ }
1024
+
1025
+ // Needs KMS to decrypt DEK.
1026
+ {
1027
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
1028
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1029
+ ASSERT(kctx);
1030
+ const char *endpoint;
1031
+ ASSERT_OK(mongocrypt_kms_ctx_endpoint(kctx, &endpoint), kctx);
1032
+ ASSERT_STREQUAL(endpoint, "placeholder1-keyVaultEndpoint.com:443");
1033
+ ASSERT_OK(mongocrypt_kms_ctx_feed(kctx, TEST_FILE("./test/data/kms-azure/decrypt-response.txt")), kctx);
1034
+ kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1035
+ ASSERT(!kctx);
1036
+ ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
1037
+ }
1038
+
1039
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_READY);
1040
+ mongocrypt_binary_t *bin = mongocrypt_binary_new();
1041
+ ASSERT_OK(mongocrypt_ctx_finalize(ctx, bin), ctx);
1042
+ ASSERT_MONGOCRYPT_BINARY_EQUAL_BSON(TEST_BSON(BSON_STR({"v" : "foo"})), bin);
1043
+ mongocrypt_binary_destroy(bin);
1044
+ mongocrypt_ctx_destroy(ctx);
1045
+ }
1046
+
1047
+ // Test decrypting with cached DEK.
1048
+ {
1049
+ mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
1050
+ ASSERT_OK(mongocrypt_ctx_explicit_decrypt_init(ctx, _mongocrypt_buffer_as_binary(&ciphertext)), ctx);
1051
+ // DEK is already cached. State transitions directly to ready.
1052
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_READY);
1053
+ mongocrypt_binary_t *bin = mongocrypt_binary_new();
1054
+ ASSERT_OK(mongocrypt_ctx_finalize(ctx, bin), ctx);
1055
+ ASSERT_MONGOCRYPT_BINARY_EQUAL_BSON(TEST_BSON(BSON_STR({"v" : "foo"})), bin);
1056
+ mongocrypt_binary_destroy(bin);
1057
+ mongocrypt_ctx_destroy(ctx);
1058
+ }
1059
+ mongocrypt_destroy(crypt);
1060
+ }
1061
+
1062
+ // Test decrypting with a cached oauth token, but not a cached DEK.
1063
+ {
1064
+ mongocrypt_t *crypt = mongocrypt_new();
1065
+ ASSERT_OK(mongocrypt_setopt_kms_providers(crypt, kms_providers), crypt);
1066
+ ASSERT_OK(_mongocrypt_init_for_test(crypt), crypt);
1067
+
1068
+ // Decrypt.
1069
+ mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
1070
+ ASSERT_OK(mongocrypt_ctx_explicit_decrypt_init(ctx, _mongocrypt_buffer_as_binary(&ciphertext)), ctx);
1071
+
1072
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_KEYS);
1073
+ ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, _mongocrypt_buffer_as_binary(&dek1)), ctx);
1074
+ ASSERT_OK(mongocrypt_ctx_mongo_done(ctx), ctx);
1075
+
1076
+ // Needs KMS for oauth token.
1077
+ {
1078
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
1079
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1080
+ ASSERT(kctx);
1081
+ const char *endpoint;
1082
+ ASSERT_OK(mongocrypt_kms_ctx_endpoint(kctx, &endpoint), kctx);
1083
+ ASSERT_STREQUAL(endpoint, "placeholder1-identityPlatformEndpoint.com:443");
1084
+ ASSERT_OK(mongocrypt_kms_ctx_feed(kctx, TEST_FILE("./test/data/kms-azure/oauth-response.txt")), kctx);
1085
+ kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1086
+ ASSERT(!kctx);
1087
+ ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
1088
+ }
1089
+
1090
+ // Recreate the `mongocrypt_ctx_t`. Expect the oauth token to be cached but the DEK not to be cached.
1091
+ mongocrypt_ctx_destroy(ctx);
1092
+
1093
+ ctx = mongocrypt_ctx_new(crypt);
1094
+ ASSERT_OK(mongocrypt_ctx_explicit_decrypt_init(ctx, _mongocrypt_buffer_as_binary(&ciphertext)), ctx);
1095
+
1096
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_KEYS);
1097
+ ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, _mongocrypt_buffer_as_binary(&dek1)), ctx);
1098
+ ASSERT_OK(mongocrypt_ctx_mongo_done(ctx), ctx);
1099
+
1100
+ // Needs KMS to decrypt DEK.
1101
+ {
1102
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
1103
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1104
+ ASSERT(kctx);
1105
+ const char *endpoint;
1106
+ ASSERT_OK(mongocrypt_kms_ctx_endpoint(kctx, &endpoint), kctx);
1107
+ ASSERT_STREQUAL(endpoint, "placeholder1-keyVaultEndpoint.com:443");
1108
+ ASSERT_OK(mongocrypt_kms_ctx_feed(kctx, TEST_FILE("./test/data/kms-azure/decrypt-response.txt")), kctx);
1109
+ kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1110
+ ASSERT(!kctx);
1111
+ ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
1112
+ }
1113
+
1114
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_READY);
1115
+ mongocrypt_binary_t *bin = mongocrypt_binary_new();
1116
+ ASSERT_OK(mongocrypt_ctx_finalize(ctx, bin), ctx);
1117
+ ASSERT_MONGOCRYPT_BINARY_EQUAL_BSON(TEST_BSON(BSON_STR({"v" : "foo"})), bin);
1118
+ mongocrypt_binary_destroy(bin);
1119
+ mongocrypt_ctx_destroy(ctx);
1120
+ mongocrypt_destroy(crypt);
1121
+ }
1122
+
1123
+ // Test encrypting with two different named Azure.
1124
+ // Expect two separate oauth token requests.
1125
+ {
1126
+ mongocrypt_t *crypt = mongocrypt_new();
1127
+ ASSERT_OK(mongocrypt_setopt_kms_providers(crypt, kms_providers), crypt);
1128
+ ASSERT_OK(_mongocrypt_init_for_test(crypt), crypt);
1129
+
1130
+ // Encrypt with azure:name1
1131
+ {
1132
+ mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
1133
+ ASSERT_OK(mongocrypt_ctx_setopt_key_alt_name(ctx, TEST_BSON(BSON_STR({"keyAltName" : "azure1"}))), ctx);
1134
+ ASSERT_OK(mongocrypt_ctx_setopt_algorithm(ctx, MONGOCRYPT_ALGORITHM_DETERMINISTIC_STR, -1), ctx);
1135
+ ASSERT_OK(mongocrypt_ctx_explicit_encrypt_init(ctx, TEST_BSON(BSON_STR({"v" : "foo"}))), ctx);
1136
+
1137
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_KEYS);
1138
+ ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, _mongocrypt_buffer_as_binary(&dek1)), ctx);
1139
+ ASSERT_OK(mongocrypt_ctx_mongo_done(ctx), ctx);
1140
+
1141
+ // Needs KMS for oauth token.
1142
+ {
1143
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
1144
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1145
+ ASSERT(kctx);
1146
+ const char *endpoint;
1147
+ ASSERT_OK(mongocrypt_kms_ctx_endpoint(kctx, &endpoint), kctx);
1148
+ ASSERT_STREQUAL(endpoint, "placeholder1-identityPlatformEndpoint.com:443");
1149
+ ASSERT_OK(mongocrypt_kms_ctx_feed(kctx, TEST_FILE("./test/data/kms-azure/oauth-response.txt")), kctx);
1150
+ kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1151
+ ASSERT(!kctx);
1152
+ ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
1153
+ }
1154
+
1155
+ // Needs KMS to decrypt DEK.
1156
+ {
1157
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
1158
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1159
+ ASSERT(kctx);
1160
+ const char *endpoint;
1161
+ ASSERT_OK(mongocrypt_kms_ctx_endpoint(kctx, &endpoint), kctx);
1162
+ ASSERT_STREQUAL(endpoint, "placeholder1-keyVaultEndpoint.com:443");
1163
+ ASSERT_OK(mongocrypt_kms_ctx_feed(kctx, TEST_FILE("./test/data/kms-azure/decrypt-response.txt")), kctx);
1164
+ kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1165
+ ASSERT(!kctx);
1166
+ ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
1167
+ }
1168
+
1169
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_READY);
1170
+ mongocrypt_binary_t *bin = mongocrypt_binary_new();
1171
+ ASSERT_OK(mongocrypt_ctx_finalize(ctx, bin), ctx);
1172
+ mongocrypt_binary_destroy(bin);
1173
+ mongocrypt_ctx_destroy(ctx);
1174
+ }
1175
+
1176
+ // Encrypt with azure:name2
1177
+ {
1178
+ mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
1179
+ ASSERT_OK(mongocrypt_ctx_setopt_key_alt_name(ctx, TEST_BSON(BSON_STR({"keyAltName" : "azure2"}))), ctx);
1180
+ ASSERT_OK(mongocrypt_ctx_setopt_algorithm(ctx, MONGOCRYPT_ALGORITHM_DETERMINISTIC_STR, -1), ctx);
1181
+ ASSERT_OK(mongocrypt_ctx_explicit_encrypt_init(ctx, TEST_BSON(BSON_STR({"v" : "foo"}))), ctx);
1182
+
1183
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_KEYS);
1184
+ ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, _mongocrypt_buffer_as_binary(&dek2)), ctx);
1185
+ ASSERT_OK(mongocrypt_ctx_mongo_done(ctx), ctx);
1186
+
1187
+ // Needs KMS for oauth token.
1188
+ {
1189
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
1190
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1191
+ ASSERT(kctx);
1192
+ const char *endpoint;
1193
+ ASSERT_OK(mongocrypt_kms_ctx_endpoint(kctx, &endpoint), kctx);
1194
+ ASSERT_STREQUAL(endpoint, "placeholder2-identityPlatformEndpoint.com:443");
1195
+ ASSERT_OK(mongocrypt_kms_ctx_feed(kctx, TEST_FILE("./test/data/kms-azure/oauth-response.txt")), kctx);
1196
+ kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1197
+ ASSERT(!kctx);
1198
+ ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
1199
+ }
1200
+
1201
+ // Needs KMS to decrypt DEK.
1202
+ {
1203
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
1204
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1205
+ ASSERT(kctx);
1206
+ const char *endpoint;
1207
+ ASSERT_OK(mongocrypt_kms_ctx_endpoint(kctx, &endpoint), kctx);
1208
+ ASSERT_STREQUAL(endpoint, "placeholder2-keyVaultEndpoint.com:443");
1209
+ ASSERT_OK(mongocrypt_kms_ctx_feed(kctx, TEST_FILE("./test/data/kms-azure/decrypt-response.txt")), kctx);
1210
+ kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1211
+ ASSERT(!kctx);
1212
+ ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
1213
+ }
1214
+
1215
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_READY);
1216
+ mongocrypt_binary_t *bin = mongocrypt_binary_new();
1217
+ ASSERT_OK(mongocrypt_ctx_finalize(ctx, bin), ctx);
1218
+ mongocrypt_binary_destroy(bin);
1219
+ mongocrypt_ctx_destroy(ctx);
1220
+ }
1221
+ mongocrypt_destroy(crypt);
1222
+ }
1223
+
1224
+ // Test encrypting when access token is included in KMS providers.
1225
+ {
1226
+ mongocrypt_t *crypt = mongocrypt_new();
1227
+
1228
+ mongocrypt_binary_t *kms_providers_withAccessToken =
1229
+ TEST_BSON(BSON_STR({"azure:name3_withAccessToken" : {"accessToken" : "placeholder3-accesstoken"}}));
1230
+
1231
+ ASSERT_OK(mongocrypt_setopt_kms_providers(crypt, kms_providers_withAccessToken), crypt);
1232
+ ASSERT_OK(_mongocrypt_init_for_test(crypt), crypt);
1233
+
1234
+ // Create `dek3` from `azure:name3_withAccessToken`
1235
+ _mongocrypt_buffer_t dek3;
1236
+ create_dek(tester,
1237
+ (create_dek_args){.kms_providers = kms_providers_withAccessToken,
1238
+ .key_alt_name = "azure3",
1239
+ .kek = TEST_BSON(BSON_STR({
1240
+ "provider" : "azure:name3_withAccessToken",
1241
+ "keyName" : "placeholder3-keyName",
1242
+ "keyVaultEndpoint" : "placeholder3-keyVaultEndpoint.com"
1243
+ })),
1244
+ // Does not need KMS for oauth token.
1245
+ .kms_response_1 = TEST_FILE("./test/data/kms-azure/encrypt-response.txt")},
1246
+ &dek3);
1247
+
1248
+ // Encrypt with `dek3`.
1249
+ {
1250
+ mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
1251
+ ASSERT_OK(mongocrypt_ctx_setopt_key_alt_name(ctx, TEST_BSON(BSON_STR({"keyAltName" : "azure3"}))), ctx);
1252
+ ASSERT_OK(mongocrypt_ctx_setopt_algorithm(ctx, MONGOCRYPT_ALGORITHM_DETERMINISTIC_STR, -1), ctx);
1253
+ ASSERT_OK(mongocrypt_ctx_explicit_encrypt_init(ctx, TEST_BSON(BSON_STR({"v" : "foo"}))), ctx);
1254
+
1255
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_KEYS);
1256
+ ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, _mongocrypt_buffer_as_binary(&dek3)), ctx);
1257
+ ASSERT_OK(mongocrypt_ctx_mongo_done(ctx), ctx);
1258
+
1259
+ // Does not need KMS for oauth token.
1260
+
1261
+ // Needs KMS to decrypt DEK.
1262
+ {
1263
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
1264
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1265
+ ASSERT(kctx);
1266
+ const char *endpoint;
1267
+ ASSERT_OK(mongocrypt_kms_ctx_endpoint(kctx, &endpoint), kctx);
1268
+ ASSERT_STREQUAL(endpoint, "placeholder3-keyVaultEndpoint.com:443");
1269
+ ASSERT_OK(mongocrypt_kms_ctx_feed(kctx, TEST_FILE("./test/data/kms-azure/decrypt-response.txt")), kctx);
1270
+ kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1271
+ ASSERT(!kctx);
1272
+ ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
1273
+ }
1274
+
1275
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_READY);
1276
+ mongocrypt_binary_t *bin = mongocrypt_binary_new();
1277
+ ASSERT_OK(mongocrypt_ctx_finalize(ctx, bin), ctx);
1278
+ mongocrypt_binary_destroy(bin);
1279
+ mongocrypt_ctx_destroy(ctx);
1280
+ }
1281
+ _mongocrypt_buffer_cleanup(&dek3);
1282
+ mongocrypt_destroy(crypt);
1283
+ }
1284
+
1285
+ _mongocrypt_buffer_cleanup(&ciphertext);
1286
+ _mongocrypt_buffer_cleanup(&dek2);
1287
+ _mongocrypt_buffer_cleanup(&dek1);
1288
+ }
1289
+
1290
+ static void test_explicit_with_named_kms_provider_for_gcp(_mongocrypt_tester_t *tester) {
1291
+ mongocrypt_binary_t *kms_providers = TEST_BSON(
1292
+ BSON_STR({
1293
+ "gcp:name1" :
1294
+ {"email" : "placeholder1-email", "privateKey" : "%s", "endpoint" : "placeholder1-oauthEndpoint.com"},
1295
+ "gcp:name2" :
1296
+ {"email" : "placeholder2-email", "privateKey" : "%s", "endpoint" : "placeholder2-oauthEndpoint.com"}
1297
+ }),
1298
+ GCP_PRIVATEKEY1,
1299
+ GCP_PRIVATEKEY2);
1300
+
1301
+ // Create `dek1` from `gcp:name1`
1302
+ _mongocrypt_buffer_t dek1;
1303
+ create_dek(tester,
1304
+ (create_dek_args){.kms_providers = kms_providers,
1305
+ .key_alt_name = "gcp1",
1306
+ .kek = TEST_BSON(BSON_STR({
1307
+ "provider" : "gcp:name1",
1308
+ "projectId" : "placeholder1-projectId",
1309
+ "location" : "placeholder1-location",
1310
+ "keyRing" : "placeholder1-keyRing",
1311
+ "keyName" : "placeholder1-keyName",
1312
+ "endpoint" : "placeholder1-kmsEndpoint.com"
1313
+ })),
1314
+ .kms_response_1 = TEST_FILE("./test/data/kms-gcp/oauth-response.txt"),
1315
+ .kms_response_2 = TEST_FILE("./test/data/kms-gcp/encrypt-response.txt")},
1316
+ &dek1);
1317
+
1318
+ // Create `dek2` from `gcp:name2`
1319
+ _mongocrypt_buffer_t dek2;
1320
+ create_dek(tester,
1321
+ (create_dek_args){.kms_providers = kms_providers,
1322
+ .key_alt_name = "gcp2",
1323
+ .kek = TEST_BSON(BSON_STR({
1324
+ "provider" : "gcp:name2",
1325
+ "projectId" : "placeholder2-projectId",
1326
+ "location" : "placeholder2-location",
1327
+ "keyRing" : "placeholder2-keyRing",
1328
+ "keyName" : "placeholder2-keyName",
1329
+ "endpoint" : "placeholder2-kmsEndpoint.com"
1330
+ })),
1331
+ .kms_response_1 = TEST_FILE("./test/data/kms-gcp/oauth-response.txt"),
1332
+ .kms_response_2 = TEST_FILE("./test/data/kms-gcp/encrypt-response.txt")},
1333
+ &dek2);
1334
+
1335
+ // Test encrypting.
1336
+ _mongocrypt_buffer_t ciphertext;
1337
+ {
1338
+ mongocrypt_t *crypt = mongocrypt_new();
1339
+ ASSERT_OK(mongocrypt_setopt_kms_providers(crypt, kms_providers), crypt);
1340
+ ASSERT_OK(_mongocrypt_init_for_test(crypt), crypt);
1341
+
1342
+ // Test encrypting without cached DEK. Store result for later decryption.
1343
+ {
1344
+ mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
1345
+ ASSERT_OK(mongocrypt_ctx_setopt_key_alt_name(ctx, TEST_BSON(BSON_STR({"keyAltName" : "gcp1"}))), ctx);
1346
+ ASSERT_OK(mongocrypt_ctx_setopt_algorithm(ctx, MONGOCRYPT_ALGORITHM_DETERMINISTIC_STR, -1), ctx);
1347
+ ASSERT_OK(mongocrypt_ctx_explicit_encrypt_init(ctx, TEST_BSON(BSON_STR({"v" : "foo"}))), ctx);
1348
+
1349
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_KEYS);
1350
+ ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, _mongocrypt_buffer_as_binary(&dek1)), ctx);
1351
+ ASSERT_OK(mongocrypt_ctx_mongo_done(ctx), ctx);
1352
+
1353
+ // Needs KMS for oauth token.
1354
+ {
1355
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
1356
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1357
+ ASSERT(kctx);
1358
+ const char *endpoint;
1359
+ ASSERT_OK(mongocrypt_kms_ctx_endpoint(kctx, &endpoint), kctx);
1360
+ ASSERT_STREQUAL(endpoint, "placeholder1-oauthEndpoint.com:443");
1361
+ ASSERT_OK(mongocrypt_kms_ctx_feed(kctx, TEST_FILE("./test/data/kms-gcp/oauth-response.txt")), kctx);
1362
+ kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1363
+ ASSERT(!kctx);
1364
+ ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
1365
+ }
1366
+
1367
+ // Needs KMS to decrypt DEK.
1368
+ {
1369
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
1370
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1371
+ ASSERT(kctx);
1372
+ const char *endpoint;
1373
+ ASSERT_OK(mongocrypt_kms_ctx_endpoint(kctx, &endpoint), kctx);
1374
+ ASSERT_STREQUAL(endpoint, "placeholder1-kmsEndpoint.com:443");
1375
+ ASSERT_OK(mongocrypt_kms_ctx_feed(kctx, TEST_FILE("./test/data/kms-gcp/decrypt-response.txt")), kctx);
1376
+ kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1377
+ ASSERT(!kctx);
1378
+ ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
1379
+ }
1380
+
1381
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_READY);
1382
+ mongocrypt_binary_t *bin = mongocrypt_binary_new();
1383
+ ASSERT_OK(mongocrypt_ctx_finalize(ctx, bin), ctx);
1384
+ _mongocrypt_buffer_copy_from_binary(&ciphertext, bin);
1385
+ mongocrypt_binary_destroy(bin);
1386
+ mongocrypt_ctx_destroy(ctx);
1387
+ }
1388
+
1389
+ // Test encrypting with cached DEK.
1390
+ {
1391
+ mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
1392
+ ASSERT_OK(mongocrypt_ctx_setopt_key_alt_name(ctx, TEST_BSON(BSON_STR({"keyAltName" : "gcp1"}))), ctx);
1393
+ ASSERT_OK(mongocrypt_ctx_setopt_algorithm(ctx, MONGOCRYPT_ALGORITHM_DETERMINISTIC_STR, -1), ctx);
1394
+ ASSERT_OK(mongocrypt_ctx_explicit_encrypt_init(ctx, TEST_BSON(BSON_STR({"v" : "foo"}))), ctx);
1395
+ // DEK is already cached. State transitions directly to ready.
1396
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_READY);
1397
+ mongocrypt_binary_t *bin = mongocrypt_binary_new();
1398
+ ASSERT_OK(mongocrypt_ctx_finalize(ctx, bin), ctx);
1399
+ mongocrypt_binary_destroy(bin);
1400
+ mongocrypt_ctx_destroy(ctx);
1401
+ }
1402
+
1403
+ mongocrypt_destroy(crypt);
1404
+ }
1405
+
1406
+ // Test decrypting.
1407
+ {
1408
+ mongocrypt_t *crypt = mongocrypt_new();
1409
+ ASSERT_OK(mongocrypt_setopt_kms_providers(crypt, kms_providers), crypt);
1410
+ ASSERT_OK(_mongocrypt_init_for_test(crypt), crypt);
1411
+
1412
+ // Test decrypting without cached DEK.
1413
+ {
1414
+ mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
1415
+ ASSERT_OK(mongocrypt_ctx_explicit_decrypt_init(ctx, _mongocrypt_buffer_as_binary(&ciphertext)), ctx);
1416
+
1417
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_KEYS);
1418
+ ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, _mongocrypt_buffer_as_binary(&dek1)), ctx);
1419
+ ASSERT_OK(mongocrypt_ctx_mongo_done(ctx), ctx);
1420
+
1421
+ // Needs KMS for oauth token.
1422
+ {
1423
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
1424
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1425
+ ASSERT(kctx);
1426
+ const char *endpoint;
1427
+ ASSERT_OK(mongocrypt_kms_ctx_endpoint(kctx, &endpoint), kctx);
1428
+ ASSERT_STREQUAL(endpoint, "placeholder1-oauthEndpoint.com:443");
1429
+ ASSERT_OK(mongocrypt_kms_ctx_feed(kctx, TEST_FILE("./test/data/kms-gcp/oauth-response.txt")), kctx);
1430
+ kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1431
+ ASSERT(!kctx);
1432
+ ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
1433
+ }
1434
+
1435
+ // Needs KMS to decrypt DEK.
1436
+ {
1437
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
1438
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1439
+ ASSERT(kctx);
1440
+ const char *endpoint;
1441
+ ASSERT_OK(mongocrypt_kms_ctx_endpoint(kctx, &endpoint), kctx);
1442
+ ASSERT_STREQUAL(endpoint, "placeholder1-kmsEndpoint.com:443");
1443
+ ASSERT_OK(mongocrypt_kms_ctx_feed(kctx, TEST_FILE("./test/data/kms-gcp/decrypt-response.txt")), kctx);
1444
+ kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1445
+ ASSERT(!kctx);
1446
+ ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
1447
+ }
1448
+
1449
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_READY);
1450
+ mongocrypt_binary_t *bin = mongocrypt_binary_new();
1451
+ ASSERT_OK(mongocrypt_ctx_finalize(ctx, bin), ctx);
1452
+ ASSERT_MONGOCRYPT_BINARY_EQUAL_BSON(TEST_BSON(BSON_STR({"v" : "foo"})), bin);
1453
+ mongocrypt_binary_destroy(bin);
1454
+ mongocrypt_ctx_destroy(ctx);
1455
+ }
1456
+
1457
+ // Test decrypting with cached DEK.
1458
+ {
1459
+ mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
1460
+ ASSERT_OK(mongocrypt_ctx_explicit_decrypt_init(ctx, _mongocrypt_buffer_as_binary(&ciphertext)), ctx);
1461
+ // DEK is already cached. State transitions directly to ready.
1462
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_READY);
1463
+ mongocrypt_binary_t *bin = mongocrypt_binary_new();
1464
+ ASSERT_OK(mongocrypt_ctx_finalize(ctx, bin), ctx);
1465
+ ASSERT_MONGOCRYPT_BINARY_EQUAL_BSON(TEST_BSON(BSON_STR({"v" : "foo"})), bin);
1466
+ mongocrypt_binary_destroy(bin);
1467
+ mongocrypt_ctx_destroy(ctx);
1468
+ }
1469
+ mongocrypt_destroy(crypt);
1470
+ }
1471
+
1472
+ // Test decrypting with a cached oauth token, but not a cached DEK.
1473
+ {
1474
+ mongocrypt_t *crypt = mongocrypt_new();
1475
+ ASSERT_OK(mongocrypt_setopt_kms_providers(crypt, kms_providers), crypt);
1476
+ ASSERT_OK(_mongocrypt_init_for_test(crypt), crypt);
1477
+
1478
+ // Decrypt.
1479
+ mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
1480
+ ASSERT_OK(mongocrypt_ctx_explicit_decrypt_init(ctx, _mongocrypt_buffer_as_binary(&ciphertext)), ctx);
1481
+
1482
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_KEYS);
1483
+ ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, _mongocrypt_buffer_as_binary(&dek1)), ctx);
1484
+ ASSERT_OK(mongocrypt_ctx_mongo_done(ctx), ctx);
1485
+
1486
+ // Needs KMS for oauth token.
1487
+ {
1488
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
1489
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1490
+ ASSERT(kctx);
1491
+ const char *endpoint;
1492
+ ASSERT_OK(mongocrypt_kms_ctx_endpoint(kctx, &endpoint), kctx);
1493
+ ASSERT_STREQUAL(endpoint, "placeholder1-oauthEndpoint.com:443");
1494
+ ASSERT_OK(mongocrypt_kms_ctx_feed(kctx, TEST_FILE("./test/data/kms-gcp/oauth-response.txt")), kctx);
1495
+ kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1496
+ ASSERT(!kctx);
1497
+ ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
1498
+ }
1499
+
1500
+ // Recreate the `mongocrypt_ctx_t`. Expect the oauth token to be cached but the DEK not to be cached.
1501
+ mongocrypt_ctx_destroy(ctx);
1502
+
1503
+ ctx = mongocrypt_ctx_new(crypt);
1504
+ ASSERT_OK(mongocrypt_ctx_explicit_decrypt_init(ctx, _mongocrypt_buffer_as_binary(&ciphertext)), ctx);
1505
+
1506
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_KEYS);
1507
+ ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, _mongocrypt_buffer_as_binary(&dek1)), ctx);
1508
+ ASSERT_OK(mongocrypt_ctx_mongo_done(ctx), ctx);
1509
+
1510
+ // Needs KMS to decrypt DEK.
1511
+ {
1512
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
1513
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1514
+ ASSERT(kctx);
1515
+ const char *endpoint;
1516
+ ASSERT_OK(mongocrypt_kms_ctx_endpoint(kctx, &endpoint), kctx);
1517
+ ASSERT_STREQUAL(endpoint, "placeholder1-kmsEndpoint.com:443");
1518
+ ASSERT_OK(mongocrypt_kms_ctx_feed(kctx, TEST_FILE("./test/data/kms-gcp/decrypt-response.txt")), kctx);
1519
+ kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1520
+ ASSERT(!kctx);
1521
+ ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
1522
+ }
1523
+
1524
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_READY);
1525
+ mongocrypt_binary_t *bin = mongocrypt_binary_new();
1526
+ ASSERT_OK(mongocrypt_ctx_finalize(ctx, bin), ctx);
1527
+ ASSERT_MONGOCRYPT_BINARY_EQUAL_BSON(TEST_BSON(BSON_STR({"v" : "foo"})), bin);
1528
+ mongocrypt_binary_destroy(bin);
1529
+ mongocrypt_ctx_destroy(ctx);
1530
+ mongocrypt_destroy(crypt);
1531
+ }
1532
+
1533
+ // Test encrypting with two different named Gcp.
1534
+ // Expect two separate oauth token requests.
1535
+ {
1536
+ mongocrypt_t *crypt = mongocrypt_new();
1537
+ ASSERT_OK(mongocrypt_setopt_kms_providers(crypt, kms_providers), crypt);
1538
+ ASSERT_OK(_mongocrypt_init_for_test(crypt), crypt);
1539
+
1540
+ // Encrypt with gcp:name1
1541
+ {
1542
+ mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
1543
+ ASSERT_OK(mongocrypt_ctx_setopt_key_alt_name(ctx, TEST_BSON(BSON_STR({"keyAltName" : "gcp1"}))), ctx);
1544
+ ASSERT_OK(mongocrypt_ctx_setopt_algorithm(ctx, MONGOCRYPT_ALGORITHM_DETERMINISTIC_STR, -1), ctx);
1545
+ ASSERT_OK(mongocrypt_ctx_explicit_encrypt_init(ctx, TEST_BSON(BSON_STR({"v" : "foo"}))), ctx);
1546
+
1547
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_KEYS);
1548
+ ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, _mongocrypt_buffer_as_binary(&dek1)), ctx);
1549
+ ASSERT_OK(mongocrypt_ctx_mongo_done(ctx), ctx);
1550
+
1551
+ // Needs KMS for oauth token.
1552
+ {
1553
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
1554
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1555
+ ASSERT(kctx);
1556
+ const char *endpoint;
1557
+ ASSERT_OK(mongocrypt_kms_ctx_endpoint(kctx, &endpoint), kctx);
1558
+ ASSERT_STREQUAL(endpoint, "placeholder1-oauthEndpoint.com:443");
1559
+ ASSERT_OK(mongocrypt_kms_ctx_feed(kctx, TEST_FILE("./test/data/kms-gcp/oauth-response.txt")), kctx);
1560
+ kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1561
+ ASSERT(!kctx);
1562
+ ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
1563
+ }
1564
+
1565
+ // Needs KMS to decrypt DEK.
1566
+ {
1567
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
1568
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1569
+ ASSERT(kctx);
1570
+ const char *endpoint;
1571
+ ASSERT_OK(mongocrypt_kms_ctx_endpoint(kctx, &endpoint), kctx);
1572
+ ASSERT_STREQUAL(endpoint, "placeholder1-kmsEndpoint.com:443");
1573
+ ASSERT_OK(mongocrypt_kms_ctx_feed(kctx, TEST_FILE("./test/data/kms-gcp/decrypt-response.txt")), kctx);
1574
+ kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1575
+ ASSERT(!kctx);
1576
+ ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
1577
+ }
1578
+
1579
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_READY);
1580
+ mongocrypt_binary_t *bin = mongocrypt_binary_new();
1581
+ ASSERT_OK(mongocrypt_ctx_finalize(ctx, bin), ctx);
1582
+ mongocrypt_binary_destroy(bin);
1583
+ mongocrypt_ctx_destroy(ctx);
1584
+ }
1585
+
1586
+ // Encrypt with gcp:name2
1587
+ {
1588
+ mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
1589
+ ASSERT_OK(mongocrypt_ctx_setopt_key_alt_name(ctx, TEST_BSON(BSON_STR({"keyAltName" : "gcp2"}))), ctx);
1590
+ ASSERT_OK(mongocrypt_ctx_setopt_algorithm(ctx, MONGOCRYPT_ALGORITHM_DETERMINISTIC_STR, -1), ctx);
1591
+ ASSERT_OK(mongocrypt_ctx_explicit_encrypt_init(ctx, TEST_BSON(BSON_STR({"v" : "foo"}))), ctx);
1592
+
1593
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_KEYS);
1594
+ ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, _mongocrypt_buffer_as_binary(&dek2)), ctx);
1595
+ ASSERT_OK(mongocrypt_ctx_mongo_done(ctx), ctx);
1596
+
1597
+ // Needs KMS for oauth token.
1598
+ {
1599
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
1600
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1601
+ ASSERT(kctx);
1602
+ const char *endpoint;
1603
+ ASSERT_OK(mongocrypt_kms_ctx_endpoint(kctx, &endpoint), kctx);
1604
+ ASSERT_STREQUAL(endpoint, "placeholder2-oauthEndpoint.com:443");
1605
+ ASSERT_OK(mongocrypt_kms_ctx_feed(kctx, TEST_FILE("./test/data/kms-gcp/oauth-response.txt")), kctx);
1606
+ kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1607
+ ASSERT(!kctx);
1608
+ ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
1609
+ }
1610
+
1611
+ // Needs KMS to decrypt DEK.
1612
+ {
1613
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
1614
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1615
+ ASSERT(kctx);
1616
+ const char *endpoint;
1617
+ ASSERT_OK(mongocrypt_kms_ctx_endpoint(kctx, &endpoint), kctx);
1618
+ ASSERT_STREQUAL(endpoint, "placeholder2-kmsEndpoint.com:443");
1619
+ ASSERT_OK(mongocrypt_kms_ctx_feed(kctx, TEST_FILE("./test/data/kms-gcp/decrypt-response.txt")), kctx);
1620
+ kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1621
+ ASSERT(!kctx);
1622
+ ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
1623
+ }
1624
+
1625
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_READY);
1626
+ mongocrypt_binary_t *bin = mongocrypt_binary_new();
1627
+ ASSERT_OK(mongocrypt_ctx_finalize(ctx, bin), ctx);
1628
+ mongocrypt_binary_destroy(bin);
1629
+ mongocrypt_ctx_destroy(ctx);
1630
+ }
1631
+ mongocrypt_destroy(crypt);
1632
+ }
1633
+
1634
+ // Test calling `mongocrypt_ctx_kms_done` before responding to an oauth request.
1635
+ {
1636
+ mongocrypt_t *crypt = mongocrypt_new();
1637
+ ASSERT_OK(mongocrypt_setopt_kms_providers(crypt, kms_providers), crypt);
1638
+ ASSERT_OK(_mongocrypt_init_for_test(crypt), crypt);
1639
+
1640
+ mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
1641
+ ASSERT_OK(mongocrypt_ctx_setopt_key_alt_name(ctx, TEST_BSON(BSON_STR({"keyAltName" : "gcp1"}))), ctx);
1642
+ ASSERT_OK(mongocrypt_ctx_setopt_algorithm(ctx, MONGOCRYPT_ALGORITHM_DETERMINISTIC_STR, -1), ctx);
1643
+ ASSERT_OK(mongocrypt_ctx_explicit_encrypt_init(ctx, TEST_BSON(BSON_STR({"v" : "foo"}))), ctx);
1644
+
1645
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_KEYS);
1646
+ ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, _mongocrypt_buffer_as_binary(&dek1)), ctx);
1647
+ ASSERT_OK(mongocrypt_ctx_mongo_done(ctx), ctx);
1648
+
1649
+ // Needs KMS for oauth token.
1650
+ {
1651
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
1652
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1653
+ ASSERT(kctx);
1654
+ const char *endpoint;
1655
+ ASSERT_OK(mongocrypt_kms_ctx_endpoint(kctx, &endpoint), kctx);
1656
+ ASSERT_FAILS(mongocrypt_ctx_kms_done(ctx), ctx, "KMS response unfinished");
1657
+ }
1658
+
1659
+ mongocrypt_ctx_destroy(ctx);
1660
+ mongocrypt_destroy(crypt);
1661
+ }
1662
+
1663
+ // Test calling `mongocrypt_ctx_kms_done` before responding to a decrypt request.
1664
+ {
1665
+ mongocrypt_t *crypt = mongocrypt_new();
1666
+ ASSERT_OK(mongocrypt_setopt_kms_providers(crypt, kms_providers), crypt);
1667
+ ASSERT_OK(_mongocrypt_init_for_test(crypt), crypt);
1668
+
1669
+ mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
1670
+ ASSERT_OK(mongocrypt_ctx_setopt_key_alt_name(ctx, TEST_BSON(BSON_STR({"keyAltName" : "gcp1"}))), ctx);
1671
+ ASSERT_OK(mongocrypt_ctx_setopt_algorithm(ctx, MONGOCRYPT_ALGORITHM_DETERMINISTIC_STR, -1), ctx);
1672
+ ASSERT_OK(mongocrypt_ctx_explicit_encrypt_init(ctx, TEST_BSON(BSON_STR({"v" : "foo"}))), ctx);
1673
+
1674
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_KEYS);
1675
+ ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, _mongocrypt_buffer_as_binary(&dek1)), ctx);
1676
+ ASSERT_OK(mongocrypt_ctx_mongo_done(ctx), ctx);
1677
+
1678
+ // Needs KMS for oauth token.
1679
+ {
1680
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
1681
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1682
+ ASSERT(kctx);
1683
+ const char *endpoint;
1684
+ ASSERT_OK(mongocrypt_kms_ctx_endpoint(kctx, &endpoint), kctx);
1685
+ ASSERT_STREQUAL(endpoint, "placeholder1-oauthEndpoint.com:443");
1686
+ ASSERT_OK(mongocrypt_kms_ctx_feed(kctx, TEST_FILE("./test/data/kms-gcp/oauth-response.txt")), kctx);
1687
+ kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1688
+ ASSERT(!kctx);
1689
+ ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
1690
+ }
1691
+
1692
+ // Needs KMS to decrypt DEK.
1693
+ {
1694
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
1695
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1696
+ ASSERT(kctx);
1697
+ const char *endpoint;
1698
+ ASSERT_OK(mongocrypt_kms_ctx_endpoint(kctx, &endpoint), kctx);
1699
+ ASSERT_STREQUAL(endpoint, "placeholder1-kmsEndpoint.com:443");
1700
+ ASSERT_FAILS(mongocrypt_ctx_kms_done(ctx), ctx, "KMS response unfinished");
1701
+ }
1702
+
1703
+ mongocrypt_ctx_destroy(ctx);
1704
+ mongocrypt_destroy(crypt);
1705
+ }
1706
+
1707
+ // Test encrypting when access token is included in KMS providers.
1708
+ {
1709
+ mongocrypt_t *crypt = mongocrypt_new();
1710
+ mongocrypt_binary_t *kms_providers_withAccessToken =
1711
+ TEST_BSON(BSON_STR({"gcp:name3_withAccessToken" : {"accessToken" : "placeholder3-accesstoken"}}));
1712
+
1713
+ ASSERT_OK(mongocrypt_setopt_kms_providers(crypt, kms_providers_withAccessToken), crypt);
1714
+ ASSERT_OK(_mongocrypt_init_for_test(crypt), crypt);
1715
+
1716
+ // Create `dek3` from `gcp:name3_withAccessToken`
1717
+ _mongocrypt_buffer_t dek3;
1718
+ {
1719
+ create_dek(tester,
1720
+ (create_dek_args){.kms_providers = kms_providers_withAccessToken,
1721
+ .key_alt_name = "gcp3",
1722
+ .kek = TEST_BSON(BSON_STR({
1723
+ "provider" : "gcp:name3_withAccessToken",
1724
+ "projectId" : "placeholder3-projectId",
1725
+ "location" : "placeholder3-location",
1726
+ "keyRing" : "placeholder3-keyRing",
1727
+ "keyName" : "placeholder3-keyName",
1728
+ "endpoint" : "placeholder3-kmsEndpoint.com"
1729
+ })),
1730
+ // Does not need KMS for oauth token.
1731
+
1732
+ .kms_response_1 = TEST_FILE("./test/data/kms-gcp/encrypt-response.txt")},
1733
+ &dek3);
1734
+ }
1735
+
1736
+ // Encrypt with `dek3`.
1737
+ {
1738
+ mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
1739
+ ASSERT_OK(mongocrypt_ctx_setopt_key_alt_name(ctx, TEST_BSON(BSON_STR({"keyAltName" : "gcp3"}))), ctx);
1740
+ ASSERT_OK(mongocrypt_ctx_setopt_algorithm(ctx, MONGOCRYPT_ALGORITHM_DETERMINISTIC_STR, -1), ctx);
1741
+ ASSERT_OK(mongocrypt_ctx_explicit_encrypt_init(ctx, TEST_BSON(BSON_STR({"v" : "foo"}))), ctx);
1742
+
1743
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_KEYS);
1744
+ ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, _mongocrypt_buffer_as_binary(&dek3)), ctx);
1745
+ ASSERT_OK(mongocrypt_ctx_mongo_done(ctx), ctx);
1746
+
1747
+ // Does not need KMS for oauth token.
1748
+
1749
+ // Needs KMS to decrypt DEK.
1750
+ {
1751
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
1752
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1753
+ ASSERT(kctx);
1754
+ const char *endpoint;
1755
+ ASSERT_OK(mongocrypt_kms_ctx_endpoint(kctx, &endpoint), kctx);
1756
+ ASSERT_STREQUAL(endpoint, "placeholder3-kmsEndpoint.com:443");
1757
+ ASSERT_OK(mongocrypt_kms_ctx_feed(kctx, TEST_FILE("./test/data/kms-gcp/decrypt-response.txt")), kctx);
1758
+ kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1759
+ ASSERT(!kctx);
1760
+ ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
1761
+ }
1762
+
1763
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_READY);
1764
+ mongocrypt_binary_t *bin = mongocrypt_binary_new();
1765
+ ASSERT_OK(mongocrypt_ctx_finalize(ctx, bin), ctx);
1766
+ mongocrypt_binary_destroy(bin);
1767
+ mongocrypt_ctx_destroy(ctx);
1768
+ }
1769
+ _mongocrypt_buffer_cleanup(&dek3);
1770
+ mongocrypt_destroy(crypt);
1771
+ }
1772
+
1773
+ _mongocrypt_buffer_cleanup(&ciphertext);
1774
+ _mongocrypt_buffer_cleanup(&dek2);
1775
+ _mongocrypt_buffer_cleanup(&dek1);
1776
+ }
1777
+
1778
+ static void test_explicit_with_named_kms_provider_for_aws(_mongocrypt_tester_t *tester) {
1779
+ mongocrypt_binary_t *kms_providers = TEST_BSON(BSON_STR({
1780
+ "aws:name1" : {"accessKeyId" : "placeholder1-aki", "secretAccessKey" : "placeholder1-sak"},
1781
+ "aws:name2" : {"accessKeyId" : "placeholder2-aki", "secretAccessKey" : "placeholder2-sak"}
1782
+ }));
1783
+
1784
+ // Create `dek1` from `aws:name1`
1785
+ _mongocrypt_buffer_t dek1;
1786
+ create_dek(tester,
1787
+ (create_dek_args){.kms_providers = kms_providers,
1788
+ .key_alt_name = "aws1",
1789
+ .kek = TEST_BSON(BSON_STR({
1790
+ "provider" : "aws:name1",
1791
+ "region" : "placeholder1-region",
1792
+ "key" : "placeholder1-key",
1793
+ "endpoint" : "placeholder1-endpoint.com"
1794
+ })),
1795
+ .kms_response_1 = TEST_FILE("./test/data/kms-aws/encrypt-response.txt")},
1796
+ &dek1);
1797
+
1798
+ // Create `dek2` from `aws:name2`
1799
+ _mongocrypt_buffer_t dek2;
1800
+ create_dek(tester,
1801
+ (create_dek_args){.kms_providers = kms_providers,
1802
+ .key_alt_name = "aws2",
1803
+ .kek = TEST_BSON(BSON_STR({
1804
+ "provider" : "aws:name2",
1805
+ "region" : "placeholder2-region",
1806
+ "key" : "placeholder2-key",
1807
+ "endpoint" : "placeholder2-endpoint.com"
1808
+ })),
1809
+ .kms_response_1 = TEST_FILE("./test/data/kms-aws/encrypt-response.txt")},
1810
+ &dek2);
1811
+
1812
+ // Test encrypting.
1813
+ _mongocrypt_buffer_t ciphertext;
1814
+ {
1815
+ mongocrypt_t *crypt = mongocrypt_new();
1816
+ ASSERT_OK(mongocrypt_setopt_kms_providers(crypt, kms_providers), crypt);
1817
+ ASSERT_OK(_mongocrypt_init_for_test(crypt), crypt);
1818
+
1819
+ // Test encrypting without cached DEK. Store result for later decryption.
1820
+ {
1821
+ mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
1822
+ ASSERT_OK(mongocrypt_ctx_setopt_key_alt_name(ctx, TEST_BSON(BSON_STR({"keyAltName" : "aws1"}))), ctx);
1823
+ ASSERT_OK(mongocrypt_ctx_setopt_algorithm(ctx, MONGOCRYPT_ALGORITHM_DETERMINISTIC_STR, -1), ctx);
1824
+ ASSERT_OK(mongocrypt_ctx_explicit_encrypt_init(ctx, TEST_BSON(BSON_STR({"v" : "foo"}))), ctx);
1825
+
1826
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_KEYS);
1827
+ ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, _mongocrypt_buffer_as_binary(&dek1)), ctx);
1828
+ ASSERT_OK(mongocrypt_ctx_mongo_done(ctx), ctx);
1829
+
1830
+ // Needs KMS to decrypt DEK.
1831
+ {
1832
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
1833
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1834
+ ASSERT(kctx);
1835
+ const char *endpoint;
1836
+ ASSERT_OK(mongocrypt_kms_ctx_endpoint(kctx, &endpoint), kctx);
1837
+ ASSERT_STREQUAL(endpoint, "placeholder1-endpoint.com:443");
1838
+ ASSERT_OK(mongocrypt_kms_ctx_feed(kctx, TEST_FILE("./test/data/kms-aws/decrypt-response.txt")), kctx);
1839
+ kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1840
+ ASSERT(!kctx);
1841
+ ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
1842
+ }
1843
+
1844
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_READY);
1845
+ mongocrypt_binary_t *bin = mongocrypt_binary_new();
1846
+ ASSERT_OK(mongocrypt_ctx_finalize(ctx, bin), ctx);
1847
+ _mongocrypt_buffer_copy_from_binary(&ciphertext, bin);
1848
+ mongocrypt_binary_destroy(bin);
1849
+ mongocrypt_ctx_destroy(ctx);
1850
+ }
1851
+
1852
+ // Test encrypting with cached DEK.
1853
+ {
1854
+ mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
1855
+ ASSERT_OK(mongocrypt_ctx_setopt_key_alt_name(ctx, TEST_BSON(BSON_STR({"keyAltName" : "aws1"}))), ctx);
1856
+ ASSERT_OK(mongocrypt_ctx_setopt_algorithm(ctx, MONGOCRYPT_ALGORITHM_DETERMINISTIC_STR, -1), ctx);
1857
+ ASSERT_OK(mongocrypt_ctx_explicit_encrypt_init(ctx, TEST_BSON(BSON_STR({"v" : "foo"}))), ctx);
1858
+ // DEK is already cached. State transitions directly to ready.
1859
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_READY);
1860
+ mongocrypt_binary_t *bin = mongocrypt_binary_new();
1861
+ ASSERT_OK(mongocrypt_ctx_finalize(ctx, bin), ctx);
1862
+ mongocrypt_binary_destroy(bin);
1863
+ mongocrypt_ctx_destroy(ctx);
1864
+ }
1865
+
1866
+ mongocrypt_destroy(crypt);
1867
+ }
1868
+
1869
+ // Test decrypting.
1870
+ {
1871
+ mongocrypt_t *crypt = mongocrypt_new();
1872
+ ASSERT_OK(mongocrypt_setopt_kms_providers(crypt, kms_providers), crypt);
1873
+ ASSERT_OK(_mongocrypt_init_for_test(crypt), crypt);
1874
+
1875
+ // Test decrypting without cached DEK.
1876
+ {
1877
+ mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
1878
+ ASSERT_OK(mongocrypt_ctx_explicit_decrypt_init(ctx, _mongocrypt_buffer_as_binary(&ciphertext)), ctx);
1879
+
1880
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_KEYS);
1881
+ ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, _mongocrypt_buffer_as_binary(&dek1)), ctx);
1882
+ ASSERT_OK(mongocrypt_ctx_mongo_done(ctx), ctx);
1883
+
1884
+ // Needs KMS to decrypt DEK.
1885
+ {
1886
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
1887
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1888
+ ASSERT(kctx);
1889
+ const char *endpoint;
1890
+ ASSERT_OK(mongocrypt_kms_ctx_endpoint(kctx, &endpoint), kctx);
1891
+ ASSERT_STREQUAL(endpoint, "placeholder1-endpoint.com:443");
1892
+ ASSERT_OK(mongocrypt_kms_ctx_feed(kctx, TEST_FILE("./test/example/kms-decrypt-reply.txt")), kctx);
1893
+ kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1894
+ ASSERT(!kctx);
1895
+ ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
1896
+ }
1897
+
1898
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_READY);
1899
+ mongocrypt_binary_t *bin = mongocrypt_binary_new();
1900
+ ASSERT_OK(mongocrypt_ctx_finalize(ctx, bin), ctx);
1901
+ ASSERT_MONGOCRYPT_BINARY_EQUAL_BSON(TEST_BSON(BSON_STR({"v" : "foo"})), bin);
1902
+ mongocrypt_binary_destroy(bin);
1903
+ mongocrypt_ctx_destroy(ctx);
1904
+ }
1905
+
1906
+ // Test decrypting with cached DEK.
1907
+ {
1908
+ mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
1909
+ ASSERT_OK(mongocrypt_ctx_explicit_decrypt_init(ctx, _mongocrypt_buffer_as_binary(&ciphertext)), ctx);
1910
+ // DEK is already cached. State transitions directly to ready.
1911
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_READY);
1912
+ mongocrypt_binary_t *bin = mongocrypt_binary_new();
1913
+ ASSERT_OK(mongocrypt_ctx_finalize(ctx, bin), ctx);
1914
+ ASSERT_MONGOCRYPT_BINARY_EQUAL_BSON(TEST_BSON(BSON_STR({"v" : "foo"})), bin);
1915
+ mongocrypt_binary_destroy(bin);
1916
+ mongocrypt_ctx_destroy(ctx);
1917
+ }
1918
+ mongocrypt_destroy(crypt);
1919
+ }
1920
+
1921
+ _mongocrypt_buffer_cleanup(&ciphertext);
1922
+ _mongocrypt_buffer_cleanup(&dek2);
1923
+ _mongocrypt_buffer_cleanup(&dek1);
1924
+ }
1925
+
1926
+ static void test_explicit_with_named_kms_provider_for_kmip(_mongocrypt_tester_t *tester) {
1927
+ mongocrypt_binary_t *kms_providers = TEST_BSON(BSON_STR({
1928
+ "kmip:name1" : {"endpoint" : "placeholder1-endpoint.com"},
1929
+ "kmip:name2" : {"endpoint" : "placeholder2-endpoint.com"}
1930
+ }));
1931
+
1932
+ mongocrypt_binary_t *get_response =
1933
+ mongocrypt_binary_new_from_data((uint8_t *)KMIP_GET_RESPONSE, (uint32_t)sizeof(KMIP_GET_RESPONSE));
1934
+
1935
+ // Create `dek1` from `kmip:name1`
1936
+ _mongocrypt_buffer_t dek1;
1937
+
1938
+ create_dek(tester,
1939
+ (create_dek_args){.kms_providers = kms_providers,
1940
+ .key_alt_name = "kmip1",
1941
+ .kek = TEST_BSON(BSON_STR({"provider" : "kmip:name1", "keyId" : "12"})),
1942
+ .kms_response_1 = get_response},
1943
+ &dek1);
1944
+
1945
+ // Create `dek2` from `kmip:name2`
1946
+ _mongocrypt_buffer_t dek2;
1947
+ create_dek(tester,
1948
+ (create_dek_args){.kms_providers = kms_providers,
1949
+ .key_alt_name = "kmip2",
1950
+ .kek = TEST_BSON(BSON_STR({"provider" : "kmip:name2", "keyId" : "12"})),
1951
+ .kms_response_1 = get_response},
1952
+ &dek2);
1953
+
1954
+ // Test encrypting.
1955
+ _mongocrypt_buffer_t ciphertext;
1956
+ {
1957
+ mongocrypt_t *crypt = mongocrypt_new();
1958
+ ASSERT_OK(mongocrypt_setopt_kms_providers(crypt, kms_providers), crypt);
1959
+ ASSERT_OK(_mongocrypt_init_for_test(crypt), crypt);
1960
+
1961
+ // Test encrypting without cached DEK. Store result for later decryption.
1962
+ {
1963
+ mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
1964
+ ASSERT_OK(mongocrypt_ctx_setopt_key_alt_name(ctx, TEST_BSON(BSON_STR({"keyAltName" : "kmip1"}))), ctx);
1965
+ ASSERT_OK(mongocrypt_ctx_setopt_algorithm(ctx, MONGOCRYPT_ALGORITHM_DETERMINISTIC_STR, -1), ctx);
1966
+ ASSERT_OK(mongocrypt_ctx_explicit_encrypt_init(ctx, TEST_BSON(BSON_STR({"v" : "foo"}))), ctx);
1967
+
1968
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_KEYS);
1969
+ ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, _mongocrypt_buffer_as_binary(&dek1)), ctx);
1970
+ ASSERT_OK(mongocrypt_ctx_mongo_done(ctx), ctx);
1971
+
1972
+ // Needs KMS to Get KEK.
1973
+ {
1974
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
1975
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1976
+ ASSERT(kctx);
1977
+ const char *endpoint;
1978
+ ASSERT_OK(mongocrypt_kms_ctx_endpoint(kctx, &endpoint), kctx);
1979
+ ASSERT_STREQUAL(endpoint, "placeholder1-endpoint.com:5696");
1980
+ // Assert request is a Get.
1981
+ {
1982
+ mongocrypt_binary_t *request = mongocrypt_binary_new();
1983
+ ASSERT_OK(mongocrypt_kms_ctx_message(kctx, request), kctx);
1984
+ ASSERT_STREQUAL(kmip_get_operation_type(request), "Get");
1985
+ mongocrypt_binary_destroy(request);
1986
+ }
1987
+ // Feed response to Get.
1988
+ ASSERT_OK(kms_ctx_feed_all(kctx, KMIP_GET_RESPONSE, (uint32_t)(sizeof(KMIP_GET_RESPONSE))), kctx);
1989
+ kctx = mongocrypt_ctx_next_kms_ctx(ctx);
1990
+ ASSERT(!kctx);
1991
+ ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
1992
+ }
1993
+
1994
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_READY);
1995
+ mongocrypt_binary_t *bin = mongocrypt_binary_new();
1996
+ ASSERT_OK(mongocrypt_ctx_finalize(ctx, bin), ctx);
1997
+ _mongocrypt_buffer_copy_from_binary(&ciphertext, bin);
1998
+ mongocrypt_binary_destroy(bin);
1999
+ mongocrypt_ctx_destroy(ctx);
2000
+ }
2001
+
2002
+ // Test encrypting with cached DEK.
2003
+ {
2004
+ mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
2005
+ ASSERT_OK(mongocrypt_ctx_setopt_key_alt_name(ctx, TEST_BSON(BSON_STR({"keyAltName" : "kmip1"}))), ctx);
2006
+ ASSERT_OK(mongocrypt_ctx_setopt_algorithm(ctx, MONGOCRYPT_ALGORITHM_DETERMINISTIC_STR, -1), ctx);
2007
+ ASSERT_OK(mongocrypt_ctx_explicit_encrypt_init(ctx, TEST_BSON(BSON_STR({"v" : "foo"}))), ctx);
2008
+ // DEK is already cached. State transitions directly to ready.
2009
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_READY);
2010
+ mongocrypt_binary_t *bin = mongocrypt_binary_new();
2011
+ ASSERT_OK(mongocrypt_ctx_finalize(ctx, bin), ctx);
2012
+ mongocrypt_binary_destroy(bin);
2013
+ mongocrypt_ctx_destroy(ctx);
2014
+ }
2015
+
2016
+ mongocrypt_destroy(crypt);
2017
+ }
2018
+
2019
+ // Test decrypting.
2020
+ {
2021
+ mongocrypt_t *crypt = mongocrypt_new();
2022
+ ASSERT_OK(mongocrypt_setopt_kms_providers(crypt, kms_providers), crypt);
2023
+ ASSERT_OK(_mongocrypt_init_for_test(crypt), crypt);
2024
+
2025
+ // Test decrypting without cached DEK.
2026
+ {
2027
+ mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
2028
+ ASSERT_OK(mongocrypt_ctx_explicit_decrypt_init(ctx, _mongocrypt_buffer_as_binary(&ciphertext)), ctx);
2029
+
2030
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_KEYS);
2031
+ ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, _mongocrypt_buffer_as_binary(&dek1)), ctx);
2032
+ ASSERT_OK(mongocrypt_ctx_mongo_done(ctx), ctx);
2033
+
2034
+ // Needs KMS to Get KEK.
2035
+ {
2036
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
2037
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
2038
+ ASSERT(kctx);
2039
+ const char *endpoint;
2040
+ ASSERT_OK(mongocrypt_kms_ctx_endpoint(kctx, &endpoint), kctx);
2041
+ ASSERT_STREQUAL(endpoint, "placeholder1-endpoint.com:5696");
2042
+ // Assert request is a Get.
2043
+ {
2044
+ mongocrypt_binary_t *request = mongocrypt_binary_new();
2045
+ ASSERT_OK(mongocrypt_kms_ctx_message(kctx, request), kctx);
2046
+ ASSERT_STREQUAL(kmip_get_operation_type(request), "Get");
2047
+ mongocrypt_binary_destroy(request);
2048
+ }
2049
+ // Feed response to Get.
2050
+ ASSERT_OK(kms_ctx_feed_all(kctx, KMIP_GET_RESPONSE, (uint32_t)(sizeof(KMIP_GET_RESPONSE))), kctx);
2051
+ kctx = mongocrypt_ctx_next_kms_ctx(ctx);
2052
+ ASSERT(!kctx);
2053
+ ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
2054
+ }
2055
+
2056
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_READY);
2057
+ mongocrypt_binary_t *bin = mongocrypt_binary_new();
2058
+ ASSERT_OK(mongocrypt_ctx_finalize(ctx, bin), ctx);
2059
+ ASSERT_MONGOCRYPT_BINARY_EQUAL_BSON(TEST_BSON(BSON_STR({"v" : "foo"})), bin);
2060
+ mongocrypt_binary_destroy(bin);
2061
+ mongocrypt_ctx_destroy(ctx);
2062
+ }
2063
+
2064
+ // Test decrypting with cached DEK.
2065
+ {
2066
+ mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
2067
+ ASSERT_OK(mongocrypt_ctx_explicit_decrypt_init(ctx, _mongocrypt_buffer_as_binary(&ciphertext)), ctx);
2068
+ // DEK is already cached. State transitions directly to ready.
2069
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_READY);
2070
+ mongocrypt_binary_t *bin = mongocrypt_binary_new();
2071
+ ASSERT_OK(mongocrypt_ctx_finalize(ctx, bin), ctx);
2072
+ ASSERT_MONGOCRYPT_BINARY_EQUAL_BSON(TEST_BSON(BSON_STR({"v" : "foo"})), bin);
2073
+ mongocrypt_binary_destroy(bin);
2074
+ mongocrypt_ctx_destroy(ctx);
2075
+ }
2076
+ mongocrypt_destroy(crypt);
2077
+ }
2078
+
2079
+ _mongocrypt_buffer_cleanup(&ciphertext);
2080
+ _mongocrypt_buffer_cleanup(&dek2);
2081
+ _mongocrypt_buffer_cleanup(&dek1);
2082
+ mongocrypt_binary_destroy(get_response);
2083
+ }
2084
+
2085
+ static void test_rewrap_with_named_kms_provider_local2local(_mongocrypt_tester_t *tester) {
2086
+ mongocrypt_binary_t *kms_providers =
2087
+ TEST_BSON(BSON_STR({"local:name1" : {"key" : "%s"}, "local:name2" : {"key" : "%s"}}),
2088
+ LOCAL_KEK1_BASE64,
2089
+ LOCAL_KEK2_BASE64);
2090
+
2091
+ // Create `dek1` from `local:name1`
2092
+ _mongocrypt_buffer_t dek1;
2093
+ create_dek(tester,
2094
+ (create_dek_args){.kms_providers = kms_providers,
2095
+ .key_alt_name = "local1",
2096
+ .kek = TEST_BSON(BSON_STR({"provider" : "local:name1"}))},
2097
+ &dek1);
2098
+
2099
+ // Rewrap `dek1` with `local:name2`.
2100
+ {
2101
+ mongocrypt_t *crypt = mongocrypt_new();
2102
+ ASSERT_OK(mongocrypt_setopt_kms_providers(crypt, kms_providers), crypt);
2103
+ ASSERT_OK(_mongocrypt_init_for_test(crypt), crypt);
2104
+
2105
+ mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
2106
+ ASSERT_OK(mongocrypt_ctx_setopt_key_encryption_key(ctx, TEST_BSON(BSON_STR({"provider" : "local:name2"}))),
2107
+ ctx);
2108
+ mongocrypt_binary_t *filter = TEST_BSON(BSON_STR({}));
2109
+ ASSERT_OK(mongocrypt_ctx_rewrap_many_datakey_init(ctx, filter), ctx);
2110
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_KEYS);
2111
+ ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, _mongocrypt_buffer_as_binary(&dek1)), ctx);
2112
+ ASSERT_OK(mongocrypt_ctx_mongo_done(ctx), ctx);
2113
+
2114
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_READY);
2115
+ mongocrypt_binary_t *bin = mongocrypt_binary_new();
2116
+ ASSERT_OK(mongocrypt_ctx_finalize(ctx, bin), ctx);
2117
+ // Check resulting document contains expected name.
2118
+ {
2119
+ bson_t bin_bson;
2120
+ ASSERT(_mongocrypt_binary_to_bson(bin, &bin_bson));
2121
+ char *pattern = BSON_STR({"v" : [ {"masterKey" : {"provider" : "local:name2"}} ]});
2122
+ _assert_match_bson(&bin_bson, TMP_BSON(pattern));
2123
+ }
2124
+ mongocrypt_binary_destroy(bin);
2125
+ mongocrypt_ctx_destroy(ctx);
2126
+ mongocrypt_destroy(crypt);
2127
+ }
2128
+
2129
+ _mongocrypt_buffer_cleanup(&dek1);
2130
+ }
2131
+
2132
+ static void test_rewrap_with_named_kms_provider_azure2azure(_mongocrypt_tester_t *tester) {
2133
+ mongocrypt_binary_t *kms_providers = TEST_BSON(BSON_STR({
2134
+ "azure:name1" : {
2135
+ "tenantId" : "placeholder1-tenantId",
2136
+ "clientId" : "placeholder1-clientId",
2137
+ "clientSecret" : "placeholder1-clientSecret",
2138
+ "identityPlatformEndpoint" : "placeholder1-identityPlatformEndpoint.com"
2139
+ },
2140
+ "azure:name2" : {
2141
+ "tenantId" : "placeholder2-tenantId",
2142
+ "clientId" : "placeholder2-clientId",
2143
+ "clientSecret" : "placeholder2-clientSecret",
2144
+ "identityPlatformEndpoint" : "placeholder2-identityPlatformEndpoint.com"
2145
+ }
2146
+ }));
2147
+
2148
+ // Create `dek1` from `azure:name1`
2149
+ _mongocrypt_buffer_t dek1;
2150
+ create_dek(tester,
2151
+ (create_dek_args){.kms_providers = kms_providers,
2152
+ .key_alt_name = "azure1",
2153
+ .kek = TEST_BSON(BSON_STR({
2154
+ "provider" : "azure:name1",
2155
+ "keyName" : "placeholder1-keyName",
2156
+ "keyVaultEndpoint" : "placeholder1-keyVaultEndpoint.com"
2157
+ })),
2158
+ .kms_response_1 = TEST_FILE("./test/data/kms-azure/oauth-response.txt"),
2159
+ .kms_response_2 = TEST_FILE("./test/data/kms-azure/encrypt-response.txt")},
2160
+ &dek1);
2161
+
2162
+ // Rewrap `dek1` with `azure:name2`.
2163
+ {
2164
+ mongocrypt_t *crypt = mongocrypt_new();
2165
+ ASSERT_OK(mongocrypt_setopt_kms_providers(crypt, kms_providers), crypt);
2166
+ ASSERT_OK(_mongocrypt_init_for_test(crypt), crypt);
2167
+
2168
+ mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
2169
+ ASSERT_OK(mongocrypt_ctx_setopt_key_encryption_key(ctx, TEST_BSON(BSON_STR({
2170
+ "provider" : "azure:name2",
2171
+ "keyName" : "placeholder2-keyName",
2172
+ "keyVaultEndpoint" : "placeholder2-keyVaultEndpoint.com"
2173
+ }))),
2174
+ ctx);
2175
+ mongocrypt_binary_t *filter = TEST_BSON(BSON_STR({}));
2176
+ ASSERT_OK(mongocrypt_ctx_rewrap_many_datakey_init(ctx, filter), ctx);
2177
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_KEYS);
2178
+ ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, _mongocrypt_buffer_as_binary(&dek1)), ctx);
2179
+ ASSERT_OK(mongocrypt_ctx_mongo_done(ctx), ctx);
2180
+
2181
+ // Needs KMS for oauth token from azure:name1.
2182
+ {
2183
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
2184
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
2185
+ ASSERT(kctx);
2186
+ const char *endpoint;
2187
+ ASSERT_OK(mongocrypt_kms_ctx_endpoint(kctx, &endpoint), kctx);
2188
+ ASSERT_STREQUAL(endpoint, "placeholder1-identityPlatformEndpoint.com:443");
2189
+ ASSERT_OK(mongocrypt_kms_ctx_feed(kctx, TEST_FILE("./test/data/kms-azure/oauth-response.txt")), kctx);
2190
+ kctx = mongocrypt_ctx_next_kms_ctx(ctx);
2191
+ ASSERT(!kctx);
2192
+ ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
2193
+ }
2194
+
2195
+ // Needs KMS to decrypt DEK from azure:name1.
2196
+ {
2197
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
2198
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
2199
+ ASSERT(kctx);
2200
+ const char *endpoint;
2201
+ ASSERT_OK(mongocrypt_kms_ctx_endpoint(kctx, &endpoint), kctx);
2202
+ ASSERT_STREQUAL(endpoint, "placeholder1-keyVaultEndpoint.com:443");
2203
+ ASSERT_OK(mongocrypt_kms_ctx_feed(kctx, TEST_FILE("./test/data/kms-azure/decrypt-response.txt")), kctx);
2204
+ kctx = mongocrypt_ctx_next_kms_ctx(ctx);
2205
+ ASSERT(!kctx);
2206
+ ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
2207
+ }
2208
+
2209
+ // Needs KMS for oauth token from azure:name2.
2210
+ {
2211
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
2212
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
2213
+ ASSERT(kctx);
2214
+ const char *endpoint;
2215
+ ASSERT_OK(mongocrypt_kms_ctx_endpoint(kctx, &endpoint), kctx);
2216
+ ASSERT_STREQUAL(endpoint, "placeholder2-identityPlatformEndpoint.com:443");
2217
+ ASSERT_OK(mongocrypt_kms_ctx_feed(kctx, TEST_FILE("./test/data/kms-azure/oauth-response.txt")), kctx);
2218
+ kctx = mongocrypt_ctx_next_kms_ctx(ctx);
2219
+ ASSERT(!kctx);
2220
+ ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
2221
+ }
2222
+
2223
+ // Needs KMS to encrypt DEK.
2224
+ {
2225
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
2226
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
2227
+ ASSERT(kctx);
2228
+ const char *endpoint;
2229
+ ASSERT_OK(mongocrypt_kms_ctx_endpoint(kctx, &endpoint), kctx);
2230
+ ASSERT_STREQUAL(endpoint, "placeholder2-keyVaultEndpoint.com:443");
2231
+ ASSERT_OK(mongocrypt_kms_ctx_feed(kctx, TEST_FILE("./test/data/kms-azure/encrypt-response.txt")), kctx);
2232
+ kctx = mongocrypt_ctx_next_kms_ctx(ctx);
2233
+ ASSERT(!kctx);
2234
+ ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
2235
+ }
2236
+
2237
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_READY);
2238
+ mongocrypt_binary_t *bin = mongocrypt_binary_new();
2239
+ ASSERT_OK(mongocrypt_ctx_finalize(ctx, bin), ctx);
2240
+ // Check resulting document contains expected name.
2241
+ {
2242
+ bson_t bin_bson;
2243
+ ASSERT(_mongocrypt_binary_to_bson(bin, &bin_bson));
2244
+ char *pattern = BSON_STR({"v" : [ {"masterKey" : {"provider" : "azure:name2"}} ]});
2245
+ _assert_match_bson(&bin_bson, TMP_BSON(pattern));
2246
+ }
2247
+ mongocrypt_binary_destroy(bin);
2248
+ mongocrypt_ctx_destroy(ctx);
2249
+ mongocrypt_destroy(crypt);
2250
+ }
2251
+
2252
+ _mongocrypt_buffer_cleanup(&dek1);
2253
+ }
2254
+
2255
+ static void test_rewrap_with_named_kms_provider_azure2local(_mongocrypt_tester_t *tester) {
2256
+ mongocrypt_binary_t *kms_providers =
2257
+ TEST_BSON(BSON_STR({
2258
+ "azure:name1" : {
2259
+ "tenantId" : "placeholder1-tenantId",
2260
+ "clientId" : "placeholder1-clientId",
2261
+ "clientSecret" : "placeholder1-clientSecret",
2262
+ "identityPlatformEndpoint" : "placeholder1-identityPlatformEndpoint.com"
2263
+ },
2264
+ "local:name1" : {"key" : "%s"}
2265
+ }),
2266
+ LOCAL_KEK1_BASE64);
2267
+
2268
+ // Create `dek1` from `azure:name1`
2269
+ _mongocrypt_buffer_t dek1;
2270
+ create_dek(tester,
2271
+ (create_dek_args){.kms_providers = kms_providers,
2272
+ .key_alt_name = "azure1",
2273
+ .kek = TEST_BSON(BSON_STR({
2274
+ "provider" : "azure:name1",
2275
+ "keyName" : "placeholder1-keyName",
2276
+ "keyVaultEndpoint" : "placeholder1-keyVaultEndpoint.com"
2277
+ })),
2278
+ .kms_response_1 = TEST_FILE("./test/data/kms-azure/oauth-response.txt"),
2279
+ .kms_response_2 = TEST_FILE("./test/data/kms-azure/encrypt-response.txt")},
2280
+ &dek1);
2281
+
2282
+ // Rewrap `dek1` with `local:name1`.
2283
+ {
2284
+ mongocrypt_t *crypt = mongocrypt_new();
2285
+ ASSERT_OK(mongocrypt_setopt_kms_providers(crypt, kms_providers), crypt);
2286
+ ASSERT_OK(_mongocrypt_init_for_test(crypt), crypt);
2287
+
2288
+ mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
2289
+ ASSERT_OK(mongocrypt_ctx_setopt_key_encryption_key(ctx, TEST_BSON(BSON_STR({"provider" : "local:name1"}))),
2290
+ ctx);
2291
+ mongocrypt_binary_t *filter = TEST_BSON(BSON_STR({}));
2292
+ ASSERT_OK(mongocrypt_ctx_rewrap_many_datakey_init(ctx, filter), ctx);
2293
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_MONGO_KEYS);
2294
+ ASSERT_OK(mongocrypt_ctx_mongo_feed(ctx, _mongocrypt_buffer_as_binary(&dek1)), ctx);
2295
+ ASSERT_OK(mongocrypt_ctx_mongo_done(ctx), ctx);
2296
+
2297
+ // Needs KMS for oauth token from azure:name1.
2298
+ {
2299
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
2300
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
2301
+ ASSERT(kctx);
2302
+ const char *endpoint;
2303
+ ASSERT_OK(mongocrypt_kms_ctx_endpoint(kctx, &endpoint), kctx);
2304
+ ASSERT_STREQUAL(endpoint, "placeholder1-identityPlatformEndpoint.com:443");
2305
+ ASSERT_OK(mongocrypt_kms_ctx_feed(kctx, TEST_FILE("./test/data/kms-azure/oauth-response.txt")), kctx);
2306
+ kctx = mongocrypt_ctx_next_kms_ctx(ctx);
2307
+ ASSERT(!kctx);
2308
+ ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
2309
+ }
2310
+
2311
+ // Needs KMS to decrypt DEK from azure:name1.
2312
+ {
2313
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
2314
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
2315
+ ASSERT(kctx);
2316
+ const char *endpoint;
2317
+ ASSERT_OK(mongocrypt_kms_ctx_endpoint(kctx, &endpoint), kctx);
2318
+ ASSERT_STREQUAL(endpoint, "placeholder1-keyVaultEndpoint.com:443");
2319
+ ASSERT_OK(mongocrypt_kms_ctx_feed(kctx, TEST_FILE("./test/data/kms-azure/decrypt-response.txt")), kctx);
2320
+ kctx = mongocrypt_ctx_next_kms_ctx(ctx);
2321
+ ASSERT(!kctx);
2322
+ ASSERT_OK(mongocrypt_ctx_kms_done(ctx), ctx);
2323
+ }
2324
+
2325
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_READY);
2326
+ mongocrypt_binary_t *bin = mongocrypt_binary_new();
2327
+ ASSERT_OK(mongocrypt_ctx_finalize(ctx, bin), ctx);
2328
+ // Check resulting document contains expected name.
2329
+ {
2330
+ bson_t bin_bson;
2331
+ ASSERT(_mongocrypt_binary_to_bson(bin, &bin_bson));
2332
+ char *pattern = BSON_STR({"v" : [ {"masterKey" : {"provider" : "local:name1"}} ]});
2333
+ _assert_match_bson(&bin_bson, TMP_BSON(pattern));
2334
+ }
2335
+ mongocrypt_binary_destroy(bin);
2336
+ mongocrypt_ctx_destroy(ctx);
2337
+ mongocrypt_destroy(crypt);
2338
+ }
2339
+
2340
+ _mongocrypt_buffer_cleanup(&dek1);
2341
+ }
2342
+
2343
+ static void test_mongocrypt_kms_ctx_get_kms_provider(_mongocrypt_tester_t *tester) {
2344
+ mongocrypt_binary_t *kms_providers =
2345
+ TEST_BSON(BSON_STR({"kmip:name1" : {"endpoint" : "placeholder1-endpoint.com"}}));
2346
+
2347
+ mongocrypt_t *crypt = mongocrypt_new();
2348
+ ASSERT_OK(mongocrypt_setopt_kms_providers(crypt, kms_providers), crypt);
2349
+ ASSERT_OK(_mongocrypt_init_for_test(crypt), crypt);
2350
+
2351
+ mongocrypt_ctx_t *ctx = mongocrypt_ctx_new(crypt);
2352
+ ASSERT_OK(
2353
+ mongocrypt_ctx_setopt_key_encryption_key(ctx, TEST_BSON(BSON_STR({"provider" : "kmip:name1", "keyId" : "12"}))),
2354
+ ctx);
2355
+ ASSERT_OK(mongocrypt_ctx_setopt_key_alt_name(ctx, TEST_BSON(BSON_STR({"keyAltName" : "kmip1"}))), ctx);
2356
+ ASSERT_OK(mongocrypt_ctx_datakey_init(ctx), ctx);
2357
+
2358
+ // Needs KMS to Get KEK.
2359
+ {
2360
+ ASSERT_STATE_EQUAL(mongocrypt_ctx_state(ctx), MONGOCRYPT_CTX_NEED_KMS);
2361
+ mongocrypt_kms_ctx_t *kctx = mongocrypt_ctx_next_kms_ctx(ctx);
2362
+ ASSERT(kctx);
2363
+ ASSERT_STREQUAL(mongocrypt_kms_ctx_get_kms_provider(kctx, NULL /* len */), "kmip:name1");
2364
+ }
2365
+
2366
+ mongocrypt_ctx_destroy(ctx);
2367
+ mongocrypt_destroy(crypt);
2368
+ }
2369
+
2370
+ void _mongocrypt_tester_install_named_kms_providers(_mongocrypt_tester_t *tester) {
2371
+ INSTALL_TEST(test_configuring_named_kms_providers);
2372
+ INSTALL_TEST(test_create_datakey_with_named_kms_provider);
2373
+ INSTALL_TEST(test_explicit_with_named_kms_provider_for_azure);
2374
+ INSTALL_TEST(test_explicit_with_named_kms_provider_for_gcp);
2375
+ INSTALL_TEST(test_explicit_with_named_kms_provider_for_aws);
2376
+ INSTALL_TEST(test_explicit_with_named_kms_provider_for_kmip);
2377
+ INSTALL_TEST(test_rewrap_with_named_kms_provider_local2local);
2378
+ INSTALL_TEST(test_rewrap_with_named_kms_provider_azure2azure);
2379
+ INSTALL_TEST(test_rewrap_with_named_kms_provider_azure2local);
2380
+ INSTALL_TEST(test_mongocrypt_kms_ctx_get_kms_provider);
2381
+ }