From 585cdb1cbe44b28d5d6de831fa2b04ffb68a609d Mon Sep 17 00:00:00 2001 From: Gabriel Viganotti Date: Tue, 4 Jul 2017 15:15:50 +0900 Subject: [PATCH] fix/Crypto: KeyBytes were not being copied after returned by safe_core causing a segv as memory was reused by the lib (#96) --- src/native/_crypto.js | 29 +++++++++++++++++++---------- test/crypto.js | 2 +- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/native/_crypto.js b/src/native/_crypto.js index eacc8ad..939eb9c 100644 --- a/src/native/_crypto.js +++ b/src/native/_crypto.js @@ -20,16 +20,25 @@ function strToBuffer(str) { } function toBuffer(app, key) { - let keyArr = key.buffer || key; - if (keyArr.length != 32) throw Error("Sign/Enc Keys _must be_ 32 bytes long.") - keyArr = t.KEYBYTES(keyArr); - return [app, keyArr] + let keyArr = key; + if (!Buffer.isBuffer(key)) { + const b = new Buffer(key); + if (b.length != 32) throw Error("Sign/Enc Keys _must be_ 32 bytes long.") + keyArr = t.KEYBYTES(b).ref().readPointer(0); + } + return [app, keyArr]; } function appStrToBuffer(appPtr, str) { return [appPtr].concat(strToBuffer(str)).concat(Array.prototype.slice.call(arguments, 2)) } +// Helper to create a copy of the received KEYBYTES array as it might +// be overwritten after the callback finishes. +function copyKeyBytesArray(res) { + return t.KEYBYTES(ref.reinterpret(res[0], 32)); +} + module.exports = { types: { SignKeyHandle, @@ -39,18 +48,18 @@ module.exports = { }, functions: { app_pub_sign_key: [t.Void, [t.AppPtr, 'pointer', 'pointer']], - sign_key_new: [t.Void, [t.AppPtr, t.KEYBYTES, 'pointer', 'pointer']], + sign_key_new: [t.Void, [t.AppPtr, ref.refType(t.KEYBYTES), 'pointer', 'pointer']], sign_key_get: [t.Void, [t.AppPtr, SignKeyHandle, 'pointer', 'pointer']], sign_key_free: [t.Void, [t.AppPtr, SignKeyHandle, 'pointer', 'pointer']], app_pub_enc_key: [t.Void, [t.AppPtr, 'pointer', 'pointer']], enc_generate_key_pair: [t.Void, [t.AppPtr, 'pointer', 'pointer']], - enc_pub_key_new: [t.Void, [t.AppPtr, t.KEYBYTES, 'pointer', 'pointer']], + enc_pub_key_new: [t.Void, [t.AppPtr, ref.refType(t.KEYBYTES), 'pointer', 'pointer']], enc_pub_key_get: [t.Void, [t.AppPtr, EncryptPubKeyHandle, 'pointer', 'pointer']], enc_secret_key_free: [t.Void, [t.AppPtr, EncryptPubKeyHandle, 'pointer', 'pointer']], - enc_secret_key_new: [t.Void, [t.AppPtr, t.KEYBYTES, 'pointer', 'pointer']], + enc_secret_key_new: [t.Void, [t.AppPtr, ref.refType(t.KEYBYTES), 'pointer', 'pointer']], enc_secret_key_get: [t.Void, [t.AppPtr, EncryptSecKeyHandle, 'pointer', 'pointer']], enc_secret_key_free: [t.Void, [t.AppPtr, EncryptSecKeyHandle, 'pointer', 'pointer']], @@ -66,17 +75,17 @@ module.exports = { api: { app_pub_sign_key: h.Promisified(null, SignKeyHandle), sign_key_new: h.Promisified(toBuffer, SignKeyHandle), - sign_key_get: h.Promisified(null, t.KEYBYTES), + sign_key_get: h.Promisified(null, ['pointer'], copyKeyBytesArray), sign_key_free: h.Promisified(null, []), app_pub_enc_key: h.Promisified(null, EncryptKeyHandle), enc_generate_key_pair: h.Promisified(null, [EncryptPubKeyHandle, EncryptSecKeyHandle]), enc_pub_key_new: h.Promisified(toBuffer, EncryptPubKeyHandle), - enc_pub_key_get: h.Promisified(null, t.KEYBYTES), + enc_pub_key_get: h.Promisified(null, ['pointer'], copyKeyBytesArray), enc_secret_key_new: h.Promisified(toBuffer, EncryptPubKeyHandle), - enc_secret_key_get: h.Promisified(null, t.KEYBYTES), + enc_secret_key_get: h.Promisified(null, ['pointer'], copyKeyBytesArray), encrypt: h.Promisified(appStrToBuffer, [t.u8Pointer, t.usize], h.asBuffer), decrypt: h.Promisified(appStrToBuffer, [t.u8Pointer, t.usize], h.asBuffer), diff --git a/test/crypto.js b/test/crypto.js index 801c068..a9e17b6 100644 --- a/test/crypto.js +++ b/test/crypto.js @@ -82,7 +82,7 @@ describe('App Crypto Tests', () => { }) ]).then((r) => should(r[0]).not.equal(r[1]))); - it.skip('generate key pair from raw keys', () => { + it('generate key pair from raw keys', () => { let rawPubKey; let rawPubKeyFromRaw; let rawSecKey;