Check signature for history keeper in a different process

pull/1/head
yflory 5 years ago
parent ab6ccfe1f6
commit 0d636dabc9

@ -0,0 +1,40 @@
const Nacl = require('tweetnacl/nacl-fast');
// TODO if this process is using too much CPU, we can use "cluster" to add load balancing to this code
process.on('message', function (data) {
console.log(+new Date(), "Message received by subprocess");
if (!data || !data.key || !data.msg || !data.txid) {
process.send({
error:'E_INVAL'
});
return;
}
const txid = data.txid;
const signedMsg = Nacl.util.decodeBase64(data.msg);
var validateKey;
try {
validateKey = Nacl.util.decodeBase64(data.key);
} catch (e) {
process.send({
txid: txid,
error:'E_BADKEY'
});
return;
}
// validate the message
const validated = Nacl.sign.open(signedMsg, validateKey);
if (!validated) {
process.send({
txid: txid,
error:'FAILED'
});
return;
}
console.log(+new Date(), "Verification done in the subprocess");
process.send({
txid: txid,
success: true
});
});

@ -3,6 +3,7 @@
const Core = module.exports; const Core = module.exports;
const Util = require("../common-util"); const Util = require("../common-util");
const escapeKeyCharacters = Util.escapeKeyCharacters; const escapeKeyCharacters = Util.escapeKeyCharacters;
const { fork } = require('child_process');
/* Use Nacl for checking signatures of messages */ /* Use Nacl for checking signatures of messages */
const Nacl = require("tweetnacl/nacl-fast"); const Nacl = require("tweetnacl/nacl-fast");

@ -6,6 +6,7 @@ const nThen = require('nthen');
const Util = require("./common-util"); const Util = require("./common-util");
const MetaRPC = require("./commands/metadata"); const MetaRPC = require("./commands/metadata");
const Nacl = require('tweetnacl/nacl-fast'); const Nacl = require('tweetnacl/nacl-fast');
const { fork } = require('child_process');
const now = function () { return (new Date()).getTime(); }; const now = function () { return (new Date()).getTime(); };
const ONE_DAY = 1000 * 60 * 60 * 24; // one day in milliseconds const ONE_DAY = 1000 * 60 * 60 * 24; // one day in milliseconds
@ -921,7 +922,14 @@ HK.onDirectMessage = function (Env, Server, seq, userId, json) {
* adds timestamps to incoming messages * adds timestamps to incoming messages
* writes messages to the store * writes messages to the store
*/ */
const check = fork('lib/check-signature.js');
const onChecked = Util.mkEvent();
check.on('message', function (res) {
onChecked.fire(res);
});
HK.onChannelMessage = function (Env, Server, channel, msgStruct) { HK.onChannelMessage = function (Env, Server, channel, msgStruct) {
console.log(+new Date(), "onChannelMessage");
const Log = Env.Log; const Log = Env.Log;
// TODO our usage of 'channel' here looks prone to errors // TODO our usage of 'channel' here looks prone to errors
@ -962,20 +970,37 @@ HK.onChannelMessage = function (Env, Server, channel, msgStruct) {
let signedMsg = (isCp) ? msgStruct[4].replace(CHECKPOINT_PATTERN, '') : msgStruct[4]; let signedMsg = (isCp) ? msgStruct[4].replace(CHECKPOINT_PATTERN, '') : msgStruct[4];
// convert the message from a base64 string into a Uint8Array // convert the message from a base64 string into a Uint8Array
// FIXME this can fail and the client won't notice const txid = Util.uid();
signedMsg = Nacl.util.decodeBase64(signedMsg); const next = w();
// FIXME this can blow up // Listen for messages
// TODO check that that won't cause any problems other than not being able to append... const onCheck = function (res) {
const validateKey = Nacl.util.decodeBase64(metadata.validateKey); if (!res) { return; }
// validate the message if (res.txid !== txid) { return; }
const validated = Nacl.sign.open(signedMsg, validateKey); // Wev'e received an answer, remove this handler
if (!validated) { console.log(+new Date(), "Received verification response");
// don't go any further if the message fails validation onChecked.unreg(onCheck);
w.abort(); if (res.error) {
Log.info("HK_SIGNED_MESSAGE_REJECTED", 'Channel '+channel.id); // don't go any further if the message fails validation
return; if (res.error === 'FAILED') {
} // Signature doesn't match the public key
Log.info("HK_SIGNED_MESSAGE_REJECTED", 'Channel '+channel.id);
}
w.abort();
return;
}
// Success, continue to next block
next();
};
onChecked.reg(onCheck);
console.log(+new Date(), "Send verification request");
// Send the request
check.send({
txid: txid,
msg: signedMsg,
key: metadata.validateKey
});
}).nThen(function () { }).nThen(function () {
// do checkpoint stuff... // do checkpoint stuff...
@ -1002,7 +1027,9 @@ HK.onChannelMessage = function (Env, Server, channel, msgStruct) {
msgStruct.push(now()); msgStruct.push(now());
// storeMessage // storeMessage
console.log(+new Date(), "Storing message");
storeMessage(Env, channel, JSON.stringify(msgStruct), isCp, getHash(msgStruct[4], Log)); storeMessage(Env, channel, JSON.stringify(msgStruct), isCp, getHash(msgStruct[4], Log));
console.log(+new Date(), "Message stored");
}); });
}; };

Loading…
Cancel
Save