clientside implementation of block signing and encryption
This commit is contained in:
parent
0365092aaf
commit
577dea4c75
1
.gitignore
vendored
1
.gitignore
vendored
@ -14,5 +14,6 @@ data
|
|||||||
npm-debug.log
|
npm-debug.log
|
||||||
pins/
|
pins/
|
||||||
blob/
|
blob/
|
||||||
|
block/
|
||||||
blobstage/
|
blobstage/
|
||||||
privileged.conf
|
privileged.conf
|
||||||
|
|||||||
@ -105,7 +105,7 @@ define([
|
|||||||
return void cb('PASS_TOO_SHORT');
|
return void cb('PASS_TOO_SHORT');
|
||||||
}
|
}
|
||||||
|
|
||||||
Cred.deriveFromPassphrase(uname, passwd, 128, function (bytes) {
|
Cred.deriveFromPassphrase(uname, passwd, 192, function (bytes) {
|
||||||
// results...
|
// results...
|
||||||
var res = {
|
var res = {
|
||||||
register: isRegister,
|
register: isRegister,
|
||||||
|
|||||||
12
rpc.js
12
rpc.js
@ -1342,7 +1342,6 @@ var validateLoginBlock = function (Env, publicKey, signature, block, cb) {
|
|||||||
try {
|
try {
|
||||||
u8_block = Nacl.util.decodeBase64(block);
|
u8_block = Nacl.util.decodeBase64(block);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// TODO print to console
|
|
||||||
return void cb('E_INVALID_BLOCK');
|
return void cb('E_INVALID_BLOCK');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1432,8 +1431,6 @@ var writeLoginBlock = function (Env, msg, cb) {
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
var removeLoginBlock = function (Env, msg, cb) {
|
var removeLoginBlock = function (Env, msg, cb) {
|
||||||
console.log(msg); // XXX
|
|
||||||
|
|
||||||
var publicKey = msg[0];
|
var publicKey = msg[0];
|
||||||
var signature = msg[1];
|
var signature = msg[1];
|
||||||
var block = Nacl.util.decodeUTF8('DELETE_BLOCK'); // clients and the server will have to agree on this constant
|
var block = Nacl.util.decodeUTF8('DELETE_BLOCK'); // clients and the server will have to agree on this constant
|
||||||
@ -1854,9 +1851,12 @@ RPC.create = function (
|
|||||||
Respond(e);
|
Respond(e);
|
||||||
});
|
});
|
||||||
case 'WRITE_LOGIN_BLOCK':
|
case 'WRITE_LOGIN_BLOCK':
|
||||||
return void writeLoginBlock(Env, msg, function (e) {
|
return void writeLoginBlock(Env, msg[1], function (e) {
|
||||||
// TODO handle response
|
if (e) {
|
||||||
e = e;
|
WARN(e, 'WRITE_LOGIN_BLOCK');
|
||||||
|
return void Respond(e);
|
||||||
|
}
|
||||||
|
Respond(e);
|
||||||
});
|
});
|
||||||
case 'REMOVE_LOGIN_BLOCK':
|
case 'REMOVE_LOGIN_BLOCK':
|
||||||
return void removeLoginBlock(Env, msg, function (e) {
|
return void removeLoginBlock(Env, msg, function (e) {
|
||||||
|
|||||||
@ -83,6 +83,21 @@ define([], function () {
|
|||||||
}).join('');
|
}).join('');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// given an array of Uint8Arrays, return a new Array with all their values
|
||||||
|
Util.uint8ArrayJoin = function (AA) {
|
||||||
|
var l = 0;
|
||||||
|
var i = 0;
|
||||||
|
for (; i < AA.length; i++) { l += AA[i].length; }
|
||||||
|
var C = new Uint8Array(l);
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
for (var offset = 0; i < AA.length; i++) {
|
||||||
|
C.set(AA[i], offset);
|
||||||
|
offset += AA[i].length;
|
||||||
|
}
|
||||||
|
return C;
|
||||||
|
};
|
||||||
|
|
||||||
Util.deduplicateString = function (array) {
|
Util.deduplicateString = function (array) {
|
||||||
var a = array.slice();
|
var a = array.slice();
|
||||||
for(var i=0; i<a.length; i++) {
|
for(var i=0; i<a.length; i++) {
|
||||||
|
|||||||
79
www/common/outer/login-block.js
Normal file
79
www/common/outer/login-block.js
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
define([
|
||||||
|
'/common/common-util.js',
|
||||||
|
'/bower_components/tweetnacl/nacl-fast.min.js',
|
||||||
|
], function (Util) {
|
||||||
|
var Nacl = window.nacl;
|
||||||
|
|
||||||
|
var Block = {};
|
||||||
|
|
||||||
|
Block.join = Util.uint8ArrayJoin;
|
||||||
|
|
||||||
|
// publickey <base64 string>
|
||||||
|
|
||||||
|
// signature <base64 string>
|
||||||
|
|
||||||
|
// block <base64 string>
|
||||||
|
|
||||||
|
// [b64_public, b64_sig, b64_block [version, nonce, content]]
|
||||||
|
|
||||||
|
Block.seed = function () {
|
||||||
|
return Nacl.hash(Nacl.util.decodeUTF8('pewpewpew'));
|
||||||
|
};
|
||||||
|
|
||||||
|
// should be deterministic from a seed...
|
||||||
|
Block.genkeys = function (seed) {
|
||||||
|
if (!seed || typeof(seed.length) !== 'number' || seed.length < 64) {
|
||||||
|
throw new Error('INVALID_SEED_LENGTH');
|
||||||
|
}
|
||||||
|
|
||||||
|
var signSeed = seed.subarray(0, Nacl.sign.seedLength);
|
||||||
|
var symmetric = seed.subarray(Nacl.sign.seedLength,
|
||||||
|
Nacl.sign.seedLength + Nacl.secretbox.keyLength);
|
||||||
|
|
||||||
|
return {
|
||||||
|
sign: Nacl.sign.keyPair.fromSeed(signSeed), // 32 bytes
|
||||||
|
symmetric: symmetric,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// (UTF8 content, keys object) => Uint8Array block
|
||||||
|
Block.encrypt = function (version, content, keys) {
|
||||||
|
var u8 = Nacl.util.decodeUTF8(content);
|
||||||
|
var nonce = Nacl.randomBytes(Nacl.secretbox.nonceLength);
|
||||||
|
return Block.join([
|
||||||
|
[0],
|
||||||
|
nonce,
|
||||||
|
Nacl.secretbox(u8, nonce, keys.symmetric)
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
|
// (uint8Array block) => payload object
|
||||||
|
Block.decrypt = function (u8_content, keys) {
|
||||||
|
// version is currently ignored since there is only one
|
||||||
|
var nonce = u8_content.subarray(1, 1 + Nacl.secretbox.nonceLength);
|
||||||
|
var box = content.subarray(1 + Nacl.secretbox.nonceLength);
|
||||||
|
return Nacl.secretbox.open(box, nonce, keys.symmetric);
|
||||||
|
};
|
||||||
|
|
||||||
|
// (Uint8Array block) => signature
|
||||||
|
Block.sign = function (ciphertext, keys) {
|
||||||
|
return Nacl.sign.detached(Nacl.hash(ciphertext), keys.sign.secretKey);
|
||||||
|
};
|
||||||
|
|
||||||
|
Block.serialize = function (content, keys) {
|
||||||
|
// encrypt the content
|
||||||
|
var ciphertext = Block.encrypt(0, content, keys);
|
||||||
|
|
||||||
|
// generate a detached signature
|
||||||
|
var sig = Block.sign(ciphertext, keys);
|
||||||
|
|
||||||
|
// serialize {publickey, sig, ciphertext}
|
||||||
|
return {
|
||||||
|
publicKey: Nacl.util.encodeBase64(keys.sign.publicKey),
|
||||||
|
signature: Nacl.util.encodeBase64(sig),
|
||||||
|
ciphertext: Nacl.util.encodeBase64(ciphertext),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
return Block;
|
||||||
|
});
|
||||||
@ -222,7 +222,19 @@ define([
|
|||||||
};
|
};
|
||||||
|
|
||||||
exp.writeLoginBlock = function (data, cb) {
|
exp.writeLoginBlock = function (data, cb) {
|
||||||
cb();
|
if (!data) { return void cb('NO_DATA'); }
|
||||||
|
if (!data.publicKey || !data.signature || !data.ciphertext) {
|
||||||
|
console.log(data);
|
||||||
|
return void cb("MISSING_PARAMETERS");
|
||||||
|
}
|
||||||
|
|
||||||
|
rpc.send('WRITE_LOGIN_BLOCK', [
|
||||||
|
data.publicKey,
|
||||||
|
data.signature,
|
||||||
|
data.ciphertext
|
||||||
|
], function (e) {
|
||||||
|
cb(e);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
cb(e, exp);
|
cb(e, exp);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user