WIP ro-rw
This commit is contained in:
parent
38ae5da2f4
commit
56f5a58419
|
@ -94,9 +94,13 @@ API.prototype._tryToComplete = function(data, cb) {
|
|||
if (wallet.status != 'complete')
|
||||
return cb('Wallet Incomplete');
|
||||
|
||||
if (!Verifier.checkCopayers(wallet.copayers, data.walletPrivKey, data.xPrivKey, data.n))
|
||||
if (!Verifier.checkCopayers(wallet.copayers, data.walletPrivKey,
|
||||
data.xPrivKey, data.n)) {
|
||||
|
||||
console.log('[api.js.99]'); //TODO
|
||||
return cb(new ServerCompromisedError(
|
||||
'Copayers in the wallet could not be verified to have known the wallet secret'));
|
||||
}
|
||||
|
||||
data.publicKeyRing = _.pluck(wallet.copayers, 'xPubKey')
|
||||
|
||||
|
@ -140,8 +144,13 @@ API.prototype._doRequest = function(method, url, args, data, cb) {
|
|||
var reqSignature;
|
||||
data = data || {};
|
||||
|
||||
if (data.signingPrivKey)
|
||||
reqSignature = _signRequest(method, url, args, data.signingPrivKey);
|
||||
if (method == 'get') {
|
||||
if (data.roPrivKey)
|
||||
reqSignature = _signRequest(method, url, args, data.roPrivKey);
|
||||
} else {
|
||||
if (data.rwPrivKey)
|
||||
reqSignature = _signRequest(method, url, args, data.rwPrivKey);
|
||||
}
|
||||
|
||||
var absUrl = this.baseUrl + url;
|
||||
var args = {
|
||||
|
@ -185,8 +194,9 @@ API.prototype._doGetRequest = function(url, data, cb) {
|
|||
|
||||
API.prototype._initData = function(network, walletPrivKey, m, n) {
|
||||
var xPrivKey = new Bitcore.HDPrivateKey(network);
|
||||
var xPubKey = (new Bitcore.HDPublicKey(xPrivKey)).toString();
|
||||
var signingPrivKey = (new Bitcore.HDPrivateKey(xPrivKey)).derive('m/1/0').privateKey;
|
||||
var xPubKey = xPrivKey.toString();
|
||||
var roPrivKey = xPrivKey.derive('m/1/0').privateKey;
|
||||
var rwPrivKey = xPrivKey.derive('m/1/1').privateKey;
|
||||
var sharedEncryptingKey = Bitcore.crypto.Hash.sha256(walletPrivKey.toBuffer()).slice(0, 16).toString('base64');
|
||||
var copayerId = WalletUtils.xPubToCopayerId(xPubKey);
|
||||
|
||||
|
@ -197,7 +207,8 @@ API.prototype._initData = function(network, walletPrivKey, m, n) {
|
|||
network: network,
|
||||
m: m,
|
||||
n: n,
|
||||
signingPrivKey: signingPrivKey.toWIF(),
|
||||
roPrivKey: roPrivKey.toWIF(),
|
||||
rwPrivKey: rwPrivKey.toWIF(),
|
||||
walletPrivKey: walletPrivKey.toWIF(),
|
||||
sharedEncryptingKey: sharedEncryptingKey,
|
||||
};
|
||||
|
|
|
@ -45,6 +45,8 @@ Verifier.checkCopayers = function(copayers, walletPrivKey, myXPrivKey, n) {
|
|||
return false;
|
||||
|
||||
var myXPubKey = new Bitcore.HDPublicKey(myXPrivKey).toString();
|
||||
console.log('[verifier.js.50:copayers:]',copayers); //TODO
|
||||
console.log('[verifier.js.48:myXPubKey:]',myXPubKey); //TODO
|
||||
if (!_.contains(_.pluck(copayers, 'xPubKey'), myXPubKey)) {
|
||||
log.error('Server response does not contains our public keys')
|
||||
return false;
|
||||
|
|
|
@ -88,10 +88,13 @@ ExpressApp.start = function(opts) {
|
|||
code: 'NOTAUTHORIZED'
|
||||
}), res, req);
|
||||
|
||||
var readOnly = req.method == 'GET';
|
||||
|
||||
var auth = {
|
||||
copayerId: credentials.copayerId,
|
||||
message: req.method.toLowerCase() + '|' + req.url + '|' + JSON.stringify(req.body),
|
||||
signature: credentials.signature,
|
||||
readOnly: readOnly,
|
||||
};
|
||||
WalletService.getInstanceWithAuth(auth, function(err, server) {
|
||||
if (err) return returnError(err, res, req);
|
||||
|
|
|
@ -11,7 +11,8 @@ var AddressManager = require('./addressmanager');
|
|||
var Utils = require('../walletutils');
|
||||
|
||||
|
||||
var MESSAGE_SIGNING_PATH = "m/1/0";
|
||||
var RO_SIGNING_PATH = "m/1/0";
|
||||
var RW_SIGNING_PATH = "m/1/1";
|
||||
|
||||
function Copayer() {
|
||||
this.version = '1.0.0';
|
||||
|
@ -30,7 +31,8 @@ Copayer.create = function(opts) {
|
|||
x.id = Utils.xPubToCopayerId(x.xPubKey);
|
||||
x.name = opts.name;
|
||||
x.xPubKeySignature = opts.xPubKeySignature; // So third parties can check independently
|
||||
x.signingPubKey = x.getSigningPubKey();
|
||||
x.roPubKey = x.getROPubKey();
|
||||
x.rwPubKey = x.getRWPubKey();
|
||||
x.addressManager = AddressManager.create({
|
||||
copayerIndex: opts.copayerIndex
|
||||
});
|
||||
|
@ -46,7 +48,8 @@ Copayer.fromObj = function(obj) {
|
|||
x.name = obj.name;
|
||||
x.xPubKey = obj.xPubKey;
|
||||
x.xPubKeySignature = obj.xPubKeySignature;
|
||||
x.signingPubKey = obj.signingPubKey;
|
||||
x.roPubKey = obj.roPubKey;
|
||||
x.rwPubKey = obj.rwPubKey;
|
||||
x.addressManager = AddressManager.fromObj(obj.addressManager);
|
||||
|
||||
return x;
|
||||
|
@ -60,8 +63,14 @@ Copayer.prototype.getPublicKey = function(path) {
|
|||
.toString();
|
||||
};
|
||||
|
||||
Copayer.prototype.getSigningPubKey = function() {
|
||||
return this.getPublicKey(MESSAGE_SIGNING_PATH);
|
||||
Copayer.prototype.getROPubKey = function() {
|
||||
return this.getPublicKey(RO_SIGNING_PATH);
|
||||
};
|
||||
|
||||
Copayer.prototype.getRWPubKey = function() {
|
||||
return this.getPublicKey(RW_SIGNING_PATH);
|
||||
};
|
||||
|
||||
|
||||
|
||||
module.exports = Copayer;
|
||||
|
|
|
@ -66,7 +66,8 @@ WalletService.getInstance = function() {
|
|||
* @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 signingPubKey.
|
||||
* @param {string} opts.signature - Signature of message to be verified using the copayer's roPubKey / rwPubKey
|
||||
* @param {string} opts.readOnly - Signature of message to be verified using the copayer's roPubKey / rwPubKey
|
||||
*/
|
||||
WalletService.getInstanceWithAuth = function(opts, cb) {
|
||||
|
||||
|
@ -78,8 +79,12 @@ WalletService.getInstanceWithAuth = function(opts, cb) {
|
|||
if (err) return cb(err);
|
||||
if (!copayer) return cb(new ClientError('NOTAUTHORIZED', 'Copayer not found'));
|
||||
|
||||
var isValid = server._verifySignature(opts.message, opts.signature, copayer.signingPubKey);
|
||||
if (!isValid) return cb(new ClientError('NOTAUTHORIZED', 'Invalid signature'));
|
||||
var pubKey = opts.readOnly ? copayer.roPubKey : copayer.rwPubKey;
|
||||
var isValid = server._verifySignature(opts.message, opts.signature,
|
||||
pubKey);
|
||||
|
||||
if (!isValid)
|
||||
return cb(new ClientError('NOTAUTHORIZED', 'Invalid signature'));
|
||||
|
||||
server.copayerId = opts.copayerId;
|
||||
server.walletId = copayer.walletId;
|
||||
|
|
|
@ -84,7 +84,8 @@ Storage.prototype.storeWalletAndUpdateCopayersLookup = function(wallet, cb) {
|
|||
_.each(wallet.copayers, function(copayer) {
|
||||
var value = {
|
||||
walletId: wallet.id,
|
||||
signingPubKey: copayer.signingPubKey,
|
||||
roPubKey: copayer.roPubKey,
|
||||
rwPubKey: copayer.rwPubKey,
|
||||
};
|
||||
ops.push({
|
||||
type: 'put',
|
||||
|
|
|
@ -164,7 +164,7 @@ describe('client API ', function() {
|
|||
})
|
||||
});
|
||||
});
|
||||
it('should be able to complete wallets in copayer that joined later', function(done) {
|
||||
it.only('should be able to complete wallets in copayer that joined later', function(done) {
|
||||
helpers.createAndJoinWallet(clients, 2, 3, function(err) {
|
||||
should.not.exist(err);
|
||||
clients[0].getBalance(function(err, x) {
|
||||
|
|
Loading…
Reference in New Issue