diff --git a/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/CAPI.java b/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/CAPI.java index f68433577..349012e6d 100644 --- a/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/CAPI.java +++ b/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/CAPI.java @@ -556,6 +556,27 @@ public interface mongocrypt_random_fn extends Callback { public static native boolean mongocrypt_ctx_setopt_query_type (mongocrypt_ctx_t ctx, cstring query_type, int len); + /** + * Set options for explicit encryption with the "rangePreview" algorithm. + * NOTE: The RangePreview algorithm is experimental only. It is not intended for + * public use. + * + * opts is a BSON document of the form: + * { + * "min": Optional, + * "max": Optional, + * "sparsity": Int64, + * "precision": Optional + * } + * + * @param ctx The @ref mongocrypt_ctx_t object. + * @param opts BSON. + * @return A boolean indicating success. If false, an error status is set. + * @since 1.7 + */ + public static native boolean + mongocrypt_ctx_setopt_algorithm_range (mongocrypt_ctx_t ctx, mongocrypt_binary_t opts); + /** * Initialize new @ref mongocrypt_t object. * @@ -825,6 +846,52 @@ public interface mongocrypt_random_fn extends Callback { mongocrypt_ctx_explicit_encrypt_init (mongocrypt_ctx_t ctx, mongocrypt_binary_t msg); + /** + * Explicit helper method to encrypt a Match Expression or Aggregate Expression. + * Contexts created for explicit encryption will not go through mongocryptd. + * Requires query_type to be "rangePreview". + * NOTE: The RangePreview algorithm is experimental only. It is not intended for + * public use. + * + * This method expects the passed-in BSON to be of the form: + * { "v" : FLE2RangeFindDriverSpec } + * + * FLE2RangeFindDriverSpec is a BSON document with one of these forms: + * + * 1. A Match Expression of this form: + * {$and: [{: {: , {: {: }}]} + * 2. An Aggregate Expression of this form: + * {$and: [{: [, ]}, {: [, ]}] + * + * may be $lt, $lte, $gt, or $gte. + * + * The value of "v" is expected to be the BSON value passed to a driver + * ClientEncryption.encryptExpression helper. + * + * Associated options for FLE 1: + * - @ref mongocrypt_ctx_setopt_key_id + * - @ref mongocrypt_ctx_setopt_key_alt_name + * - @ref mongocrypt_ctx_setopt_algorithm + * + * Associated options for Queryable Encryption: + * - @ref mongocrypt_ctx_setopt_key_id + * - @ref mongocrypt_ctx_setopt_index_key_id + * - @ref mongocrypt_ctx_setopt_contention_factor + * - @ref mongocrypt_ctx_setopt_query_type + * - @ref mongocrypt_ctx_setopt_algorithm_range + * + * An error is returned if FLE 1 and Queryable Encryption incompatible options + * are set. + * + * @param ctx A @ref mongocrypt_ctx_t. + * @param msg A @ref mongocrypt_binary_t the plaintext BSON value. + * @return A boolean indicating success. + * @since 1.7 + */ + public static native boolean + mongocrypt_ctx_explicit_encrypt_expression_init (mongocrypt_ctx_t ctx, + mongocrypt_binary_t msg); + /** * Initialize a context for decryption. * diff --git a/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/MongoCrypt.java b/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/MongoCrypt.java index a8ae093de..5022f2fb6 100644 --- a/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/MongoCrypt.java +++ b/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/MongoCrypt.java @@ -18,7 +18,6 @@ package com.mongodb.crypt.capi; -import org.bson.BsonBinary; import org.bson.BsonDocument; import java.io.Closeable; @@ -62,6 +61,16 @@ public interface MongoCrypt extends Closeable { */ MongoCryptContext createExplicitEncryptionContext(BsonDocument document, MongoExplicitEncryptOptions options); + /** + * Create a context to use for encryption + * + * @param document the document to encrypt, which must be in the form { "v" : BSON value to encrypt } + * @param options the expression encryption options + * @return the context + * @since 1.7 + */ + MongoCryptContext createEncryptExpressionContext(BsonDocument document, MongoExplicitEncryptOptions options); + /** * Create a context to use for encryption * diff --git a/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/MongoCryptImpl.java b/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/MongoCryptImpl.java index 459f1f9ec..7cf6f0d0e 100644 --- a/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/MongoCryptImpl.java +++ b/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/MongoCryptImpl.java @@ -43,10 +43,12 @@ import static com.mongodb.crypt.capi.CAPI.mongocrypt_ctx_decrypt_init; import static com.mongodb.crypt.capi.CAPI.mongocrypt_ctx_encrypt_init; import static com.mongodb.crypt.capi.CAPI.mongocrypt_ctx_explicit_decrypt_init; +import static com.mongodb.crypt.capi.CAPI.mongocrypt_ctx_explicit_encrypt_expression_init; import static com.mongodb.crypt.capi.CAPI.mongocrypt_ctx_explicit_encrypt_init; import static com.mongodb.crypt.capi.CAPI.mongocrypt_ctx_new; import static com.mongodb.crypt.capi.CAPI.mongocrypt_ctx_rewrap_many_datakey_init; import static com.mongodb.crypt.capi.CAPI.mongocrypt_ctx_setopt_algorithm; +import static com.mongodb.crypt.capi.CAPI.mongocrypt_ctx_setopt_algorithm_range; import static com.mongodb.crypt.capi.CAPI.mongocrypt_ctx_setopt_contention_factor; import static com.mongodb.crypt.capi.CAPI.mongocrypt_ctx_setopt_key_alt_name; import static com.mongodb.crypt.capi.CAPI.mongocrypt_ctx_setopt_key_encryption_key; @@ -258,33 +260,23 @@ public MongoCryptContext createDataKeyContext(final String kmsProvider, final Mo @Override public MongoCryptContext createExplicitEncryptionContext(final BsonDocument document, final MongoExplicitEncryptOptions options) { isTrue("open", !closed.get()); - mongocrypt_ctx_t context = mongocrypt_ctx_new(wrapped); - if (context == null) { - throwExceptionFromStatus(); - } + mongocrypt_ctx_t context = configureExplicitEncryption(options); - if (options.getKeyId() != null) { - try (BinaryHolder keyIdBinaryHolder = toBinary(ByteBuffer.wrap(options.getKeyId().getData()))) { - configure(() -> mongocrypt_ctx_setopt_key_id(context, keyIdBinaryHolder.getBinary()), context); - } - } else if (options.getKeyAltName() != null) { - try (BinaryHolder keyAltNameBinaryHolder = toBinary(new BsonDocument("keyAltName", new BsonString(options.getKeyAltName())))) { - configure(() -> mongocrypt_ctx_setopt_key_alt_name(context, keyAltNameBinaryHolder.getBinary()), context); - } + try (BinaryHolder documentBinaryHolder = toBinary(document)) { + configure(() -> mongocrypt_ctx_explicit_encrypt_init(context, documentBinaryHolder.getBinary()), context); } - configure(() -> mongocrypt_ctx_setopt_algorithm(context, new cstring(options.getAlgorithm()), -1), context); - if (options.getQueryType() != null) { - configure(() -> mongocrypt_ctx_setopt_query_type(context, new cstring(options.getQueryType()), -1), context); - } - if (options.getContentionFactor() != null) { - configure(() -> mongocrypt_ctx_setopt_contention_factor(context, options.getContentionFactor()), context); - } + return new MongoCryptContextImpl(context); + } + + @Override + public MongoCryptContext createEncryptExpressionContext(final BsonDocument document, final MongoExplicitEncryptOptions options) { + isTrue("open", !closed.get()); + mongocrypt_ctx_t context = configureExplicitEncryption(options); try (BinaryHolder documentBinaryHolder = toBinary(document)) { - configure(() -> mongocrypt_ctx_explicit_encrypt_init(context, documentBinaryHolder.getBinary()), context); + configure(() -> mongocrypt_ctx_explicit_encrypt_expression_init(context, documentBinaryHolder.getBinary()), context); } - return new MongoCryptContextImpl(context); } @@ -339,6 +331,40 @@ public void close() { } } + private mongocrypt_ctx_t configureExplicitEncryption(final MongoExplicitEncryptOptions options) { + mongocrypt_ctx_t context = mongocrypt_ctx_new(wrapped); + if (context == null) { + throwExceptionFromStatus(); + } + + if (options.getKeyId() != null) { + try (BinaryHolder keyIdBinaryHolder = toBinary(ByteBuffer.wrap(options.getKeyId().getData()))) { + configure(() -> mongocrypt_ctx_setopt_key_id(context, keyIdBinaryHolder.getBinary()), context); + } + } else if (options.getKeyAltName() != null) { + try (BinaryHolder keyAltNameBinaryHolder = toBinary(new BsonDocument("keyAltName", new BsonString(options.getKeyAltName())))) { + configure(() -> mongocrypt_ctx_setopt_key_alt_name(context, keyAltNameBinaryHolder.getBinary()), context); + } + } + + if (options.getAlgorithm() != null) { + configure(() -> mongocrypt_ctx_setopt_algorithm(context, new cstring(options.getAlgorithm()), -1), context); + } + if (options.getQueryType() != null) { + configure(() -> mongocrypt_ctx_setopt_query_type(context, new cstring(options.getQueryType()), -1), context); + } + if (options.getContentionFactor() != null) { + configure(() -> mongocrypt_ctx_setopt_contention_factor(context, options.getContentionFactor()), context); + } + if (options.getRangeOptions() != null) { + try (BinaryHolder rangeOptionsHolder = toBinary(options.getRangeOptions())) { + configure(() -> mongocrypt_ctx_setopt_algorithm_range(context, rangeOptionsHolder.getBinary()), context); + } + } + return context; + } + + private void configure(final Supplier successSupplier) { if (!successSupplier.get()) { throwExceptionFromStatus(); diff --git a/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/MongoExplicitEncryptOptions.java b/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/MongoExplicitEncryptOptions.java index eba1ea55d..7dbe236c4 100644 --- a/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/MongoExplicitEncryptOptions.java +++ b/bindings/java/mongocrypt/src/main/java/com/mongodb/crypt/capi/MongoExplicitEncryptOptions.java @@ -18,6 +18,7 @@ package com.mongodb.crypt.capi; import org.bson.BsonBinary; +import org.bson.BsonDocument; import java.util.Objects; @@ -30,6 +31,7 @@ public class MongoExplicitEncryptOptions { private final String algorithm; private final Long contentionFactor; private final String queryType; + private final BsonDocument rangeOptions; /** * The builder for the options @@ -40,6 +42,7 @@ public static class Builder { private String algorithm; private Long contentionFactor; private String queryType; + private BsonDocument rangeOptions; private Builder() { } @@ -108,6 +111,20 @@ public Builder queryType(final String queryType) { return this; } + /** + * The Range Options. + * + *

It is an error to set rangeOptions when the algorithm is not "rangePreview".

+ * + * @param rangeOptions the range options + * @return this + * @since 1.7 + */ + public Builder rangeOptions(final BsonDocument rangeOptions) { + this.rangeOptions = rangeOptions; + return this; + } + /** * Build the options. * @@ -169,17 +186,27 @@ public String getQueryType() { return queryType; } + /** + * Gets the range options + * @return the range options + * @since 1.7 + */ + public BsonDocument getRangeOptions() { + return rangeOptions; + } + private MongoExplicitEncryptOptions(Builder builder) { this.keyId = builder.keyId; this.keyAltName = builder.keyAltName; this.algorithm = builder.algorithm; this.contentionFactor = builder.contentionFactor; this.queryType = builder.queryType; - if (!Objects.equals(algorithm, "Indexed")) { + this.rangeOptions = builder.rangeOptions; + if (!(Objects.equals(algorithm, "Indexed") || Objects.equals(algorithm, "RangePreview"))) { if (contentionFactor != null) { - throw new IllegalStateException("Invalid configuration, contentionFactor can only be set if algorithm is 'Indexed'"); + throw new IllegalStateException("Invalid configuration, contentionFactor can only be set if algorithm is 'Indexed' or 'RangePreview'"); } else if (queryType != null) { - throw new IllegalStateException("Invalid configuration, queryType can only be set if algorithm is 'Indexed'"); + throw new IllegalStateException("Invalid configuration, queryType can only be set if algorithm is 'Indexed' or 'RangePreview'"); } } } @@ -191,7 +218,8 @@ public String toString() { ", keyAltName='" + keyAltName + '\'' + ", algorithm='" + algorithm + '\'' + ", contentionFactor=" + contentionFactor + - ", queryType=" + queryType + + ", queryType='" + queryType + '\'' + + ", rangeOptions=" + rangeOptions + '}'; } } diff --git a/bindings/java/mongocrypt/src/test/java/com/mongodb/crypt/capi/MongoCryptTest.java b/bindings/java/mongocrypt/src/test/java/com/mongodb/crypt/capi/MongoCryptTest.java index b7868acdc..9ac136b7a 100644 --- a/bindings/java/mongocrypt/src/test/java/com/mongodb/crypt/capi/MongoCryptTest.java +++ b/bindings/java/mongocrypt/src/test/java/com/mongodb/crypt/capi/MongoCryptTest.java @@ -23,9 +23,6 @@ import org.bson.BsonDocument; import org.bson.BsonString; import org.bson.RawBsonDocument; -import org.bson.codecs.BsonDocumentCodec; -import org.bson.codecs.DecoderContext; -import org.bson.json.JsonReader; import org.junit.jupiter.api.Test; import java.io.BufferedReader; @@ -167,7 +164,7 @@ public void testDataKeyCreation() { } @Test - public void testExplicitEncryptionDecryption() throws IOException, URISyntaxException { + public void testExplicitEncryptionDecryption() { MongoCrypt mongoCrypt = createMongoCrypt(); assertNotNull(mongoCrypt); @@ -200,6 +197,37 @@ public void testExplicitEncryptionDecryption() throws IOException, URISyntaxExce mongoCrypt.close(); } + @Test + public void testExplicitExpressionEncryption() { + MongoCrypt mongoCrypt = createMongoCrypt(); + assertNotNull(mongoCrypt); + + BsonDocument valueToEncrypt = getResourceAsDocument("fle2-find-range-explicit/int32/value-to-encrypt.json"); + BsonDocument rangeOptions = getResourceAsDocument("fle2-find-range-explicit/int32/rangeopts.json"); + BsonDocument expectedEncryptedPayload = getResourceAsDocument("fle2-find-range-explicit/int32/encrypted-payload.json"); + + MongoExplicitEncryptOptions options = MongoExplicitEncryptOptions.builder() + .keyId(new BsonBinary(BsonBinarySubType.UUID_STANDARD, Base64.getDecoder().decode("q83vqxI0mHYSNBI0VniQEg=="))) + .algorithm("RangePreview") + .queryType("rangePreview") + .contentionFactor(4L) + .rangeOptions(rangeOptions) + .build(); + MongoCryptContext encryptor = mongoCrypt.createEncryptExpressionContext(valueToEncrypt, options); + assertEquals(State.NEED_MONGO_KEYS, encryptor.getState()); + + testKeyDecryptor(encryptor, "fle2-find-range-explicit/int32/key-filter.json", "keys/ABCDEFAB123498761234123456789012-local-document.json"); + + assertEquals(State.READY, encryptor.getState()); + + RawBsonDocument actualEncryptedPayload = encryptor.finish(); + assertEquals(State.DONE, encryptor.getState()); + assertEquals(expectedEncryptedPayload, actualEncryptedPayload); + + encryptor.close(); + mongoCrypt.close(); + } + @Test public void testExplicitEncryptionDecryptionKeyAltName() throws IOException, URISyntaxException { MongoCrypt mongoCrypt = createMongoCrypt(); @@ -213,7 +241,7 @@ public void testExplicitEncryptionDecryptionKeyAltName() throws IOException, URI MongoCryptContext encryptor = mongoCrypt.createExplicitEncryptionContext(documentToEncrypt, options); assertEquals(State.NEED_MONGO_KEYS, encryptor.getState()); - testKeyDecryptor(encryptor, true); + testKeyDecryptor(encryptor, "key-filter-keyAltName.json", "key-document.json"); assertEquals(State.READY, encryptor.getState()); @@ -234,16 +262,19 @@ public void testExplicitEncryptionDecryptionKeyAltName() throws IOException, URI mongoCrypt.close(); } - private void testKeyDecryptor(final MongoCryptContext context) throws URISyntaxException, IOException { - testKeyDecryptor(context, false); + private void testKeyDecryptor(final MongoCryptContext context) { + testKeyDecryptor(context, "key-filter.json", "key-document.json"); } - private void testKeyDecryptor(final MongoCryptContext context, final boolean keyAltName) throws URISyntaxException, IOException { + private void testKeyDecryptor(final MongoCryptContext context, final String keyFilterPath, final String keyDocumentPath) { BsonDocument keyFilter = context.getMongoOperation(); - String keyFilterJson = keyAltName ? "key-filter-keyAltName.json" : "key-filter.json"; - assertEquals(getResourceAsDocument(keyFilterJson), keyFilter); - context.addMongoOperationResult(getResourceAsDocument("key-document.json")); + assertEquals(getResourceAsDocument(keyFilterPath), keyFilter); + context.addMongoOperationResult(getResourceAsDocument(keyDocumentPath)); context.completeMongoOperation(); + if (context.getState() == State.READY) { + return; + } + assertEquals(State.NEED_KMS, context.getState()); MongoKeyDecryptor keyDecryptor = context.nextKeyDecryptor(); @@ -278,38 +309,37 @@ private MongoCrypt createMongoCrypt() { .build()); } - private static BsonDocument getResourceAsDocument(final String fileName) throws URISyntaxException, IOException { - URL resource = MongoCryptTest.class.getResource("/" + fileName); - if (resource == null) { - throw new RuntimeException("Could not find file " + fileName); - } - File resourceFile = new File(resource.toURI()); - return new BsonDocumentCodec().decode(new JsonReader(getFileAsString(resourceFile, System.getProperty("line.separator"))), - DecoderContext.builder().build()); + private static BsonDocument getResourceAsDocument(final String fileName) { + return BsonDocument.parse(getFileAsString(fileName, System.getProperty("line.separator"))); } - private static ByteBuffer getHttpResourceAsByteBuffer(final String fileName) throws URISyntaxException, IOException { - URL resource = MongoCryptTest.class.getResource("/" + fileName); - if (resource == null) { - throw new RuntimeException("Could not find file " + fileName); - } - File resourceFile = new File(resource.toURI()); - return ByteBuffer.wrap(getFileAsString(resourceFile, "\r\n").getBytes(StandardCharsets.UTF_8)); + private static ByteBuffer getHttpResourceAsByteBuffer(final String fileName) { + return ByteBuffer.wrap(getFileAsString(fileName, "\r\n").getBytes(StandardCharsets.UTF_8)); } - private static String getFileAsString(final File file, String lineSeparator) throws IOException { - StringBuilder stringBuilder = new StringBuilder(); - String line; - try (BufferedReader reader = new BufferedReader(new InputStreamReader(Files.newInputStream(file.toPath()), StandardCharsets.UTF_8))) { - boolean first = true; - while ((line = reader.readLine()) != null) { - if (!first) { - stringBuilder.append(lineSeparator); + private static String getFileAsString(final String fileName, String lineSeparator) { + try { + URL resource = MongoCryptTest.class.getResource("/" + fileName); + if (resource == null) { + throw new RuntimeException("Could not find file " + fileName); + } + File file = new File(resource.toURI()); + StringBuilder stringBuilder = new StringBuilder(); + String line; + try (BufferedReader reader = new BufferedReader( + new InputStreamReader(Files.newInputStream(file.toPath()), StandardCharsets.UTF_8))) { + boolean first = true; + while ((line = reader.readLine()) != null) { + if (!first) { + stringBuilder.append(lineSeparator); + } + first = false; + stringBuilder.append(line); } - first = false; - stringBuilder.append(line); } + return stringBuilder.toString(); + } catch (Throwable t) { + throw new RuntimeException("Could not parse file " + fileName, t); } - return stringBuilder.toString(); } } diff --git a/bindings/java/mongocrypt/src/test/resources/fle2-find-range-explicit/int32/encrypted-payload.json b/bindings/java/mongocrypt/src/test/resources/fle2-find-range-explicit/int32/encrypted-payload.json new file mode 100644 index 000000000..1541413d1 --- /dev/null +++ b/bindings/java/mongocrypt/src/test/resources/fle2-find-range-explicit/int32/encrypted-payload.json @@ -0,0 +1,26 @@ +{ + "v": { + "$and": [ + { + "age": { + "$gte": { + "$binary": { + "base64": "CgUCAAADcGF5bG9hZADBAQAABGcAhQEAAAMwAH0AAAAFZAAgAAAAAInd0noBhIiJMv8QTjcfgRqnnVhxRJRRACLfvgT+CTR/BXMAIAAAAADm0EjqF/T4EmR6Dw6NaPLrL0OuzS4AFvm90czFluAAygVjACAAAAAA0d8XgDtErXhD2Il47RZ6es9tJjjenynp6roL00NDzzwAAzEAfQAAAAVkACAAAAAA7lkNtT6RLw91aJ07K/blwlFs5wi9pQjqUXDcaCTxe98FcwAgAAAAAPwySffuLQihmF70Ot93KtaUMNU8KpmA+niyPRcvarNMBWMAIAAAAADH7BDBCS/7LwB7NYkxPNDb5QXXROFnh2+7z8JFwX7wnQADMgB9AAAABWQAIAAAAACcMWVTbZC4ox5VdjWeYKLgf4oBjpPlbTTAkucm9JPK0wVzACAAAAAA3tIww4ZTytkxFsUKyJbc3zwQ2w7DhkOqaNvX9g8pi3gFYwAgAAAAAOK5ETACEX4i+2e0dDtUeGozbxKNlqmkRK5IEZCrv7M5AAAFZQAgAAAAAL7iv5ju6p02+CadotQZUkgqtSIYD2HaywGsizUpIBYMEmNtAAQAAAAAAAAAABBwYXlsb2FkSWQAAAAAABBmaXJzdE9wZXJhdG9yAAIAAAAQc2Vjb25kT3BlcmF0b3IABAAAAAA=", + "subType": "6" + } + } + } + }, + { + "age": { + "$lte": { + "$binary": { + "base64": "CjsAAAAQcGF5bG9hZElkAAAAAAAQZmlyc3RPcGVyYXRvcgACAAAAEHNlY29uZE9wZXJhdG9yAAQAAAAA", + "subType": "6" + } + } + } + } + ] + } +} diff --git a/bindings/java/mongocrypt/src/test/resources/fle2-find-range-explicit/int32/key-document.json b/bindings/java/mongocrypt/src/test/resources/fle2-find-range-explicit/int32/key-document.json new file mode 100644 index 000000000..e69de29bb diff --git a/bindings/java/mongocrypt/src/test/resources/fle2-find-range-explicit/int32/key-filter.json b/bindings/java/mongocrypt/src/test/resources/fle2-find-range-explicit/int32/key-filter.json new file mode 100644 index 000000000..897364761 --- /dev/null +++ b/bindings/java/mongocrypt/src/test/resources/fle2-find-range-explicit/int32/key-filter.json @@ -0,0 +1,19 @@ +{ + "$or": [ + { + "_id": { + "$in": [ + { + "$binary": "q83vqxI0mHYSNBI0VniQEg==", + "$type": "04" + } + ] + } + }, + { + "keyAltNames": { + "$in": [] + } + } + ] +} \ No newline at end of file diff --git a/bindings/java/mongocrypt/src/test/resources/fle2-find-range-explicit/int32/rangeopts.json b/bindings/java/mongocrypt/src/test/resources/fle2-find-range-explicit/int32/rangeopts.json new file mode 100644 index 000000000..5ef3da478 --- /dev/null +++ b/bindings/java/mongocrypt/src/test/resources/fle2-find-range-explicit/int32/rangeopts.json @@ -0,0 +1,11 @@ +{ + "min": { + "$numberInt": "0" + }, + "max": { + "$numberInt": "200" + }, + "sparsity": { + "$numberLong": "1" + } +} diff --git a/bindings/java/mongocrypt/src/test/resources/fle2-find-range-explicit/int32/value-to-encrypt.json b/bindings/java/mongocrypt/src/test/resources/fle2-find-range-explicit/int32/value-to-encrypt.json new file mode 100644 index 000000000..4c294e887 --- /dev/null +++ b/bindings/java/mongocrypt/src/test/resources/fle2-find-range-explicit/int32/value-to-encrypt.json @@ -0,0 +1,20 @@ +{ + "v": { + "$and": [ + { + "age": { + "$gte": { + "$numberInt": "23" + } + } + }, + { + "age": { + "$lte": { + "$numberInt": "35" + } + } + } + ] + } +} diff --git a/bindings/java/mongocrypt/src/test/resources/keys/ABCDEFAB123498761234123456789012-local-document.json b/bindings/java/mongocrypt/src/test/resources/keys/ABCDEFAB123498761234123456789012-local-document.json new file mode 100644 index 000000000..e5d1a3f76 --- /dev/null +++ b/bindings/java/mongocrypt/src/test/resources/keys/ABCDEFAB123498761234123456789012-local-document.json @@ -0,0 +1,30 @@ +{ + "_id": { + "$binary": { + "base64": "q83vqxI0mHYSNBI0VniQEg==", + "subType": "04" + } + }, + "keyMaterial": { + "$binary": { + "base64": "27OBvUqHAuYFy60nwCdvq2xmZ4kFzVySphXzBGq+HEot13comCoydEfnltBzLTuXLbV9cnREFJIO5f0jMqrlkxIuvAV8yO84p5VJTEa8j/xSNe7iA594rx7UeKT0fOt4VqM47fht8h+8PZYc5JVezvEMvwk115IBCwENxDjLtT0g+y8Hf+aTUEGtxrYToH8zf1/Y7S16mHiIc4jK3/vxHw==", + "subType": "00" + } + }, + "creationDate": { + "$date": { + "$numberLong": "1648915408923" + } + }, + "updateDate": { + "$date": { + "$numberLong": "1648915408923" + } + }, + "status": { + "$numberInt": "0" + }, + "masterKey": { + "provider": "local" + } +}