fix proposal signature validation in publishTx

This commit is contained in:
Ivan Socolsky 2016-01-28 11:01:03 -03:00
parent 7f423d1351
commit 5f35aafc29
2 changed files with 26 additions and 32 deletions

View File

@ -650,8 +650,8 @@ WalletService.prototype.joinWallet = function(opts, cb) {
}
if (_.find(wallet.copayers, {
xPubKey: opts.xPubKey
})) return cb(Errors.COPAYER_IN_WALLET);
xPubKey: opts.xPubKey
})) return cb(Errors.COPAYER_IN_WALLET);
if (wallet.copayers.length == wallet.n) return cb(Errors.WALLET_FULL);
@ -744,8 +744,8 @@ WalletService.prototype._canCreateAddress = function(ignoreMaxGap, cb) {
isChange: true
}), Defaults.MAX_MAIN_ADDRESS_GAP);
if (latestAddresses.length < Defaults.MAX_MAIN_ADDRESS_GAP || _.any(latestAddresses, {
hasActivity: true
})) return cb(null, true);
hasActivity: true
})) return cb(null, true);
var bc = self._getBlockchainExplorer(latestAddresses[0].network);
var activityFound = false;
@ -1618,8 +1618,6 @@ WalletService.prototype._verifyRequestPubKey = function(requestPubKey, signature
* @param {Object} opts
* @param {string} opts.txProposalId - The tx id.
* @param {string} opts.proposalSignature - S(raw tx). Used by other copayers to verify the proposal.
* @param {string} opts.proposalSignaturePubKey - (Optional) An alternative public key used to verify the proposal signature.
* @param {string} opts.proposalSignaturePubKeySig - (Optional) A signature used to validate the opts.proposalSignaturePubKey.
*/
WalletService.prototype.publishTx = function(opts, cb) {
var self = this;
@ -1648,13 +1646,11 @@ WalletService.prototype.publishTx = function(opts, cb) {
return cb(new ClientError('Invalid proposal signature'));
}
// Verify signingKey
if (opts.proposalSignaturePubKey) {
if (opts.proposalSignaturePubKey != signingKey ||
!self._verifyRequestPubKey(opts.proposalSignaturePubKey, opts.proposalSignaturePubKeySig, copayer.xPubKey)
) {
return cb(new ClientError('Invalid proposal signing key'));
}
// Save signature info for other copayers to check
txp.proposalSignature = opts.proposalSignature;
if (signingKey.selfSigned) {
txp.proposalSignaturePubKey = signingKey.key;
txp.proposalSignaturePubKeySig = signingKey.signature;
}
// Verify UTXOs are still available

View File

@ -2739,6 +2739,7 @@ describe('Wallet service', function() {
server.getPendingTxs({}, function(err, txs) {
should.not.exist(err);
txs.length.should.equal(1);
should.exist(txs[0].proposalSignature);
done();
});
});
@ -2795,21 +2796,14 @@ describe('Wallet service', function() {
should.not.exist(err);
should.exist(txp);
var raw = txp.getRawTx();
var proposalSignature = helpers.signMessage(raw, TestData.copayers[0].privKey_1H_0);
var pubKey = new Bitcore.PrivateKey(TestData.copayers[0].privKey_1H_0).toPublicKey().toString();
var pubKeySig = helpers.signMessage(pubKey, TestData.copayers[1].privKey_1H_0);
var publishOpts = {
txProposalId: txp.id,
proposalSignature: proposalSignature,
proposalSignaturePubKey: pubKey,
proposalSignaturePubKeySig: pubKeySig,
proposalSignature: helpers.signMessage(txp.getRawTx(), TestData.copayers[1].privKey_1H_0),
}
server.publishTx(publishOpts, function(err) {
should.exist(err);
err.message.should.contain('Invalid proposal signing key');
err.message.should.contain('Invalid proposal signature');
done();
});
});
@ -2818,18 +2812,17 @@ describe('Wallet service', function() {
it('should accept a tx proposal signed with a custom key', function(done) {
var reqPrivKey = new Bitcore.PrivateKey();
var reqPubKey = reqPrivKey.toPublicKey();
var reqPubKey = reqPrivKey.toPublicKey().toString();
var xPrivKey = TestData.copayers[0].xPrivKey_44H_0H_0H;
var sig = helpers.signRequestPubKey(reqPubKey, xPrivKey);
var opts = {
var accessOpts = {
copayerId: TestData.copayers[0].id44,
requestPubKey: reqPubKey,
signature: sig,
signature: helpers.signRequestPubKey(reqPubKey, xPrivKey),
};
server.addAccess(opts, function(err) {
server.addAccess(accessOpts, function(err) {
should.not.exist(err);
helpers.stubUtxos(server, wallet, [1, 2], function() {
@ -2846,14 +2839,19 @@ describe('Wallet service', function() {
var publishOpts = {
txProposalId: txp.id,
proposalSignature: helpers.signMessage(txp.getRawTx(), reqPrivKey),
proposalSignaturePubKey: reqPubKey,
proposalSignaturePubKeySig: sig,
}
server.publishTx(publishOpts, function(err) {
should.exist(err);
err.message.should.contain('Invalid proposal signing key');
done();
should.not.exist(err);
server.getTx({
txProposalId: txp.id
}, function(err, x) {
should.not.exist(err);
x.proposalSignature.should.equal(publishOpts.proposalSignature);
x.proposalSignaturePubKey.should.equal(accessOpts.requestPubKey);
x.proposalSignaturePubKeySig.should.equal(accessOpts.signature);
done();
});
});
});
});