From 18c73ad282e0d49aeb9268f6a59ba50ca3faf3ee Mon Sep 17 00:00:00 2001 From: ansuz Date: Wed, 28 Apr 2021 11:16:55 +0530 Subject: [PATCH] WIP working password change with restricted registration --- lib/commands/block.js | 56 +++++++++++++++++++++------------ www/common/cryptpad-common.js | 2 +- www/common/outer/login-block.js | 28 ++++++----------- www/common/pinpad.js | 2 +- 4 files changed, 47 insertions(+), 41 deletions(-) diff --git a/lib/commands/block.js b/lib/commands/block.js index d3a4a5437..a398359d2 100644 --- a/lib/commands/block.js +++ b/lib/commands/block.js @@ -86,20 +86,37 @@ var createLoginBlockPath = function (Env, publicKey) { // FIXME BLOCKS return Path.join(Env.paths.block, safeKey.slice(0, 2), safeKey); }; -var validateAncestorProof = function (Env, proof, newPubKey, cb) { -/* prove that you own an existing block by signing for its publicKey - -we will need: - -1. the publicKey -2. for the old key's block to exist - * path = createLoginBlockPath(Env, oldPublicKey) - * path && FS.readFile(path, err => { !err }) -3. a message signed with that publicKey - -*/ - - cb("E_RESTRICTED"); +var validateAncestorProof = function (Env, proof, _cb) { + var cb = Util.once(Util.mkAsync(_cb)); +/* prove that you own an existing block by signing for its publicKey */ + try { + var parsed = JSON.parse(proof); + var pub = parsed[0]; + var u8_pub = Nacl.util.decodeBase64(pub); + var sig = parsed[1]; + var u8_sig = Nacl.util.decodeBase64(sig); + var valid = false; + nThen(function (w) { + // XXX restricted-registration do this in a worker + valid = Nacl.sign.detached.verify(u8_pub, u8_sig, u8_pub); + if (!valid) { + w.abort(); + return void cb('E_INVALID_ANCESTOR_PROOF'); + } + // else fall through to next step + }).nThen(function (w) { + var path = createLoginBlockPath(Env, pub); + Fs.access(path, Fs.constants.F_OK, w(function (err) { + if (!err) { return; } + w.abort(); // else + return void cb("E_MISSING_ANCESTOR"); + })); + }).nThen(function () { + cb(void 0, valid); + }); + } catch (err) { + return void cb(err); + } }; Block.writeLoginBlock = function (Env, safeKey, msg, _cb) { // FIXME BLOCKS @@ -119,14 +136,13 @@ Block.writeLoginBlock = function (Env, safeKey, msg, _cb) { // FIXME BLOCKS w.abort(); return cb("E_RESTRICTED"); } - -// TODO check that the provided proof was valid -// XXX restricted-registration check whether proof of an existing block was provided - validateAncestorProof(Env, void 0, w(function (err) { - if (err) { + validateAncestorProof(Env, registrationProof, w(function (err, validated) { + if (err || !validated) { // double check that it was validated w.abort(); - cb(err); + // XXX Log + return void cb("E_RESTRICTED"); // XXX restricted-registration we can provide more descriptive errors if we check that the client will understand them } + // else fall through to the next block })); }).nThen(function (w) { validateLoginBlock(Env, publicKey, signature, block, w(function (e, _validatedBlock) { diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index 6a5a66047..0da28a2bc 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -1857,7 +1857,7 @@ define([ var content = Block.serialize(JSON.stringify(temp), blockKeys); console.error("OLD AND NEW BLOCK KEYS", oldBlockKeys, blockKeys); // XXX ignored unless restricted registration is active? - // content.registrationProof = Block.proveAncestor(); + content.registrationProof = Block.proveAncestor(oldBlockKeys); console.log("writing new login block"); common.writeLoginBlock(content, waitFor(function (obj) { diff --git a/www/common/outer/login-block.js b/www/common/outer/login-block.js index 46f5158af..e181dbf3f 100644 --- a/www/common/outer/login-block.js +++ b/www/common/outer/login-block.js @@ -88,26 +88,16 @@ define([ Block.proveAncestor = function (O /* oldBlockKeys */, N /* newBlockKeys */) { N = N; -/* - var registrationProof; - var registrationSig; - if (keys.previous) { - // XXX restricted-registration - // sign the publicKey of the new key with the old key - - // your existing block's publicKey - // the new block's publicKey - // some proof of recency to prevent replays? - // a signature of the whole thing - - // registrationProof = [oldPublicKey, newPublicKey]; - // registrationSig = sign(registrationProof, oldPrivateKey); + var u8_pub = Util.find(O, ['sign', 'publicKey']); + var u8_secret = Util.find(O, ['sign', 'secretKey']); + try { + // sign your old publicKey with your old privateKey + var u8_sig = Nacl.sign.detached(u8_pub, u8_secret); + // return an array with the sig and the pubkey + return JSON.stringify([u8_pub, u8_sig].map(Nacl.util.encodeBase64)); + } catch (err) { + throw err; // XXX restricted-registration } -*/ - -// needed for password change with restricted registration -//registrationProof: registrationProof? Nacl.util.encodeBase64(registrationProof): undefined, -//registrationSig: registrationSig? Nacl.util.encode }; Block.remove = function (keys) { diff --git a/www/common/pinpad.js b/www/common/pinpad.js index e1dad6488..7e9cd4ee2 100644 --- a/www/common/pinpad.js +++ b/www/common/pinpad.js @@ -226,7 +226,7 @@ var factory = function (Util, Rpc) { console.log(data); return void cb("MISSING_PARAMETERS"); } - if (['string', 'undefined'].indexOf(typeof(data.registrationProof)) !== -1) { + if (['string', 'undefined'].indexOf(typeof(data.registrationProof)) === -1) { return void cb("INVALID_REGISTRATION_PROOF"); }