From d293ba4d44596d4e7a7eac89acad0c31b8671695 Mon Sep 17 00:00:00 2001 From: ansuz Date: Thu, 6 Jul 2017 09:43:55 +0200 Subject: [PATCH 1/4] add support for invite hashes --- www/common/common-hash.js | 18 +++++++++++++++++- www/common/cryptpad-common.js | 1 + 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/www/common/common-hash.js b/www/common/common-hash.js index c4f452dc7..888c0a338 100644 --- a/www/common/common-hash.js +++ b/www/common/common-hash.js @@ -54,7 +54,7 @@ Version 1 if (!hash) { return; } var parsed = {}; var hashArr = fixDuplicateSlashes(hash).split('/'); - if (['media', 'file', 'user'].indexOf(type) === -1) { + if (['media', 'file', 'user', 'invite'].indexOf(type) === -1) { parsed.type = 'pad'; if (hash.slice(0,1) !== '/' && hash.length >= 56) { // Old hash @@ -93,6 +93,16 @@ Version 1 } return parsed; } + if (['invite'].indexOf(type) !== -1) { + parsed.type = 'invite'; + if (hashArr[1] && hashArr[1] === '1') { + parsed.version = 1; + parsed.channel = hashArr[2]; + parsed.pubkey = hashArr[3].replace(/-/g, '/'); + return parsed; + } + return parsed; + } return; }; var parsePadUrl = Hash.parsePadUrl = function (href) { @@ -320,5 +330,11 @@ Version 1 return hash; }; + Hash.createInviteUrl = function (curvePublic, channel) { + channel = channel || Hash.createChannelId(); + return window.location.origin + '/invite/#/1/' + channel + + '/' + curvePublic.replace(/\//g, '-') + '/'; + }; + return Hash; }); diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index d3f081ef3..8b17db3d7 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -107,6 +107,7 @@ define([ common.findWeaker = Hash.findWeaker; common.findStronger = Hash.findStronger; common.serializeHash = Hash.serializeHash; + common.createInviteUrl = Hash.createInviteUrl; // Userlist common.createUserList = UserList.create; From df53166b3764902157dfc420aa7d16147739c56d Mon Sep 17 00:00:00 2001 From: ansuz Date: Thu, 6 Jul 2017 10:22:20 +0200 Subject: [PATCH 2/4] implement and use prototype curve encryptors --- www/common/curve.js | 23 ++++++++--------- www/invite/main.js | 60 ++++++++++++++++++++++----------------------- 2 files changed, 42 insertions(+), 41 deletions(-) diff --git a/www/common/curve.js b/www/common/curve.js index 62432a703..f0707662e 100644 --- a/www/common/curve.js +++ b/www/common/curve.js @@ -2,35 +2,36 @@ define([ '/bower_components/tweetnacl/nacl-fast.min.js', ], function () { var Nacl = window.nacl; - var Curve = {}; // nacl.box(message, nonce, theirPublicKey, mySecretKey) Curve.encrypt = function (message, theirPub, mySecret) { var buffer = Nacl.util.decodeUTF8(message); - var nonce = Nacl.randomBytes(24); - var box = Nacl.box(buffer, nonce, theirPub, mySecret); - - return [Nacl.util.encodeBase64(nonce), Nacl.util.encodeBase64(box)].join('|'); + return Nacl.util.encodeBase64(nonce) + '|' + Nacl.util.encodeBase64(box); }; // nacl.box.open(box, nonce, theirPublicKey, mySecretKey) Curve.decrypt = function (packed, theirPub, mySecret) { var unpacked = packed.split('|'); var nonce = Nacl.util.decodeBase64(unpacked[0]); - var box = Nacl.util.decodeBase64(unpacked[1]); - var message = Nacl.box.open(box, nonce, theirPub, mySecret); - return Nacl.util.encodeUTF8(message); }; - Curve.createEncryptor = function () { - console.log("PEWPEW"); - throw new Error("E_NOT_IMPL"); + Curve.createEncryptor = function (theirPublic, mySecret) { + var theirs = Nacl.util.decodeBase64(theirPublic); + var mine = Nacl.util.decodeBase64(mySecret); + return { + encrypt: function (msg) { + return Curve.encrypt(msg, theirs, mine); + }, + decrypt: function (packed) { + return Curve.decrypt(packed, theirs, mine); + } + }; }; return Curve; diff --git a/www/invite/main.js b/www/invite/main.js index 900c02e58..aa11fca16 100644 --- a/www/invite/main.js +++ b/www/invite/main.js @@ -9,24 +9,8 @@ define([ var Nacl = window.nacl; - var alice = Nacl.box.keyPair(); - var bob = Nacl.box.keyPair(); - - var packed = Curve.encrypt('pewpew', bob.publicKey, alice.secretKey); - console.log(packed); - - var message = Curve.decrypt(packed, alice.publicKey, bob.secretKey); - - console.log(message); - - Cryptpad.removeLoadingScreen(); - Cryptpad.alert(message); - - return {}; - //var Messages = Cryptpad.Messages; var onReady = function () { - if (!APP.initialized) { APP.initialized = true; } @@ -37,22 +21,42 @@ define([ var onDisconnect = function () {}; var onChange = function () {}; - var andThen = function (profileHash) { - var secret = Cryptpad.getSecrets('profile', profileHash); - var readOnly = APP.readOnly = secret.keys && !secret.keys.editKeyStr; + var andThen = function () { + var hash = window.location.hash.slice(1); + + var info = Cryptpad.parseTypeHash('invite', hash); + console.log(info); + + if (!info.pubkey) { + Cryptpad.removeLoadingScreen(); + Cryptpad.alert('invalid invite'); + return; + } + + var proxy = Cryptpad.getProxy(); + var mySecret = proxy.curvePrivate; + + var encryptor = Curve.createEncryptor(info.pubkey, mySecret); + + Cryptpad.removeLoadingScreen(); + var message = 'hello!'; + Cryptpad.alert(message); + var listmapConfig = { data: {}, - websocketURL: Cryptpad.getWebsocketURL(), - channel: secret.channel, - readOnly: readOnly, - validateKey: secret.keys.validateKey || undefined, - crypto: Crypto.createEncryptor(secret.keys), + network: Cryptpad.getNetwork(), + channel: info.channel, + readOnly: false, //undefined, + validateKey: undefined, + crypto: encryptor, userName: 'profile', logLevel: 1, }; var lm = APP.lm = Listmap.create(listmapConfig); lm.proxy.on('create', onInit) - .on('ready', onReady) + .on('ready', function () { + console.log(JSON.stringify(lm.proxy)); + }) .on('disconnect', onDisconnect) .on('change', [], onChange); }; @@ -84,11 +88,7 @@ define([ Cryptpad.ready(function () { Cryptpad.reportAppUsage(); - - if (window.location.hash) { - return void andThen(window.location.hash.slice(1)); - } + andThen(); }); }); - }); From 909e00bbc3f25803a2a9332ff8947ae1ff98f299 Mon Sep 17 00:00:00 2001 From: ansuz Date: Thu, 6 Jul 2017 10:25:43 +0200 Subject: [PATCH 3/4] create a listmap object using public key crypto --- www/common/curve-put.js | 47 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 www/common/curve-put.js diff --git a/www/common/curve-put.js b/www/common/curve-put.js new file mode 100644 index 000000000..1916e31f9 --- /dev/null +++ b/www/common/curve-put.js @@ -0,0 +1,47 @@ +define([ + '/common/curve.js', + '/bower_components/chainpad-listmap/chainpad-listmap.js', +], function (Curve, Listmap) { + var Edit = {}; + + Edit.create = function (network, channel, theirs, mine, cb) { + try { + var encryptor = Curve.createEncryptor(theirs, mine); + var lm = Listmap.create({ + network: network, + data: {}, + channel: channel, + readOnly: false, + validateKey: undefined, + crypto: encryptor, + userName: 'lol', + logLevel: 1, + }); + + var done = function () { + // TODO make this abort and disconnect the session after the + // user has finished making changes to the object, and they + // have propagated. + }; + + lm.proxy + .on('create', function () { + console.log('created'); + }) + .on('ready', function () { + console.log('ready'); + cb(lm); + }) + .on('disconnect', function () { + console.log('disconnected'); + }) + .on('change', [], function (o, n, p) { + console.log(o, n, p); + }); + } catch (e) { + console.error(e); + } + }; + + return Edit; +}); From d3bbdc27c0e2568a92688f804c2cd2e2c264af74 Mon Sep 17 00:00:00 2001 From: ansuz Date: Thu, 6 Jul 2017 10:33:31 +0200 Subject: [PATCH 4/4] lint compliance --- www/common/curve-put.js | 2 +- www/invite/main.js | 9 +-------- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/www/common/curve-put.js b/www/common/curve-put.js index 1916e31f9..a57e7ac5e 100644 --- a/www/common/curve-put.js +++ b/www/common/curve-put.js @@ -30,7 +30,7 @@ define([ }) .on('ready', function () { console.log('ready'); - cb(lm); + cb(lm, done); }) .on('disconnect', function () { console.log('disconnected'); diff --git a/www/invite/main.js b/www/invite/main.js index aa11fca16..df58db885 100644 --- a/www/invite/main.js +++ b/www/invite/main.js @@ -7,15 +7,7 @@ define([ ], function ($, Cryptpad, Listmap, Curve) { var APP = window.APP = {}; - var Nacl = window.nacl; - //var Messages = Cryptpad.Messages; - var onReady = function () { - if (!APP.initialized) { - APP.initialized = true; - } - }; - var onInit = function () {}; var onDisconnect = function () {}; @@ -55,6 +47,7 @@ define([ var lm = APP.lm = Listmap.create(listmapConfig); lm.proxy.on('create', onInit) .on('ready', function () { + APP.initialized = true; console.log(JSON.stringify(lm.proxy)); }) .on('disconnect', onDisconnect)