From c40e90180fa1259aa368a2c52b4f0dc55d594eb7 Mon Sep 17 00:00:00 2001 From: Bailey Pearson Date: Wed, 31 Jul 2024 08:08:37 -0600 Subject: [PATCH 1/3] make expression mode requried --- addon/mongocrypt.cc | 29 ++++++++++++++++++++--------- addon/mongocrypt.h | 5 +++++ package.json | 1 + test/bindings.test.ts | 14 ++++++++++++++ 4 files changed, 40 insertions(+), 9 deletions(-) diff --git a/addon/mongocrypt.cc b/addon/mongocrypt.cc index 421bb93..9ea3c41 100644 --- a/addon/mongocrypt.cc +++ b/addon/mongocrypt.cc @@ -589,13 +589,29 @@ Value MongoCrypt::MakeEncryptionContext(const CallbackInfo& info) { } Value MongoCrypt::MakeExplicitEncryptionContext(const CallbackInfo& info) { - std::unique_ptr context( - mongocrypt_ctx_new(_mongo_crypt.get())); - Uint8Array valueBuffer = Uint8ArrayFromValue(info[0], "value"); Object options = info.Length() > 1 ? info[1].ToObject() : Object::New(info.Env()); + if (!options.Get("expressionMode").IsBoolean()) { + throw TypeError::New(Env(), "option `expressionMode` is required."); + } + + bool expression_mode = options.Get("expressionMode").ToBoolean(); + ExplicitEncryptionContextInitFunction context_init_function = + expression_mode ? mongocrypt_ctx_explicit_encrypt_expression_init + : mongocrypt_ctx_explicit_encrypt_init; + + return MakeExplicitEncryptionContextInternal(context_init_function, valueBuffer, options); +} + +Value MongoCrypt::MakeExplicitEncryptionContextInternal( + ExplicitEncryptionContextInitFunction context_init_function, + const Uint8Array& valueBuffer, + const Object& options) { + std::unique_ptr context( + mongocrypt_ctx_new(_mongo_crypt.get())); + if (!options.Get("keyId").IsUndefined()) { Uint8Array keyId = Uint8ArrayFromValue(options["keyId"], "keyId"); @@ -658,12 +674,7 @@ Value MongoCrypt::MakeExplicitEncryptionContext(const CallbackInfo& info) { std::unique_ptr binaryValue( Uint8ArrayToBinary(valueBuffer)); - const bool isExpressionMode = options.Get("expressionMode").ToBoolean(); - - const bool status = - isExpressionMode - ? mongocrypt_ctx_explicit_encrypt_expression_init(context.get(), binaryValue.get()) - : mongocrypt_ctx_explicit_encrypt_init(context.get(), binaryValue.get()); + const bool status = context_init_function(context.get(), binaryValue.get()); if (!status) { throw TypeError::New(Env(), errorStringFromStatus(context.get())); diff --git a/addon/mongocrypt.h b/addon/mongocrypt.h index 61d6950..fb3d73d 100644 --- a/addon/mongocrypt.h +++ b/addon/mongocrypt.h @@ -56,6 +56,8 @@ namespace opensslcrypto { std::unique_ptr createOpenSSLCryptoHooks(); } +typedef bool (*ExplicitEncryptionContextInitFunction)(mongocrypt_ctx_t*, mongocrypt_binary_t*); + class MongoCrypt : public Napi::ObjectWrap { public: static Napi::Function Init(Napi::Env env); @@ -67,6 +69,9 @@ class MongoCrypt : public Napi::ObjectWrap { Napi::Value MakeExplicitDecryptionContext(const Napi::CallbackInfo& info); Napi::Value MakeDataKeyContext(const Napi::CallbackInfo& info); Napi::Value MakeRewrapManyDataKeyContext(const Napi::CallbackInfo& info); + Napi::Value MakeExplicitEncryptionContextInternal(ExplicitEncryptionContextInitFunction init_fn, + const Napi::Uint8Array& value, + const Napi::Object& options); Napi::Value Status(const Napi::CallbackInfo& info); Napi::Value CryptSharedLibVersionInfo(const Napi::CallbackInfo& info); diff --git a/package.json b/package.json index 93a8f34..2e84a4a 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "check:clang-format": "clang-format --style=file:.clang-format --dry-run --Werror addon/*", "test": "mocha test", "prepare": "tsc", + "rebuild": "node-gyp rebuild", "prebuild": "prebuild --runtime napi --strip --verbose --all" }, "author": { diff --git a/test/bindings.test.ts b/test/bindings.test.ts index 186bc01..53e2803 100644 --- a/test/bindings.test.ts +++ b/test/bindings.test.ts @@ -387,6 +387,20 @@ describe('MongoCryptConstructor', () => { ).to.be.instanceOf(MongoCryptContextCtor); }); }); + + describe('options.expressionMode', function () { + it('throws if `expressionMode` is not defined', function () { + expect(() => + mc.makeExplicitEncryptionContext(value, { + // minimum required arguments from libmongocrypt + keyId: keyId.buffer, + algorithm: 'Unindexed' + }) + ) + .to.throw(/option `expressionMode` is required./) + .to.be.instanceOf(TypeError); + }); + }); }); }); From 5411440234e676a5044ffe565f8567835a9efb8a Mon Sep 17 00:00:00 2001 From: Bailey Pearson Date: Wed, 31 Jul 2024 08:17:21 -0600 Subject: [PATCH 2/3] fix new crypto callback test --- test/crypto.test.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/crypto.test.ts b/test/crypto.test.ts index 628dd33..87dd33e 100644 --- a/test/crypto.test.ts +++ b/test/crypto.test.ts @@ -38,7 +38,8 @@ function createEncryptedDocument(mongoCrypt: MongoCrypt) { const ctx = mongoCrypt.makeExplicitEncryptionContext(BSON.serialize({ v }), { keyId: keyId.buffer, - algorithm + algorithm, + expressionMode: false }); const getState = () => ctx.state; @@ -85,7 +86,7 @@ describe('Crypto hooks', () => { const mongoCryptOptions: ConstructorParameters[0] = { kmsProviders: BSON.serialize(kmsProviders), - cryptoCallbacks: spiedCallbacks + cryptoCallbacks: spiedCallbacks, }; const mongoCrypt = new MongoCrypt(mongoCryptOptions); From 46d0853be170c3f8ce2d04427bac70ece53a817d Mon Sep 17 00:00:00 2001 From: Bailey Pearson Date: Wed, 31 Jul 2024 08:23:14 -0600 Subject: [PATCH 3/3] fix lint --- test/crypto.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/crypto.test.ts b/test/crypto.test.ts index 87dd33e..21edd54 100644 --- a/test/crypto.test.ts +++ b/test/crypto.test.ts @@ -86,7 +86,7 @@ describe('Crypto hooks', () => { const mongoCryptOptions: ConstructorParameters[0] = { kmsProviders: BSON.serialize(kmsProviders), - cryptoCallbacks: spiedCallbacks, + cryptoCallbacks: spiedCallbacks }; const mongoCrypt = new MongoCrypt(mongoCryptOptions);