add proposal check on sign
This commit is contained in:
parent
a375d08c84
commit
9665f23bc5
|
@ -17,9 +17,6 @@ Verifier.checkAddress = function(data, address) {
|
||||||
return (local.address == address.address && JSON.stringify(local.publicKeys) == JSON.stringify(address.publicKeys));
|
return (local.address == address.address && JSON.stringify(local.publicKeys) == JSON.stringify(address.publicKeys));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
Verifier.checkCopayers = function(copayers, walletPrivKey, myXPrivKey, n) {
|
Verifier.checkCopayers = function(copayers, walletPrivKey, myXPrivKey, n) {
|
||||||
|
|
||||||
var walletPubKey = Bitcore.PrivateKey.fromString(walletPrivKey).toPublicKey().toString();
|
var walletPubKey = Bitcore.PrivateKey.fromString(walletPrivKey).toPublicKey().toString();
|
||||||
|
@ -56,4 +53,11 @@ Verifier.checkCopayers = function(copayers, walletPrivKey, myXPrivKey, n) {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Verifier.checkTxProposal = function(data, txp) {
|
||||||
|
var header = txp.toAddress + '|' + txp.amount + '|' + (txp.message || '');
|
||||||
|
if (!SignUtils.verify(header, txp.proposalSignature, data.signingPubKey)) return false;
|
||||||
|
|
||||||
|
return Verifier.checkAddress(data, txp.changeAddress);
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = Verifier;
|
module.exports = Verifier;
|
||||||
|
|
|
@ -62,7 +62,6 @@ function API(opts) {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
API.prototype._tryToComplete = function(data, cb) {
|
API.prototype._tryToComplete = function(data, cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
|
@ -329,6 +328,10 @@ API.prototype.signTxProposal = function(txp, cb) {
|
||||||
function(err, data) {
|
function(err, data) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
|
|
||||||
|
if (!Verifier.checkTxProposal(data, txp)) {
|
||||||
|
return cb(new ServerCompromisedError('Server sent fake transaction proposal'));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//Derive proper key to sign, for each input
|
//Derive proper key to sign, for each input
|
||||||
var privs = [],
|
var privs = [],
|
||||||
|
|
|
@ -464,7 +464,7 @@ CopayServer.prototype.createTx = function(opts, cb) {
|
||||||
if (!wallet.isComplete()) return cb(new ClientError('Wallet is not complete'));
|
if (!wallet.isComplete()) return cb(new ClientError('Wallet is not complete'));
|
||||||
|
|
||||||
var copayer = wallet.getCopayer(self.copayerId);
|
var copayer = wallet.getCopayer(self.copayerId);
|
||||||
var msg = opts.toAddress + '|' + opts.amount + '|' + opts.message;
|
var msg = opts.toAddress + '|' + opts.amount + '|' + (opts.message || '');
|
||||||
if (!self._verifySignature(msg, opts.proposalSignature, copayer.signingPubKey))
|
if (!self._verifySignature(msg, opts.proposalSignature, copayer.signingPubKey))
|
||||||
return cb(new ClientError('Invalid proposal signature'));
|
return cb(new ClientError('Invalid proposal signature'));
|
||||||
|
|
||||||
|
|
|
@ -126,6 +126,46 @@ describe(' client API ', function() {
|
||||||
client.request = request;
|
client.request = request;
|
||||||
|
|
||||||
|
|
||||||
|
client.createAddress(function(err, x) {
|
||||||
|
should.not.exist(err);
|
||||||
|
x.address.should.equal('2N3fA6wDtnebzywPkGuNK9KkFaEzgbPRRTq');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
it(' should detect fake addresses ', function(done) {
|
||||||
|
var response = {
|
||||||
|
createdOn: 1424105995,
|
||||||
|
address: '2N3fA6wDtnebzywPkGuNK9KkFaEzgbPRRTq',
|
||||||
|
path: 'm/2147483647/0/8',
|
||||||
|
publicKeys: ['03f6a5fe8db51bfbaf26ece22a3e3bc242891a47d3048fc70bc0e8c03a071ad76f']
|
||||||
|
};
|
||||||
|
var request = sinon.mock().yields(null, {
|
||||||
|
statusCode: 200
|
||||||
|
}, response);
|
||||||
|
client.request = request;
|
||||||
|
client.createAddress(function(err, x) {
|
||||||
|
err.code.should.equal('SERVERCOMPROMISED');
|
||||||
|
err.message.should.contain('fake address');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe(' createAddress ', function() {
|
||||||
|
it(' should check address ', function(done) {
|
||||||
|
|
||||||
|
var response = {
|
||||||
|
createdOn: 1424105995,
|
||||||
|
address: '2N3fA6wDtnebzywPkGuNK9KkFaEzgbPRRTq',
|
||||||
|
path: 'm/2147483647/0/7',
|
||||||
|
publicKeys: ['03f6a5fe8db51bfbaf26ece22a3e3bc242891a47d3048fc70bc0e8c03a071ad76f']
|
||||||
|
};
|
||||||
|
var request = sinon.mock().yields(null, {
|
||||||
|
statusCode: 200
|
||||||
|
}, response);
|
||||||
|
client.request = request;
|
||||||
|
|
||||||
|
|
||||||
client.createAddress(function(err, x) {
|
client.createAddress(function(err, x) {
|
||||||
should.not.exist(err);
|
should.not.exist(err);
|
||||||
x.address.should.equal('2N3fA6wDtnebzywPkGuNK9KkFaEzgbPRRTq');
|
x.address.should.equal('2N3fA6wDtnebzywPkGuNK9KkFaEzgbPRRTq');
|
||||||
|
|
|
@ -176,7 +176,7 @@ helpers.createProposalOpts = function(toAddress, amount, message, signingKey) {
|
||||||
message: message,
|
message: message,
|
||||||
proposalSignature: null,
|
proposalSignature: null,
|
||||||
};
|
};
|
||||||
var msg = opts.toAddress + '|' + opts.amount + '|' + opts.message;
|
var msg = opts.toAddress + '|' + opts.amount + '|' + (opts.message || '');
|
||||||
try {
|
try {
|
||||||
opts.proposalSignature = SignUtils.sign(msg, signingKey);
|
opts.proposalSignature = SignUtils.sign(msg, signingKey);
|
||||||
} catch (ex) {}
|
} catch (ex) {}
|
||||||
|
@ -706,7 +706,7 @@ describe('Copay server', function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fail to create tx for address invalid address', function(done) {
|
it('should fail to create tx for invalid address', function(done) {
|
||||||
helpers.createUtxos(server, wallet, [100, 200], function(utxos) {
|
helpers.createUtxos(server, wallet, [100, 200], function(utxos) {
|
||||||
helpers.stubBlockExplorer(server, utxos);
|
helpers.stubBlockExplorer(server, utxos);
|
||||||
var txOpts = helpers.createProposalOpts('invalid address', 80, null, TestData.copayers[0].privKey);
|
var txOpts = helpers.createProposalOpts('invalid address', 80, null, TestData.copayers[0].privKey);
|
||||||
|
|
Loading…
Reference in New Issue