supports multiple pubkeys per copayer

This commit is contained in:
Matias Alejo Garcia 2015-08-04 21:05:26 -03:00
parent 3122e9ba7c
commit edc3bc6713
7 changed files with 57 additions and 38 deletions

View File

@ -151,16 +151,6 @@ ExpressApp.prototype.start = function(opts, cb) {
});
router.put('/v1/copayers', function(req, res) {
getServerWithAuth(req, res, function(server) {
server.replaceTemporaryRequestKey(req.body, function(err, result) {
if (err) return returnError(err, res, req);
res.json(result);
});
});
});
router.get('/v1/wallets/', function(req, res) {
getServerWithAuth(req, res, function(server) {
var result = {};

View File

@ -17,11 +17,10 @@ function Copayer() {
};
// requestPubKey could be one or an array of keys
Copayer.create = function(opts) {
opts = opts || {};
$.checkArgument(opts.xPubKey, 'Missing copayer extended public key');
$.checkArgument(opts.requestPubKey, 'Missing copayer request public key');
$.checkArgument(opts.requestPubKey || opts.requestPubKeys, 'Missing copayer request public key');
opts.copayerIndex = opts.copayerIndex || 0;
@ -32,12 +31,16 @@ Copayer.create = function(opts) {
x.id = WalletUtils.xPubToCopayerId(x.xPubKey);
x.name = opts.name;
x.signature = opts.signature; // So third parties can check independently
x.requestPubKey = opts.requestPubKey;
if (!x.requestPubKeys) {
x.requestPubKeys = [{
key: opts.requestPubKey,
signature: opts.signature,
}];
}
x.addressManager = AddressManager.create({
copayerIndex: opts.copayerIndex
});
x.isTemporaryRequestKey = opts.isTemporaryRequestKey || false;
return x;
};
@ -49,12 +52,15 @@ Copayer.fromObj = function(obj) {
x.id = obj.id;
x.name = obj.name;
x.xPubKey = obj.xPubKey;
x.requestPubKey = obj.requestPubKey;
x.signature = obj.signature;
x.isTemporaryRequestKey = obj.isTemporaryRequestKey;
if (!obj.requestPubKeys) {
x.requestPubKeys = [{
key: obj.requestPubKey,
signature: obj.signature,
}];
} else {
x.requestPubKeys = obj.requestPubKeys;
}
x.addressManager = AddressManager.fromObj(obj.addressManager);
return x;
};

View File

@ -115,15 +115,12 @@ Wallet.prototype.addCopayerRequestKey = function(copayerId, requestPubKey, signa
});
$.checkState(c);
if (_.isArray(c.requestPubKey)) {
$.checkState(_.isArray(c.signature));
//new ones go first
c.requestPubKeys.unshift({
key: requestPubKey,
signature: signature,
});
c.requestPubKey.push(requestPubKey);
c.signature.push(signature);
} else {
c.requestPubKey = requestPubKey;
c.signature = signature;
}
//this._updatePublicKeyRing();
};

View File

@ -165,7 +165,7 @@ WalletService.getInstance = function(opts) {
* @param {Object} opts
* @param {string} opts.copayerId - The copayer id making the request.
* @param {string} opts.message - The contents of the request to be signed.
* @param {string} opts.signature - Signature of message to be verified using the copayer's requestPubKey
* @param {string} opts.signature - Signature of message to be verified using one of the copayer's requestPubKeys
* @param {string} opts.clientVersion - A string that identifies the client issuing the request
*/
WalletService.getInstanceWithAuth = function(opts, cb) {
@ -177,7 +177,7 @@ WalletService.getInstanceWithAuth = function(opts, cb) {
if (err) return cb(err);
if (!copayer) return cb(new ClientError(Errors.codes.NOT_AUTHORIZED, 'Copayer not found'));
var isValid = server._verifySignature(opts.message, opts.signature, copayer.requestPubKey);
var isValid = server._verifySignatureAgainstArray(opts.message, opts.signature, copayer.requestPubKeys);
if (!isValid)
return cb(new ClientError(Errors.codes.NOT_AUTHORIZED, 'Invalid signature'));
@ -276,10 +276,24 @@ WalletService.prototype.getWallet = function(opts, cb) {
* Verifies a signature
* @param text
* @param signature
* @param pubKey
* @param pubKeys
*/
WalletService.prototype._verifySignature = function(text, signature, pubKey) {
return WalletUtils.verifyMessage(text, signature, pubKey);
WalletService.prototype._verifySignature = function(text, signature, pubkey) {
return WalletUtils.verifyMessage(text, signature, pubkey);
};
/*
* Verifies signature againt a collection of pubkeys
* @param text
* @param signature
* @param pubKeys
*/
WalletService.prototype._verifySignatureAgainstArray = function(text, signature, pubKeys) {
var self = this;
return _.any(pubKeys, function(item) {
return self._verifySignature(text, signature, item.key);
});
};
/**
@ -545,7 +559,7 @@ WalletService.prototype.verifyMessageSignature = function(opts, cb) {
var copayer = wallet.getCopayer(self.copayerId);
var isValid = self._verifySignature(opts.message, opts.signature, copayer.requestPubKey);
var isValid = self._verifySignatureAgainstArray(opts.message, opts.signature, copayer.requestPubKeys);
return cb(null, isValid);
});
};
@ -966,7 +980,7 @@ WalletService.prototype.createTx = function(opts, cb) {
hash = WalletUtils.getProposalHash(header)
}
if (!self._verifySignature(hash, opts.proposalSignature, copayer.requestPubKey))
if (!self._verifySignatureAgainstArray(hash, opts.proposalSignature, copayer.requestPubKeys))
return cb(new ClientError('Invalid proposal signature'));
self._canCreateTx(self.copayerId, function(err, canCreate) {

View File

@ -110,10 +110,11 @@ Storage.prototype.storeWalletAndUpdateCopayersLookup = function(wallet, cb) {
var self = this;
var copayerLookups = _.map(wallet.copayers, function(copayer) {
$.checkState(copayer.requestPubKeys);
return {
copayerId: copayer.id,
walletId: wallet.id,
requestPubKey: copayer.requestPubKey,
requestPubKeys: copayer.requestPubKeys,
};
});
@ -133,11 +134,20 @@ Storage.prototype.storeWalletAndUpdateCopayersLookup = function(wallet, cb) {
};
Storage.prototype.fetchCopayerLookup = function(copayerId, cb) {
this.db.collection(collections.COPAYERS_LOOKUP).findOne({
copayerId: copayerId
}, function(err, result) {
if (err) return cb(err);
if (!result) return cb();
if (!result.requestPubKeys) {
result.requestPubKeys = [{
key: result.requestPubKey,
signature: result.signature,
}];
}
return cb(null, result);
});
};

View File

@ -1405,7 +1405,7 @@ describe('Wallet service', function() {
});
describe.only('Multiple request Pub Keys', function() {
describe.skip('Multiple request Pub Keys', function() {
var server, wallet;
beforeEach(function(done) {
helpers.createAndJoinWallet(2, 2, function(s, w) {

View File

@ -90,6 +90,7 @@ describe('Storage', function() {
name: 'copayer ' + i,
xPubKey: 'xPubKey ' + i,
requestPubKey: 'requestPubKey ' + i,
signature: 'xxx',
});
wallet.addCopayer(copayer);
});
@ -101,7 +102,8 @@ describe('Storage', function() {
should.not.exist(err);
should.exist(lookup);
lookup.walletId.should.equal('123');
lookup.requestPubKey.should.equal('requestPubKey 1');
lookup.requestPubKeys[0].key.should.equal('requestPubKey 1');
lookup.requestPubKeys[0].signature.should.equal('xxx');
done();
})
});