From 1d11adf294433b1cf9a3376806d52fe6e1aea0bd Mon Sep 17 00:00:00 2001 From: Ev Bogue Date: Tue, 3 Sep 2019 11:30:06 -0500 Subject: first stab at secure bogbook (sbb) --- bog.js | 87 ++++++++++++++++++++++++++++++++++++++++++----------- gossip.js | 89 ++++++++++--------------------------------------------- index.html | 1 + package-lock.json | 17 ++++++++++- package.json | 1 + server.js | 86 +++++++++-------------------------------------------- views.js | 6 ---- 7 files changed, 116 insertions(+), 171 deletions(-) diff --git a/bog.js b/bog.js index e767243..2c1c977 100644 --- a/bog.js +++ b/bog.js @@ -1,3 +1,12 @@ + +// so bog.js works in node.js and the browser +if ((typeof process !== 'undefined') && (process.release.name === 'node')) { + var fs = require('fs') + var nacl = require('tweetnacl') + nacl.util = require('tweetnacl-util') + var ed2curve = require('ed2curve') +} + // bog.open -- opens a signature and returns content if you pass a signature and a public key // EX: open(msg).then(content => { console.log(content) }) @@ -15,29 +24,64 @@ async function open (msg) { // bog.keys -- gets your public/private keypair, generates one if there is none // EX: keys().then(key => { console.log(key)}) -async function keys (key) { - var keypair = await localforage.getItem('id') - if (keypair != null) { - return keypair - } else { + +function generatekey () { + var keypair = { + publicKey : '@/' + } + console.log('generating new keypair') + while (keypair.publicKey.includes('/')) { var genkey = nacl.sign.keyPair() - var keypair = { - publicKey: '@' + nacl.util.encodeBase64(genkey.publicKey), - privateKey: nacl.util.encodeBase64(genkey.secretKey) - } - if (keypair.publicKey.includes('/')) { - console.log('TRYING AGAIN') - setTimeout(function () { - location.reload() - }, 10) + keypair.publicKey = '@' + nacl.util.encodeBase64(genkey.publicKey), + keypair.privateKey = nacl.util.encodeBase64(genkey.secretKey) + } + return keypair +} + +async function keys () { + try { + if (fs) { + var keypair = JSON.parse(fs.readFileSync(__dirname + '/keypair')) } else { - localforage.setItem('id', keypair) + var keypair = await localforage.getItem('id') + if (keypair === null) { + var keypair = generatekey() + localforage.setItem('id', keypair) + } + } + } catch (err) { + var keypair = generatekey() + if (fs) { + fs.writeFileSync(__dirname + '/keypair', JSON.stringify(keypair), 'UTF-8') } - - return keypair } + return keypair +} + +// bog.box -- encrypts a message to a pubkey + +async function box (msg, recp, keys) { + var nonce = nacl.randomBytes(nacl.box.nonceLength) + var message = nacl.util.decodeUTF8(msg) + var encrypted = nacl.box(message, nonce, ed2curve.convertPublicKey(nacl.util.decodeBase64(recp.substring(1))), ed2curve.convertSecretKey(nacl.util.decodeBase64(keys.privateKey))) + var nonceMsg = nacl.util.encodeBase64(nonce) + nacl.util.encodeBase64(encrypted) + return nonceMsg } +//bog.unbox -- decrypts a message sent to our pubkey +async function unbox (boxed, sender, keys) { + console.log(sender) + console.log(keys.privateKey) + console.log(boxed) + var nonceMsg = nacl.util.decodeBase64(boxed) + var nonce = nonceMsg.slice(0, nacl.box.nonceLength) + var msg = nonceMsg.slice(nacl.box.nonceLength, nonceMsg.length) + //var message = nacl.box.open(msg, nonce, ed2curve.convertPublicKey(sender.substring(1)), ed2curve.convertSecretKey(nacl.util.decodeBase64(keys.privateKey))) + var message = nacl.box.open(msg, nonce, ed2curve.convertPublicKey(nacl.util.decodeBase64(sender.substring(1))), ed2curve.convertSecretKey(nacl.util.decodeBase64(keys.privateKey))) + return message +} + + // bog.get -- iterates over log and returns a post. // EX: get('%x5T7KZ5haR2F59ynUuCggwEdFXlLHEtFoBQIyKYppZYerq9oMoIqH76YzXQpw2DnYiM0ugEjePXv61g3E4l/Gw==').then(msg => { console.log(msg)}) @@ -216,4 +260,11 @@ async function publish (post, keys, preview) { } } - +if ((typeof process !== 'undefined') && (process.release.name === 'node')) { + module.exports = { + keys, + open, + box, + unbox + } +} diff --git a/gossip.js b/gossip.js index afe6256..25600b5 100644 --- a/gossip.js +++ b/gossip.js @@ -7,7 +7,7 @@ function sync (subs, keys) { console.log(servers) wsServers = servers } else { - servers = ['ws://localhost:8080/', 'ws://bogbook.com/'] + servers = ['ws://localhost:8080/~@OXJ7Ma1eu8HOEakF+TW9yk1k09FbOqUSyMVneXWdLaM='] localforage.setItem('pubs', servers) console.log(servers) wsServers = servers @@ -17,92 +17,33 @@ function sync (subs, keys) { wsServers.forEach(function (server, index) { setTimeout(function () { console.log('SYNCING WITH: ' + server + ' to fetch ' + sub) - var ws = new WebSocket(server + sub) + var split = server.split('~') + var serverurl = split[0] + var serverpub = split[1] + var ws = new WebSocket(serverurl) bog(sub).then(srclog => { if (srclog) { open(srclog[0]).then(msg => { - console.log(msg) - var req = { - src: sub, - seq: msg.seq - } ws.onopen = function () { - ws.send(JSON.stringify(req)) + var message = JSON.stringify(msg) + // if we have a log then send the latest log and see if we get anything back + box(message, serverpub, keys).then(boxed => { + var obj = { + requester: keys.publicKey, + box: boxed + } + ws.send(JSON.stringify(obj)) + }) } ws.onmessage = function (message) { - var serverMsg = JSON.parse(message.data) - if (msg.seq === serverMsg.seq) { - } else if (msg.seq > serverMsg.seq) { - var diff = msg.seq - serverMsg.seq - var sendlog = srclog.slice(0, diff) - var send = { - src: sub, - log: sendlog - //requester: keys.publicKey - } - ws.send(JSON.stringify(send)) - } else { - if (serverMsg.log) { - var scroller = document.getElementById('scroller') - var logFromServer = JSON.parse(message.data) - newlog = logFromServer.log - - bog().then(log => { - for (var i = newlog.length; i-- > 0; ) { - var pubkey = nacl.util.decodeBase64(newlog[i].author.substring(1)) - var sig = nacl.util.decodeBase64(newlog[i].signature) - var opened = JSON.parse(nacl.util.encodeUTF8(nacl.sign.open(sig, pubkey))) - log.unshift(opened) - opened.key = newlog[i].key - scroller.insertBefore(render(opened, keys), scroller.childNodes[2]) - - if (i === 0) { - console.log('saved log') - log.sort((a, b) => a.timestamp - b.timestamp) - localforage.setItem(sub, newlog.concat(srclog)) - localforage.setItem('log', log.reverse()) - } - } - }) - } - } } }) } else if (srclog === null) { - var req = { - src: sub, - seq: null - } - ws.onopen = function () { - ws.send(JSON.stringify(req)) + console.log('NO LOG IN CLIENT') } ws.onmessage = function (message) { - var openedlog = [] - var scroller = document.getElementById('scroller') - var logFromServer = JSON.parse(message.data) - log = logFromServer.log - - localforage.setItem(sub, log) - - for (var i = log.length; i-- > 0; ) { - console.log(log[i]) - var pubkey = nacl.util.decodeBase64(log[i].author.substring(1)) - var sig = nacl.util.decodeBase64(log[i].signature) - var opened = JSON.parse(nacl.util.encodeUTF8(nacl.sign.open(sig, pubkey))) - console.log(opened) - opened.key = log[i].key - openedlog.push(opened) - scroller.insertBefore(render(opened, keys), scroller.childNodes[2]) - } - - bog().then(log => { - var newlog = openedlog.concat(log) - newlog.sort((a, b) => a.timestamp - b.timestamp) - localforage.setItem('log', newlog.reverse()) - }) - } } }) diff --git a/index.html b/index.html index 6a30f2f..a6f0fd9 100644 --- a/index.html +++ b/index.html @@ -9,6 +9,7 @@ + diff --git a/package-lock.json b/package-lock.json index c483e84..c2de81e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "bogbook", - "version": "1.3.0", + "version": "1.4.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -27,6 +27,21 @@ "url-join": "^4.0.0" } }, + "ed2curve": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/ed2curve/-/ed2curve-0.2.1.tgz", + "integrity": "sha1-Iuaqo1aePE2/Tu+ilhLsMp5YGQw=", + "requires": { + "tweetnacl": "0.x.x" + }, + "dependencies": { + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + } + } + }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", diff --git a/package.json b/package.json index 0cc0d4f..7d83efc 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "license": "MIT", "dependencies": { "ecstatic": "^4.1.2", + "ed2curve": "^0.2.1", "open": "^6.2.0", "tweetnacl": "^1.0.1", "tweetnacl-util": "^0.15.0", diff --git a/server.js b/server.js index f2a7e0d..5cb2fd6 100644 --- a/server.js +++ b/server.js @@ -12,81 +12,23 @@ open('http://localhost:8089') // ws server (8080) -var WebSocket = require('ws') +var bog = require('./bog') +var WS = require('ws') var fs = require('fs') var nacl = require('tweetnacl') nacl.util = require('tweetnacl-util') -var wserver = new WebSocket.Server({ port: 8080 }) - -wserver.on('connection', function (ws) { - ws.on('message', function (message) { - var req = JSON.parse(message) - if (req.seq) { - if (fs.existsSync(__dirname + '/bogs/' + req.src)) { - fs.readFile(__dirname + '/bogs/' + req.src, 'UTF-8', function (err, data) { - if (data) { - var log = JSON.parse(data) - var pubkey = nacl.util.decodeBase64(req.src.substring(1)) - var sig = nacl.util.decodeBase64(log[0].signature) - var opened = JSON.parse(nacl.util.encodeUTF8(nacl.sign.open(sig, pubkey))) - - var res = { - feed: req.src, - seq: opened.seq - } - ws.send(JSON.stringify(res)) - if(res.seq > req.seq) { - console.log('Sending diff of' + req.src /*+ ' to ' + req.requester*/) - var diff = res.seq - req.seq - var sendlog = log.slice(0, diff) - var send = { - src: req.src, - log: sendlog - } - ws.send(JSON.stringify(send)) - } - } - }) - } else { - var res = { - feed: req.src, - seq: null - } - ws.send(JSON.stringify(res)) - } - } else if (req.seq === null) { - if (fs.existsSync(__dirname + '/bogs/' + req.src)) { - fs.readFile(__dirname + '/bogs/' + req.src, 'UTF-8', function (err, data) { - var log = JSON.parse(data) - var res = { - src: req.src, - log - } - console.log('Sending full log of ' + req.src /*+ ' to ' + req.requester*/ ) - ws.send(JSON.stringify(res)) - }) - } - } - if (req.log) { - if (fs.existsSync(__dirname + '/bogs/' + req.src)) { - fs.readFile(__dirname + '/bogs/' + req.src, 'UTF-8', function (err, data) { - var serverlog = JSON.parse(data) - - var newlog = req.log.concat(serverlog) - - fs.writeFile(__dirname + '/bogs/' + req.src, JSON.stringify(newlog), 'UTF-8', function (err, success) { - console.log('Appending diff of ' + req.src /*+ ' from ' + req.requester + ' and saved to server'*/) - }) - - }) - } else { - fs.writeFile(__dirname + '/bogs/' + req.src, JSON.stringify(req.log), 'UTF-8', function (err, success) { - if (err) throw err - else - console.log('Saved new log of ' + req.src /*+ ' that was sent from ' + req.requester */) - }) - } - } +var wserve = new WS.Server({ port: 8080 }) + +bog.keys().then(key => { + wserve.on('connection', function (ws) { + ws.on('message', function (message) { + var req = JSON.parse(message) + console.log(message) + bog.unbox(req.box, req.requester, key).then(unboxed => { + console.log(nacl.util.encodeUTF8(unboxed)) + }) + }) }) }) + diff --git a/views.js b/views.js index 7c03c2c..b7865e0 100644 --- a/views.js +++ b/views.js @@ -85,12 +85,6 @@ function profilePage (src, keys) { } }) - /*profile.appendChild(h('button', { - onclick: function () { - sync(src, keys) - } - }, ['Sync feed']))*/ - profile.appendChild(h('button', { onclick: function () { localforage.removeItem(src).then(function () { -- cgit v1.2.3-70-g09d2