From cd152f122ffabe4ead9734e60552ed188895f09c Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Fri, 11 Jun 2021 17:45:47 +1000 Subject: [PATCH] chore: add secure websockets example (#930) * Add Secure WebSockets example * Make dial accept self-signed cert --- examples/package.json | 1 + examples/transports/4.js | 89 +++++++++++++++++++++++++ examples/transports/test-4.js | 33 +++++++++ examples/transports/test.js | 2 + examples/transports/test_certs/cert.pem | 32 +++++++++ examples/transports/test_certs/key.pem | 52 +++++++++++++++ package.json | 4 +- 7 files changed, 211 insertions(+), 2 deletions(-) create mode 100644 examples/transports/4.js create mode 100644 examples/transports/test-4.js create mode 100644 examples/transports/test_certs/cert.pem create mode 100644 examples/transports/test_certs/key.pem diff --git a/examples/package.json b/examples/package.json index 4bd37311..7b877b97 100644 --- a/examples/package.json +++ b/examples/package.json @@ -16,6 +16,7 @@ "which": "^2.0.1" }, "devDependencies": { + "https": "^1.0.0", "playwright": "^1.7.1" } } diff --git a/examples/transports/4.js b/examples/transports/4.js new file mode 100644 index 00000000..487315ec --- /dev/null +++ b/examples/transports/4.js @@ -0,0 +1,89 @@ +/* eslint-disable no-console */ +'use strict' + +const Libp2p = require('../..') +const TCP = require('libp2p-tcp') +const WebSockets = require('libp2p-websockets') +const { NOISE } = require('libp2p-noise') +const MPLEX = require('libp2p-mplex') + +const fs = require('fs'); +const https = require('https'); +const pipe = require('it-pipe') + +const transportKey = WebSockets.prototype[Symbol.toStringTag]; + +const httpServer = https.createServer({ + cert: fs.readFileSync('./test_certs/cert.pem'), + key: fs.readFileSync('./test_certs/key.pem'), +}); + +const createNode = async (addresses = []) => { + if (!Array.isArray(addresses)) { + addresses = [addresses] + } + + const node = await Libp2p.create({ + addresses: { + listen: addresses + }, + modules: { + transport: [WebSockets], + connEncryption: [NOISE], + streamMuxer: [MPLEX] + }, + config: { + peerDiscovery: { + // Disable autoDial as it would fail because we are using a self-signed cert. + // `dialProtocol` does not fail because we pass `rejectUnauthorized: false`. + autoDial: false + }, + transport: { + [transportKey]: { + listenerOptions: { server: httpServer }, + }, + }, + } + }) + + await node.start() + return node +} + +function printAddrs(node, number) { + console.log('node %s is listening on:', number) + node.multiaddrs.forEach((ma) => console.log(`${ma.toString()}/p2p/${node.peerId.toB58String()}`)) +} + +function print ({ stream }) { + pipe( + stream, + async function (source) { + for await (const msg of source) { + console.log(msg.toString()) + } + } + ) +} + +;(async () => { + const [node1, node2] = await Promise.all([ + createNode('/ip4/127.0.0.1/tcp/10000/wss'), + createNode([]) + ]) + + printAddrs(node1, '1') + printAddrs(node2, '2') + + node1.handle('/print', print) + node2.handle('/print', print) + + const targetAddr = `${node1.multiaddrs[0]}/p2p/${node1.peerId.toB58String()}`; + + // node 2 (Secure WebSockets) dials to node 1 (Secure Websockets) + const { stream } = await node2.dialProtocol(targetAddr, '/print', { websocket: { rejectUnauthorized: false } }) + await pipe( + ['node 2 dialed to node 1 successfully'], + stream + ) +})(); diff --git a/examples/transports/test-4.js b/examples/transports/test-4.js new file mode 100644 index 00000000..8ee6d8e3 --- /dev/null +++ b/examples/transports/test-4.js @@ -0,0 +1,33 @@ +'use strict' + +const path = require('path') +const execa = require('execa') +const pDefer = require('p-defer') +const uint8ArrayToString = require('uint8arrays/to-string') + +async function test () { + const deferNode1 = pDefer() + + process.stdout.write('4.js\n') + + const proc = execa('node', [path.join(__dirname, '4.js')], { + cwd: path.resolve(__dirname), + all: true + }) + + proc.all.on('data', async (data) => { + process.stdout.write(data) + const line = uint8ArrayToString(data) + + if (line.includes('node 2 dialed to node 1 successfully')) { + deferNode1.resolve() + } + }) + + await Promise.all([ + deferNode1.promise, + ]) + proc.kill() +} + +module.exports = test diff --git a/examples/transports/test.js b/examples/transports/test.js index 72fa27ee..8ef5d0b5 100644 --- a/examples/transports/test.js +++ b/examples/transports/test.js @@ -3,11 +3,13 @@ const test1 = require('./test-1') const test2 = require('./test-2') const test3 = require('./test-3') +const test4 = require('./test-4') async function test() { await test1() await test2() await test3() + await test4() } module.exports = test diff --git a/examples/transports/test_certs/cert.pem b/examples/transports/test_certs/cert.pem new file mode 100644 index 00000000..0574192b --- /dev/null +++ b/examples/transports/test_certs/cert.pem @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFlzCCA3+gAwIBAgIUMYedwb9L/BtvZ7Lhu71iSKrXsa4wDQYJKoZIhvcNAQEL +BQAwajELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAlZBMREwDwYDVQQHDAhTb21lQ2l0 +eTESMBAGA1UECgwJTXlDb21wYW55MRMwEQYDVQQLDApNeURpdmlzaW9uMRIwEAYD +VQQDDAkxMjcuMC4wLjEwHhcNMjEwNDI4MDIzMjA5WhcNMjIwNDI4MDIzMjA5WjBq +MQswCQYDVQQGEwJVUzELMAkGA1UECAwCVkExETAPBgNVBAcMCFNvbWVDaXR5MRIw +EAYDVQQKDAlNeUNvbXBhbnkxEzARBgNVBAsMCk15RGl2aXNpb24xEjAQBgNVBAMM +CTEyNy4wLjAuMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANNhXBu0 +GH1Kzl9iaQxCxEnyyAShS5FYScdKxqpYsgJT4poLWLQBZQEFLEqbdillIlTZqMss +jWqkFL2xmjqdcnOKFEZUarntVE2hxFYYQex2Fi8MYwFj+Pvt74d02xPyfzFNFgyX +a1EakoGBwClaf3I7jW7raPudjcf4HnwQ7r/NwiO8FqHFZgLcTnwI8bk+cxDoDAqu +mhqMB5nnerqvKEyR9Fb2PoL+8PwOPJOOKTDVwLMeMJu2WLR8AU2FzOj5SVI2qsu9 +Ps5azysD8KQAMcw4y9s6do36SaMQS85fbvXBV7XBqMD34HPBUbFiCoFoaCzK9Zfb +pCXyVJMUNmw5hyq9nbjUt4Kvr/58bU2gjUKSdPf6KhBxFnDZwl+2qqPdVIb/qtwz +HExtJWq3upklXNOg3HoR6vcr1O9ReJHrzLRMEb51WP1aN/qJ2/lRskcZ4A806qwr +W67BvnOg6s3ZtxHN9v3bsyfsvC66w8PEfCnCVxugC7cUW0gtW54AU75T3ukg7X+m +vECr/+qIzNEBIxxCPgefCG/JAdJhQ5SCvoARAVPStUIWDmigDeOt7go5nKbdVIJ4 +7bbBFUhHT2mTHu30fHhRqSDcHzwE7Zz6YJIJmKq29UmzUazFnKlLU67MjLJwiDPm +fC3GyOdAWkkZE5hjtkiy+3yWoEHhaJYRI1u3AgMBAAGjNTAzMAsGA1UdDwQEAwIE +MDATBgNVHSUEDDAKBggrBgEFBQcDATAPBgNVHREECDAGhwR/AAABMA0GCSqGSIb3 +DQEBCwUAA4ICAQCx/ynu4iCQAK8VId/QQe7GqgOpFgx+6Mce9GQC6ZVEjAPgapsS +Pl+l6+11cFjHKv0+Z/iN2JgkFmNXfwJcfYI0tHbMK+0U9hgKb1eFgiIwCqb4cPOz +wMwusZ95BjIbtcEbL/+pMUpNhmjPz1fOILJZtDVq++lqJCv7t8+SoAmMVYtlcLNg +muuV/UYR3uqvnAJmjgJVWs4otDGrxCYJE48M+9L2Gm05Htpi9WL1bZaQ+fJ85m85 +daedLc6R1/ZRTIH6i73sD4rYs0bx1fCJvkbcgXtKMHEkiHuG/MzR7Pa4cJAVKCx9 +lRTgrO7Gkllt2+jp4qg0YhdNq89e0DNA5cyB9H4udRgHQOcrlVRiX9OD/Kz+F5m/ +fQwMdbnqdg3ar5DSa8Q5g3bdLbNSCcI9sjCLTkNxUC/XTWGdG03RCVIt1qvBvZHk +JaG6xGpbRZ5CN0T9eindd38JBrkPAPfgl6qhwvcqh6uVFYua+7KmF9K+mKarlmMw +6RWaw2j4sMgUyRIS6fR9vDc20SrtoNvKQM1U6+0VYs1nizfkmsqqqRODmERKbKwc +ahKJFubXfr8gz+PipAKFZbxr2EPAyoiNkx+0eM6Eedo55oP2BoGHEfXEoAonyMFM +F/xTbpFtdRYE2hwsZCk86fpbcPTmdCY8txeZ7+4Bme2d9XXsTAxF64usqQ== +-----END CERTIFICATE----- diff --git a/examples/transports/test_certs/key.pem b/examples/transports/test_certs/key.pem new file mode 100644 index 00000000..dfee3017 --- /dev/null +++ b/examples/transports/test_certs/key.pem @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +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 +xfk6H6FDZv4ao7QSrFR4hlTIz6V9/aqQkdOhsBSQyQKCAQEAzHwz4Qr5xVduGLbY +S6HV/7vHDI6Jf+3lBvqUidWa013w5yls3sZXsSckkgshRoVMszayIbystnXJMNcx +YlEDWn3iIItzHNHMKkzdOvsCETMIlvnkt6UTmK4xY+dSq4jp7Ty0N+qi8fdaCb2q +tyrYTnHHYId6bUHMBY5QZsYAaTNvYNAO96A0UaNyl42q84iTiLkJYg9SsQPad15W +7gU84Jk6rEMYdndQDvEAHpnZ1y0yA2vtySZYsbK0wj34tgTl+0/8izn7JgF4ezNH +6iQ7Z0OuDT763IrmIxBH0ZEi9YnwSYyIsr6iUYjlQIUuPFRnQYQXEdm5Xfw1pZsL +xhYoTwKCAQB9edDe4LX+0z9i4qr0iHV8H/WoyI5UD/Pc217PKkYM3+ewR9SL9D9z +TS78Sl7HgRgEmIu+MR/u5B2ePf7jkvB/oxyPwqAzJeJ72mV3Mevm27G/Ndd8lt5W +FBCGOx7ZeP4/Cv4mvPD979ix2IalDoWMSWJnpQPN+B1jGeCrUYAXQc1k/vU99gLa +8Tuu3WfBpVAsO7hAC9mu6tuLyfKVqiMOVs2aky9xLqiqW/6uIcGu+owrr+gkDDY/ +JfBSUfxYKcjtJiHOEbFGrrRe93XsngmaTz/Hv9A/QLVCuJgWEHlt4WHSc+BtAtaV +9avp6VlyVNfe4KEKW7IekrI0cmfMdXkl +-----END PRIVATE KEY----- diff --git a/package.json b/package.json index 4f8d112c..7e6cf38d 100644 --- a/package.json +++ b/package.json @@ -79,6 +79,7 @@ }, "dependencies": { "@motrix/nat-api": "^0.3.1", + "@vascosantos/moving-average": "^1.1.0", "abort-controller": "^3.0.0", "aggregate-error": "^3.1.0", "any-signal": "^2.1.1", @@ -108,7 +109,6 @@ "libp2p-utils": "^0.3.1", "mafmt": "^9.0.0", "merge-options": "^3.0.4", - "@vascosantos/moving-average": "^1.1.0", "multiaddr": "^9.0.1", "multicodec": "^3.0.1", "multihashing-async": "^2.1.2", @@ -157,7 +157,7 @@ "libp2p-noise": "^3.0.0", "libp2p-tcp": "^0.15.4", "libp2p-webrtc-star": "^0.22.2", - "libp2p-websockets": "^0.15.6", + "libp2p-websockets": "^0.15.8", "multihashes": "^4.0.2", "nock": "^13.0.3", "p-defer": "^3.0.0",