diff --git a/README.md b/README.md index cc741b8..d0c8b22 100644 --- a/README.md +++ b/README.md @@ -43,11 +43,12 @@ const secio = require('libp2p-secio') The current `secio` tag, usable in `multistream`. -### `encrypt(id, key, insecure)` +### `encrypt(id, key, insecure[, callback])` - `id: PeerId` - The id of the node. - `key: RSAPrivateKey` - The private key of the node. - `insecure: PullStream` - The insecure connection. +- `callback: Function` - Called if an error happens during the initialization. Returns the `insecure` connection provided, wrapped with secio. This is a pull-stream. diff --git a/benchmarks/send.js b/benchmarks/send.js index 097655c..84b0d16 100644 --- a/benchmarks/send.js +++ b/benchmarks/send.js @@ -46,7 +46,7 @@ suite.add('createKey', function (d) { pull( pull.infinite(), pull.take(100), - pull.map((val) => Buffer(val.toString())), + pull.map((val) => new Buffer(val.toString())), local ) diff --git a/gulpfile.js b/gulpfile.js new file mode 100644 index 0000000..f0b82b6 --- /dev/null +++ b/gulpfile.js @@ -0,0 +1,43 @@ +'use strict' + +const gulp = require('gulp') +const multiaddr = require('multiaddr') +const pull = require('pull-stream') +const WS = require('libp2p-websockets') +const PeerId = require('peer-id') + +const peerNodeJSON = require('./test/peer-node.json') +const secio = require('./src') + +let listener +const ma = multiaddr('/ip4/127.0.0.1/tcp/9090/ws') + +gulp.task('test:browser:before', (done) => { + PeerId.createFromJSON(peerNodeJSON, (err, id) => { + if (err) { + throw err + } + + const ws = new WS() + listener = ws.createListener((conn) => { + const encrypted = secio.encrypt(id, id._privKey, conn, (err) => { + if (err) { + throw err + } + }) + + pull( + encrypted, + encrypted + ) + }) + + listener.listen(ma, done) + }) +}) + +gulp.task('test:browser:after', (done) => { + listener.close(done) +}) + +require('aegir/gulp')(gulp) diff --git a/package.json b/package.json index f7ce426..aa596bc 100644 --- a/package.json +++ b/package.json @@ -6,12 +6,12 @@ "scripts": { "lint": "aegir-lint", "build": "aegir-build", - "test": "aegir-test", - "test:node": "aegir-test --env node", - "test:browser": "aegir-test --env browser", - "release": "aegir-release", - "release-minor": "aegir-release --type minor", - "release-major": "aegir-release --type major", + "test": "gulp test", + "test:node": "gulp test:node", + "test:browser": "gulp test:browser", + "release": "gulp release", + "release-minor": "gulp release --type minor", + "release-major": "gulp release --type major", "coverage": "aegir-coverage", "coverage-publish": "aegir-coverage publish", "bench": "node benchmarks/send.js" @@ -26,25 +26,27 @@ "license": "MIT", "dependencies": { "async": "^2.1.2", - "debug": "^2.2.0", + "debug": "^2.3.2", "interface-connection": "^0.3.0", - "libp2p-crypto": "^0.7.0", + "libp2p-crypto": "^0.7.1", "multihashing-async": "^0.2.0", "peer-id": "^0.8.0", - "protocol-buffers": "^3.1.7", + "protocol-buffers": "^3.1.8", "pull-defer": "^0.2.2", "pull-handshake": "^1.1.4", "pull-length-prefixed": "^1.2.0", "pull-stream": "^3.5.0" }, "devDependencies": { - "aegir": "^9.0.1", + "aegir": "^9.1.1", "benchmark": "^2.1.2", "chai": "^3.5.0", + "gulp": "^3.9.1", + "libp2p-websockets": "^0.9.1", "multistream-select": "^0.13.0", "pre-commit": "^1.1.3", - "pull-pair": "^1.1.0", - "pull-pushable": "^2.0.1" + "pull-goodbye": "0.0.1", + "pull-pair": "^1.1.0" }, "pre-commit": [ "lint", @@ -67,4 +69,4 @@ "Richard Littauer ", "greenkeeperio-bot " ] -} \ No newline at end of file +} diff --git a/src/etm.js b/src/etm.js index 0880c34..2f1fb5d 100644 --- a/src/etm.js +++ b/src/etm.js @@ -10,6 +10,7 @@ const lpOpts = { exports.createBoxStream = (cipher, mac) => { return pull( + ensureBuffer(), pull.asyncMap((chunk, cb) => { cipher.encrypt(chunk, (err, data) => { if (err) { @@ -31,6 +32,7 @@ exports.createBoxStream = (cipher, mac) => { exports.createUnboxStream = (decipher, mac) => { return pull( + ensureBuffer(), lp.decode(lpOpts), pull.asyncMap((chunk, cb) => { const l = chunk.length @@ -65,3 +67,13 @@ exports.createUnboxStream = (decipher, mac) => { }) ) } + +function ensureBuffer () { + return pull.map((c) => { + if (typeof c === 'string') { + return new Buffer(c, 'utf-8') + } + + return c + }) +} diff --git a/src/index.js b/src/index.js index 4276fcf..afde604 100644 --- a/src/index.js +++ b/src/index.js @@ -23,7 +23,10 @@ module.exports = { if (!callback) { callback = (err) => { - throw err + if (err) { + console.error(err) + throw err + } } } diff --git a/test/browser.js b/test/browser.js new file mode 100644 index 0000000..ea206b5 --- /dev/null +++ b/test/browser.js @@ -0,0 +1,58 @@ +/* eslint-env mocha */ +'use strict' + +const expect = require('chai').expect +const multiaddr = require('multiaddr') +const pull = require('pull-stream') +const pullGoodbye = require('pull-goodbye') +const WS = require('libp2p-websockets') +const PeerId = require('peer-id') +const parallel = require('async/parallel') + +const peerBrowserJSON = require('./peer-browser.json') +const secio = require('../src') + +describe('secio browser <-> nodejs', () => { + const ma = multiaddr('/ip4/127.0.0.1/tcp/9090/ws') + let conn + let encryptedConn + + before((done) => { + parallel([ + (cb) => PeerId.createFromJSON(peerBrowserJSON, cb), + (cb) => { + const ws = new WS() + conn = ws.dial(ma, cb) + } + ], (err, res) => { + if (err) { + return done(err) + } + + encryptedConn = secio.encrypt(res[0], res[0]._privKey, conn) + done() + }) + }) + + it('echo', (done) => { + const message = 'Hello World!' + + const s = pullGoodbye({ + source: pull.values([message]), + sink: pull.collect((err, results) => { + expect(err).to.not.exist + expect(results).to.be.eql([message]) + done() + }) + }, 'GoodBye') + + pull( + s, + encryptedConn, + // Need to convert to a string as goodbye only understands strings + + pull.map((msg) => msg.toString()), + s + ) + }) +}) diff --git a/test/index.spec.js b/test/index.spec.js index 99d55aa..cb8171a 100644 --- a/test/index.spec.js +++ b/test/index.spec.js @@ -102,18 +102,18 @@ describe('libp2p-secio', () => { }) }) -function createSession (insecure, cb) { +function createSession (insecure, callback) { crypto.generateKeyPair('RSA', 2048, (err, key) => { if (err) { - return cb(err) + return callback(err) } key.public.hash((err, digest) => { if (err) { - return cb(err) + return callback(err) } - cb(null, secio.encrypt(new PeerId(digest, key), key, insecure)) + callback(null, secio.encrypt(new PeerId(digest, key), key, insecure)) }) }) } diff --git a/test/peer-browser.json b/test/peer-browser.json new file mode 100644 index 0000000..976c60a --- /dev/null +++ b/test/peer-browser.json @@ -0,0 +1,5 @@ +{ + "id": "QmWDLy5Q31n9TbPsoE49NjagV8uJbNbixQ4JbyB2WcnNmv", + "privKey": "CAASpwkwggSjAgEAAoIBAQCi3wtY+s70DLgeMKk7BhQq0Xmpkl1Z9YHaP+8ERM2slqPYSAnG1zaOP4iy+O0AAji+7/pIRGVYyY2oBmCM7Uo2jZZZHEAcJ0Ih4vIT7jwnqdOUrEkkiHxgVCq2+yxgY85LpiIDzJIme3Atc90roPfJi5wpgxM8Yvxwh/Jpr0it4VrNxWSQmGgxfrK9La5ezfFSs/MrU+aA8Qh+vMkRQHsBVyr30pzK1bD2l3kkg5hC48wClduoYHB1IGAOgx14Hsu+4qX/tpu7c3HXL9mPvjHsddqeKiHIs1u2kkXKw+myDyIJr/FVPHQxxpuOnA+GmPVQI5d+INLVzCV88CfzqKwpAgMBAAECggEATYj/HvHvWbFAaWbi+W1QZn3ofDhoZm4AzkSHZbHXc+UWxNyugtFrcFaAnirwsINePk+CB6s/z//LhwTaK9y+6q+Gto9DWeO6kOU4NxK/4mXviqRmAZVUGIuY9hkmrBB3Yf4JzWMy5Ez5PzocPSvZKkJjKkPzAVliMbQWTAedAuE1eq9b5Nb5MQJq/1a9RYFdFm0kYy7FgwQbMsoXc3Uv5s+TJGwXzhsUFH6MpNZGniUsS6wiwWPLjdGKebUrf/pD8Z7nwscSQBKzkyrHVBGfImOtNcgM+BwesN+WUFqyAJRvPv0SNVu+KwkVx3jEqAaIf5vxO62TNok+TuBxQP8HrQKBgQDai5dWEy08EZOyuM0MlU3fXhpUFczSrtxw1Ty4a4ma+jQitcaCnUdgA1keQhTpLYoSqE0NL8uykTC3FcRF2AQf0jTGZ94smbu5cJkWWh5NoIW2EnkSQwfPMjHGKjwKhltIbiAxlnbxmpLd3CTTx7eVXB5a5WgVih1fYOThoXzKTwKBgQC+yNLQ7FkxsCW3wRQ6ANk/6mQEYpuX6ap2TtxykvwCwuWbadufeRAZb52gbiNUgClqT7h0Kper6mBqhs7ubU55DVJMUTLKqWLQVkHdkQIoau5uXaYoX/1/bfc65BgHg61aUF93hJAYzv0NuEEX2UaLAXcpYfXe2Liv8AYvr9mcBwKBgDPDqpXdtvIqa6SCdzcKykYlAPF3tGsWteoX5+j6t744k07BZYKchEJuqJYtKszMV47xxEZiUso576L+Cd5NOzTaUlvIUGyaAUf8LpaHw/O5GNK2b2zu6ZOfHQEGEfCgQFDYnNGCBSxW44CfWy26eXZsOlhnTA8GBs0Ho076NBerAoGAV/5iFZBdFyjKTLVV8ebATNV7qfYdE3TndUesL4ARkeh4ZDTv4d7BiSnMxtjlnKy77Ve1mIaoi9c+/wMMYDW0EusNATwWNBjqBXMzT9D48NFZBThWUZrsXaDHfbcESjr2cohNb9+JYpfdaT2JcEl7WtOjNUgEUfMdQ7Bt+gKeWHMCgYEApoS8oknM4AtveP/w3YYSLSILbNMx2sYDNJ6HGDdg9ajjpTez4PS+BgqhcMkzMd/oVB7VD2n8As35LxppfHtSEPW1II/h3Phtd//HT8Wsu2L0BRoY/JIMLCbTwTSbtVr2+w9vWz7pg2Q2r0uScYadYNpMNF2uXC6vd6TFyCc17ic=", + "pubKey": "CAASpgIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCi3wtY+s70DLgeMKk7BhQq0Xmpkl1Z9YHaP+8ERM2slqPYSAnG1zaOP4iy+O0AAji+7/pIRGVYyY2oBmCM7Uo2jZZZHEAcJ0Ih4vIT7jwnqdOUrEkkiHxgVCq2+yxgY85LpiIDzJIme3Atc90roPfJi5wpgxM8Yvxwh/Jpr0it4VrNxWSQmGgxfrK9La5ezfFSs/MrU+aA8Qh+vMkRQHsBVyr30pzK1bD2l3kkg5hC48wClduoYHB1IGAOgx14Hsu+4qX/tpu7c3HXL9mPvjHsddqeKiHIs1u2kkXKw+myDyIJr/FVPHQxxpuOnA+GmPVQI5d+INLVzCV88CfzqKwpAgMBAAE=" +} diff --git a/test/peer-node.json b/test/peer-node.json new file mode 100644 index 0000000..09e1635 --- /dev/null +++ b/test/peer-node.json @@ -0,0 +1,5 @@ +{ + "id": "QmY2cwDxD3B2n1Tv9YiBKZXgKkKCkcS5r2sCJMu9oBcGBq", + "privKey": "CAASqAkwggSkAgEAAoIBAQCfBFkPbclTBzE4W4hhuteYrK4qR3eQnfbwfR1LUPdNmZKZxnTuQmL86ZCQCBzolqbJVFWb+phs2y3+0jCt/pdwSAjWIO8A9PJBcavJzYhi9JLLg8wl96xIHqHHQ8JsD8np1RLOYFQ1w2jNrXkDO0RQXb62+7xSoSyG4Y8UrhT/n65fv3aGlhqcYh1Tz4DV1bWdXzEOfg3R+KGmMcbJT4eC0x04gvxZXlTOmI2YMW+DunK/RN8fmt9YJqqu/f2bed+cuGsmwqfX/grDjVRjSxK2QECGYXjxU7WIZMrqBvlkBc7sWFyp3KHFU8bZYvP6a6K/dgoTbQAcz/UJswGpE9j3AgMBAAECggEAFZNFci53Lmi/aOIicwAi2Hg1eU8RDfIg2yhenSVzKHg5x9uBagJf4+jc0G4JXhVys8ZZhzxNChgC+ZwTNshgS7+6UzNMuliBthdyM4NLigGdGTfcrxoXqgFd+edbrcXGo49hadbwFgtZYO60iJe2ASF3CuTE/IEZxYM9IpUsDDKqZ8/fToLQk80XQuupiqwx4X6Yon/XTSLnNBSMA/hnhuwjJjw90DQQs+OER4ixbS7ENCFrMvV2omtwHh+bo2bfFhdyzSrV2wiRIyQiP6cOT5k7AsHkz2xzU7novNAW3D0bXDYhlBpTWEvn3yoKKkYuYptP9lyA2hcGedoVCR1wYQKBgQD1zWUdgnf3BfpYB0E3gItAEAgy1dvGny39XGvRtFZCWfykNKCyjOe48lXntNAjQq22Leo4U4LQWb/PWkYlO3mm2Zt1Posyx6lBbFS6h+5dCFDPbC7zvf1QD5kyAtS93Xds8gX4YWQVd0jj3ov7f3FghlTjnc6udTPD1oWiaekeqwKBgQClnTo+WHf9ZPQtZzBNht/rqEYA1p6KiedsAR1cXYMhernafLQ5FnT4czp3gZTcnEAsTfBg4mp3j+dqxmN/YpPI6hRMQlbsi7Zv3ro7FivTUHBYdWC2OHu+fDbpqras8s6nRBilKzkcaMf5WPw+fQpcr+zor4fFM01oGxfBClo+5QKBgQAI6kc1l8rUGdJnqPOzmKT0UOCLP3h2LsXTP6vlcj4CsBLavdHqR/QLoDZ/be5yqPN1/RpWqqi+99JeKe8LYKnb5F6gFQGleNpptg0oqs95bljH/SuCyaxLYBV1W+btb//p4qlWxemEYcwx/5tiJtAs6RJhIxMg/r0+6CP2rRK4ewKBgQCWNPQOd87cVCPiyiRVLG8LHaPgPsesf0cV/izTCT1VsCnAsDoFTQjqDhiJK04IiO7rQAU02iYWKr6JaUX000OWhjfCsqiEAnOFI01lKca18c7zbAI7Qx94tNBZPixQ0Cf+LRTtOTajPaWh0cN2KZKsXiNRJ2LMyKr8MRZqTylqwQKBgCb6022/mnnJQQue3NpgOnm9hSnnmm+zNU74DhQbzf5Uod+hzlpQsQnH7q935KAZj7VQGxkb0w4ctwyggoQnljCtuT+8kNLmZd5bFmx9JfY5uqzhvOueC/AKJdQ0S61NVs5YqEUrmLPRvSG5TXH3swWcHt7ofOgTsdZTKPqduj5x", + "pubKey": "CAASpgIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCfBFkPbclTBzE4W4hhuteYrK4qR3eQnfbwfR1LUPdNmZKZxnTuQmL86ZCQCBzolqbJVFWb+phs2y3+0jCt/pdwSAjWIO8A9PJBcavJzYhi9JLLg8wl96xIHqHHQ8JsD8np1RLOYFQ1w2jNrXkDO0RQXb62+7xSoSyG4Y8UrhT/n65fv3aGlhqcYh1Tz4DV1bWdXzEOfg3R+KGmMcbJT4eC0x04gvxZXlTOmI2YMW+DunK/RN8fmt9YJqqu/f2bed+cuGsmwqfX/grDjVRjSxK2QECGYXjxU7WIZMrqBvlkBc7sWFyp3KHFU8bZYvP6a6K/dgoTbQAcz/UJswGpE9j3AgMBAAE=" +}