always check proposal signature
This commit is contained in:
parent
57f8863bf9
commit
53bb2567d6
|
@ -6,8 +6,8 @@ var common = require('./common');
|
|||
|
||||
program
|
||||
.version('0.0.1')
|
||||
.option('-c,--config [file]', 'Wallet config filename')
|
||||
.option('-v,--verbose', 'be verbose')
|
||||
.option('-c, --config [file]', 'Wallet config filename')
|
||||
.option('-v, --verbose', 'be verbose')
|
||||
.parse(process.argv);
|
||||
|
||||
var args = program.args;
|
||||
|
|
|
@ -7,8 +7,8 @@ var common = require('./common');
|
|||
|
||||
program
|
||||
.version('0.0.1')
|
||||
.option('-c,--config [file]', 'Wallet config filename')
|
||||
.option('-v,--verbose', 'be verbose')
|
||||
.option('-c, --config [file]', 'Wallet config filename')
|
||||
.option('-v, --verbose', 'be verbose')
|
||||
.parse(process.argv);
|
||||
|
||||
var args = program.args;
|
||||
|
|
|
@ -6,8 +6,8 @@ var common = require('./common');
|
|||
|
||||
program
|
||||
.version('0.0.1')
|
||||
.option('-c,--config [file]', 'Wallet config filename')
|
||||
.option('-v,--verbose', 'be verbose')
|
||||
.option('-c, --config [file]', 'Wallet config filename')
|
||||
.option('-v, --verbose', 'be verbose')
|
||||
.parse(process.argv);
|
||||
|
||||
var args = program.args;
|
||||
|
|
|
@ -6,8 +6,8 @@ var common = require('./common');
|
|||
|
||||
program
|
||||
.version('0.0.1')
|
||||
.option('-c,--config [file]', 'Wallet config filename')
|
||||
.option('-n,--network [networkname]', 'livenet|testnet', String, 'livenet')
|
||||
.option('-c, --config [file]', 'Wallet config filename')
|
||||
.option('-n, --network [networkname]', 'livenet|testnet', String, 'livenet')
|
||||
.usage('[options] <walletName> <m-n> [copayerName]')
|
||||
.parse(process.argv);
|
||||
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
var program = require('commander');
|
||||
var cli = require('../lib/clilib.js');
|
||||
|
||||
program
|
||||
.version('0.0.1')
|
||||
.parse(process.argv);
|
||||
|
||||
|
|
@ -6,7 +6,7 @@ var common = require('./common');
|
|||
|
||||
program
|
||||
.version('0.0.1')
|
||||
.option('-c,--config [file]', 'Wallet config filename')
|
||||
.option('-c, --config [file]', 'Wallet config filename')
|
||||
.usage('[options] <secret> [copayerName]')
|
||||
.parse(process.argv);
|
||||
|
||||
|
|
|
@ -6,8 +6,8 @@ var common = require('./common');
|
|||
|
||||
program
|
||||
.version('0.0.1')
|
||||
.option('-c,--config [file]', 'Wallet config filename')
|
||||
.option('-v,--verbose', 'be verbose')
|
||||
.option('-c, --config [file]', 'Wallet config filename')
|
||||
.option('-v, --verbose', 'be verbose')
|
||||
.usage('[options] <address> <amount> <message>')
|
||||
.parse(process.argv);
|
||||
|
||||
|
|
|
@ -6,8 +6,8 @@ var common = require('./common');
|
|||
|
||||
program
|
||||
.version('0.0.1')
|
||||
.option('-c,--config [file]', 'Wallet config filename')
|
||||
.option('-v,--verbose', 'be verbose')
|
||||
.option('-c, --config [file]', 'Wallet config filename')
|
||||
.option('-v, --verbose', 'be verbose')
|
||||
.parse(process.argv);
|
||||
|
||||
var args = program.args;
|
||||
|
|
|
@ -332,7 +332,6 @@ CopayServer.prototype._getUtxos = function(cb) {
|
|||
|
||||
// Get addresses for this wallet
|
||||
self.storage.fetchAddresses(self.walletId, function(err, addresses) {
|
||||
console.log('[server.js.334:addresses:]',addresses); //TODO
|
||||
if (err) return cb(err);
|
||||
if (addresses.length == 0)
|
||||
return cb(null, []);
|
||||
|
@ -389,7 +388,6 @@ CopayServer.prototype.getBalance = function(opts, cb) {
|
|||
var self = this;
|
||||
|
||||
self._getUtxos(function(err, utxos) {
|
||||
console.log('[server.js.390:utxos:]',utxos); //TODO
|
||||
if (err) return cb(err);
|
||||
|
||||
var balance = {};
|
||||
|
@ -445,15 +443,13 @@ CopayServer.prototype._selectUtxos = function(txp, utxos) {
|
|||
CopayServer.prototype.createTx = function(opts, cb) {
|
||||
var self = this;
|
||||
|
||||
if (!Utils.checkRequired(opts, ['toAddress', 'amount']))
|
||||
if (!Utils.checkRequired(opts, ['toAddress', 'amount', 'proposalSignature']))
|
||||
return cb(new ClientError('Required argument missing'));
|
||||
|
||||
Utils.runLocked(self.walletId, cb, function(cb) {
|
||||
self.getWallet({}, function(err, wallet) {
|
||||
if (err) return cb(err);
|
||||
if (!wallet.isComplete()) return cb(new ClientError('Wallet is not complete'));
|
||||
if (wallet.isShared() && !Utils.checkRequired(opts, 'proposalSignature'))
|
||||
return cb(new ClientError('Proposal signature is required for shared wallets'));
|
||||
|
||||
var copayer = wallet.getCopayer(self.copayerId);
|
||||
var msg = opts.toAddress + '|' + opts.amount + '|' + opts.message;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
var _ = require('lodash');
|
||||
var Bitcore = require('bitcore');
|
||||
var PrivateKey = Bitcore.PrivateKey;
|
||||
|
@ -10,12 +9,11 @@ var BufferReader = Bitcore.encoding.BufferReader;
|
|||
|
||||
|
||||
|
||||
var SignUtils = function () {
|
||||
};
|
||||
var SignUtils = function() {};
|
||||
|
||||
/* TODO: It would be nice to be compatible with bitcoind signmessage. How
|
||||
* the hash is calculated there? */
|
||||
SignUtils.hash = function (text) {
|
||||
SignUtils.hash = function(text) {
|
||||
var buf = new Buffer(text);
|
||||
var ret = Hash.sha256sha256(buf);
|
||||
ret = new BufferReader(ret).readReverse();
|
||||
|
@ -23,14 +21,14 @@ SignUtils.hash = function (text) {
|
|||
};
|
||||
|
||||
|
||||
SignUtils.sign = function (text, privKey) {
|
||||
SignUtils.sign = function(text, privKey) {
|
||||
var priv = new PrivateKey(privKey);
|
||||
var hash = SignUtils.hash(text);
|
||||
return ECDSA.sign(hash, priv, 'little').toString();
|
||||
};
|
||||
|
||||
|
||||
SignUtils.verify = function (text, signature, pubKey) {
|
||||
SignUtils.verify = function(text, signature, pubKey) {
|
||||
var pub = new PublicKey(pubKey);
|
||||
var hash = SignUtils.hash(text);
|
||||
|
||||
|
|
|
@ -167,9 +167,13 @@ helpers.createProposalOpts = function(toAddress, amount, message, signingKey) {
|
|||
toAddress: toAddress,
|
||||
amount: helpers.toSatoshi(amount),
|
||||
message: message,
|
||||
proposalSignature: null,
|
||||
};
|
||||
var msg = opts.toAddress + '|' + opts.amount + '|' + opts.message;
|
||||
opts.proposalSignature = SignUtils.sign(msg, signingKey);
|
||||
try {
|
||||
opts.proposalSignature = SignUtils.sign(msg, signingKey);
|
||||
} catch (ex) {}
|
||||
|
||||
return opts;
|
||||
};
|
||||
|
||||
|
@ -667,6 +671,34 @@ describe('Copay server', function() {
|
|||
});
|
||||
});
|
||||
|
||||
it('should fail to create tx with invalid proposal signature', function(done) {
|
||||
helpers.createUtxos(server, wallet, [100, 200], function(utxos) {
|
||||
helpers.stubBlockExplorer(server, utxos);
|
||||
var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 80, null, 'dummy');
|
||||
|
||||
server.createTx(txOpts, function(err, tx) {
|
||||
should.not.exist(tx);
|
||||
err.should.exist;
|
||||
err.message.should.equal('Invalid proposal signature');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail to create tx with proposal signed by another copayer', function(done) {
|
||||
helpers.createUtxos(server, wallet, [100, 200], function(utxos) {
|
||||
helpers.stubBlockExplorer(server, utxos);
|
||||
var txOpts = helpers.createProposalOpts('18PzpUFkFZE8zKWUPvfykkTxmB9oMR8qP7', 80, null, TestData.copayers[1].privKey);
|
||||
|
||||
server.createTx(txOpts, function(err, tx) {
|
||||
should.not.exist(tx);
|
||||
err.should.exist;
|
||||
err.message.should.equal('Invalid proposal signature');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail to create tx for address invalid address', function(done) {
|
||||
helpers.createUtxos(server, wallet, [100, 200], function(utxos) {
|
||||
helpers.stubBlockExplorer(server, utxos);
|
||||
|
|
Loading…
Reference in New Issue