Skip to content

Commit

Permalink
fix(NODE-6300): make expressionMode required in C++ in makeExplicitEn…
Browse files Browse the repository at this point in the history
…cryptionContext (#37)
  • Loading branch information
baileympearson committed Aug 6, 2024
1 parent 184167e commit c6f106a
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 10 deletions.
29 changes: 20 additions & 9 deletions addon/mongocrypt.cc
Original file line number Diff line number Diff line change
Expand Up @@ -589,13 +589,29 @@ Value MongoCrypt::MakeEncryptionContext(const CallbackInfo& info) {
}

Value MongoCrypt::MakeExplicitEncryptionContext(const CallbackInfo& info) {
std::unique_ptr<mongocrypt_ctx_t, MongoCryptContextDeleter> 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<mongocrypt_ctx_t, MongoCryptContextDeleter> context(
mongocrypt_ctx_new(_mongo_crypt.get()));

if (!options.Get("keyId").IsUndefined()) {
Uint8Array keyId = Uint8ArrayFromValue(options["keyId"], "keyId");

Expand Down Expand Up @@ -658,12 +674,7 @@ Value MongoCrypt::MakeExplicitEncryptionContext(const CallbackInfo& info) {
std::unique_ptr<mongocrypt_binary_t, MongoCryptBinaryDeleter> 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()));
Expand Down
5 changes: 5 additions & 0 deletions addon/mongocrypt.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ namespace opensslcrypto {
std::unique_ptr<CryptoHooks> createOpenSSLCryptoHooks();
}

typedef bool (*ExplicitEncryptionContextInitFunction)(mongocrypt_ctx_t*, mongocrypt_binary_t*);

class MongoCrypt : public Napi::ObjectWrap<MongoCrypt> {
public:
static Napi::Function Init(Napi::Env env);
Expand All @@ -67,6 +69,9 @@ class MongoCrypt : public Napi::ObjectWrap<MongoCrypt> {
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);
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down
14 changes: 14 additions & 0 deletions test/bindings.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
});
});
});

Expand Down
3 changes: 2 additions & 1 deletion test/crypto.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit c6f106a

Please sign in to comment.