From 76831caf50c3e5148ef00a61630ea21dc6029456 Mon Sep 17 00:00:00 2001 From: Ivan Socolsky Date: Thu, 26 Nov 2015 14:05:52 -0300 Subject: [PATCH] verify proposal signature over raw tx --- lib/server.js | 6 ++++++ test/integration/helpers.js | 14 ++++++++++++++ test/integration/server.js | 14 +++++--------- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/lib/server.js b/lib/server.js index 3fd84a9..d0529c3 100644 --- a/lib/server.js +++ b/lib/server.js @@ -1449,6 +1449,12 @@ WalletService.prototype.sendTx = function(opts, cb) { if (!txp) return cb(Errors.TX_NOT_FOUND); if (!txp.isTemporary()) return cb(); + var raw = txp.getRawTx(); + var validSignature = self._verifySignature(raw, opts.proposalSignature, opts.proposalSignaturePubKey); + if (!validSignature) { + return cb(new ClientError('Invalid proposal signature')); + } + // Verify UTXOs are still available self.getUtxos({}, function(err, utxos) { if (err) return cb(err); diff --git a/test/integration/helpers.js b/test/integration/helpers.js index 24fb9d0..882a94f 100644 --- a/test/integration/helpers.js +++ b/test/integration/helpers.js @@ -394,6 +394,20 @@ helpers.createProposalOpts2 = function(outputs, moreOpts, inputs) { return opts; }; +helpers.getProposalSignatureOpts = function(txp, signingKey) { + var raw = txp.getRawTx(); + var proposalSignature = helpers.signMessage(raw, signingKey); + var x = new Bitcore.PrivateKey(signingKey).toPublicKey().toString(); + + return { + txProposalId: txp.id, + proposalSignature: proposalSignature, + proposalSignaturePubKey: new Bitcore.PrivateKey(signingKey).toPublicKey().toString(), + proposalSignaturePubKeySig: 'dummy', + } +}; + + helpers.createProposalOpts = function(type, outputs, signingKey, moreOpts, inputs) { _.each(outputs, function(output) { output.amount = helpers.toSatoshi(output.amount); diff --git a/test/integration/server.js b/test/integration/server.js index cf5ec35..9d8feb4 100644 --- a/test/integration/server.js +++ b/test/integration/server.js @@ -2366,7 +2366,7 @@ describe('Wallet service', function() { }); }); - it('should be able to send a temporary tx proposal', function(done) { + it.only('should be able to send a temporary tx proposal', function(done) { helpers.stubUtxos(server, wallet, [1, 2], function() { var txOpts = helpers.createProposalOpts2([{ toAddress: '18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', @@ -2375,15 +2375,11 @@ describe('Wallet service', function() { message: 'some message', customData: 'some custom data', }); - server.createTx(txOpts, function(err, tx) { + server.createTx(txOpts, function(err, txp) { should.not.exist(err); - should.exist(tx); - server.sendTx({ - txProposalId: tx.id, - proposalSignature: 'dummy', - proposalSignaturePubKey: 'dummy', - proposalSignaturePubKeySig: 'dummy', - }, function(err) { + should.exist(txp); + var sendOpts = helpers.getProposalSignatureOpts(txp, TestData.copayers[0].privKey_1H_0); + server.sendTx(sendOpts, function(err) { should.not.exist(err); server.getPendingTxs({}, function(err, txs) { should.not.exist(err);