verify old user password before proceeding to change passwords

This commit is contained in:
ansuz 2018-06-22 15:34:50 +02:00
parent e03b9fe630
commit 01614c4256
5 changed files with 79 additions and 59 deletions

View file

@ -46,9 +46,12 @@ define([
// 32 more for a signing key
var edSeed = opt.edSeed = dispense(32);
// 32 more bytes to seed an additional signing key
// 64 more bytes to seed an additional signing key
opt.blockSeed = dispense(64);
var blockKeys = opt.blockKeys = Block.genkeys(opt.blockSeed);
opt.blockHash = Block.getBlockHash(blockKeys);
// derive a private key from the ed seed
var signingKeypair = Nacl.sign.keyPair.fromSeed(new Uint8Array(edSeed));

View file

@ -10,9 +10,10 @@ define([
'/common/wire.js',
'/common/flat-dom.js',
'/common/media-tag.js',
'/common/outer/login-block.js',
'/bower_components/tweetnacl/nacl-fast.min.js',
], function ($, Hyperjson, Sortify, Drive, Test, Hash, Util, Thumb, Wire, Flat, MediaTag) {
], function ($, Hyperjson, Sortify, Drive, Test, Hash, Util, Thumb, Wire, Flat, MediaTag, Block) {
window.Hyperjson = Hyperjson;
window.Sortify = Sortify;
var Nacl = window.nacl;
@ -300,15 +301,12 @@ define([
}, "test support for ugly tracking query paramaters in url");
assert(function (cb) {
var href = 'https://cryptpad.fr/block/pe/pewpewpewpewpew';
var key = Nacl.randomBytes(32);
var keys = Block.genkeys(Nacl.randomBytes(64));
var hash = Block.getBlockHash(keys);
var parsed = Block.parseBlockHash(hash);
var hash = Hash.createBlockHash(href, key);
var parsed = Hash.parseBlockHash(hash);
cb(parsed && href === parsed.href &&
parsed.keys.symmetric.length === key.length);
cb(parsed &&
parsed.keys.symmetric.length === keys.symmetric.length);
}, 'parse a block hash');
assert(function (cb) {

View file

@ -474,43 +474,6 @@ Version 1
'/' + curvePublic.replace(/\//g, '-') + '/';
};
// XXX consider putting Block functions in /common/outer/login-block.js
Hash.createBlockHash = function (href, key) {
if (typeof(href) !== 'string') { return; }
if (!(key instanceof Uint8Array)) { return; }
// TODO verify inputs
try { return href + '#' + Nacl.util.encodeBase64(key); }
catch (e) { return; }
};
var decodeSafeB64 = function (b64) {
try {
return Nacl.util.decodeBase64(b64.replace(/\-/g, '/'));
} catch (e) {
console.error(e);
return;
}
};
Hash.parseBlockHash = function (hash) {
if (typeof(hash) !== 'string') { return; }
var parts = hash.split('#');
if (parts.length !== 2) { return; }
try {
return {
href: parts[0],
keys: {
symmetric: decodeSafeB64(parts[1]),
}
};
} catch (e) {
console.error(e);
return;
}
};
// Create untitled documents when no name is given
var getLocaleDate = function () {
if (window.Intl && window.Intl.DateTimeFormat) {

View file

@ -713,10 +713,9 @@ define([
var newHash, newHref, newSecret, newBlockSeed;
var oldIsOwned = false;
// XXX ansuz: check that the old password is correct
throw new Error("XXX");
var blockHash = LocalStore.getBlockHash();
var oldBlockKeys;
var Cred, Block, Login;
Nthen(function (waitFor) {
require([
@ -728,6 +727,30 @@ define([
Block = _Block;
Login = _Login;
}));
}).nThen(function (waitFor) {
// confirm that the provided password is correct
Cred.deriveFromPassphrase(accountName, password, Login.requiredBytes, waitFor(function (bytes) {
var allocated = Login.allocateBytes(bytes);
oldBlockKeys = allocated.blockKeys;
if (blockHash) {
if (blockHash !== allocated.blockHash) {
// incorrect password probably
waitFor.abort();
return void cb({
error: 'INVALID_PASSWORD',
});
}
// the user has already created a block, so you should compare against that
} else {
// otherwise they're a legacy user, and we should check against the User_hash
if (hash !== allocated.userHash) {
waitFor.abort();
return void cb({
error: 'INVALID_PASSWORD',
});
}
}
}));
}).nThen(function (waitFor) {
// Check if our drive is already owned
common.anonRpcMsg('GET_METADATA', secret.channel, waitFor(function (err, obj) {
@ -789,7 +812,7 @@ define([
}).nThen(function (waitFor) {
// Remove block hash
if (blockHash) {
var removeData = Block.remove(keys);
var removeData = Block.remove(oldBlockKeys);
common.removeLoginBlock(removeData, waitFor(function (obj) {
if (obj && obj.error) { return void console.error(obj.error); }
}));
@ -1051,13 +1074,6 @@ define([
}));
}
}).nThen(function (waitFor) {
// XXX debugging
if (LocalStore.getUserHash()) {
console.log('User_hash detected');
} else {
console.log("User_hash not detected");
}
var cfg = {
init: true,
//query: onMessage, // TODO temporary, will be replaced by a webworker channel

View file

@ -104,10 +104,50 @@ define([
Block.getBlockHash = function (keys) {
var publicKey = urlSafeB64(keys.sign.publicKey);
var relative = 'block/' + publicKey.slice(0, 2) + '/' + publicKey; // XXX FIXME use configurable path from /api/config
// 'block/' here is hardcoded because it's hardcoded on the server
// if we want to make CryptPad work in server subfolders, we'll need
// to update this path derivation
var relative = 'block/' + publicKey.slice(0, 2) + '/' + publicKey;
var symmetric = urlSafeB64(keys.symmetric);
return ApiConfig.httpUnsafeOrigin + relative + '#' + symmetric;
};
/*
Block.createBlockHash = function (href, key) {
if (typeof(href) !== 'string') { return; }
if (!(key instanceof Uint8Array)) { return; }
try { return href + '#' + Nacl.util.encodeBase64(key); }
catch (e) { return; }
};
*/
var decodeSafeB64 = function (b64) {
try {
return Nacl.util.decodeBase64(b64.replace(/\-/g, '/'));
} catch (e) {
console.error(e);
return;
}
};
Block.parseBlockHash = function (hash) {
if (typeof(hash) !== 'string') { return; }
var parts = hash.split('#');
if (parts.length !== 2) { return; }
try {
return {
href: parts[0],
keys: {
symmetric: decodeSafeB64(parts[1]),
}
};
} catch (e) {
console.error(e);
return;
}
};
return Block;
});