From e0b8f3319fa048b2119c3c69ced0a0697854c49b Mon Sep 17 00:00:00 2001 From: Manuel Araoz Date: Tue, 19 Aug 2014 12:46:20 -0400 Subject: [PATCH] remove WebRTC --- js/models/network/WebRTC.js | 525 ------------------------------------ test/index.html | 2 +- test/test.network.WebRTC.js | 507 ---------------------------------- 3 files changed, 1 insertion(+), 1033 deletions(-) delete mode 100644 js/models/network/WebRTC.js delete mode 100644 test/test.network.WebRTC.js diff --git a/js/models/network/WebRTC.js b/js/models/network/WebRTC.js deleted file mode 100644 index 256bc3ec7..000000000 --- a/js/models/network/WebRTC.js +++ /dev/null @@ -1,525 +0,0 @@ -'use strict'; - -var EventEmitter = require('events').EventEmitter; -var bitcore = require('bitcore'); -var util = bitcore.util; -var nodeUtil = require('util'); -var Message = require('../core/Message'); -/* - * Emits - * 'connect' - * when network layout has change (new/lost peers, etc) - * - * 'data' - * when an unknown data type arrives - * - * Provides - * send(toPeerIds, {data}, cb?) - * - */ - -function Network(opts) { - var self = this; - opts = opts || {}; - this.apiKey = opts.apiKey || 'lwjd5qra8257b9'; - this.debug = opts.debug || 3; - this.maxPeers = opts.maxPeers || 10; - this.reconnectAttempts = opts.reconnectAttempts || 3; - this.sjclParams = opts.sjclParams || { - salt: 'f28bfb49ef70573c', - iter: 500, - mode: 'ccm', - ts: parseInt(64), - }; - this.opts = {}; - ['config', 'port', 'host', 'path', 'debug', 'key', 'secure'].forEach(function(k) { - if (opts.hasOwnProperty(k)) self.opts[k] = opts[k]; - }); - this.cleanUp(); -} - -nodeUtil.inherits(Network, EventEmitter); - -Network.prototype.cleanUp = function() { - this.started = false; - this.connectedPeers = []; - this.peerId = null; - this.privkey = null; //TODO: hide privkey in a closure - this.key = null; - this.copayerId = null; - this.allowedCopayerIds = null; - this.isInboundPeerAuth = []; - this.copayerForPeer = {}; - this.connections = {}; - this.criticalErr = ''; - if (this.peer) { - this.peer.disconnect(); - this.peer.destroy(); - this.peer.removeAllListeners(); - this.peer = null; - } - this.closing = 0; - this.tries = 0; - this.removeAllListeners(); -}; - - -// Array helpers -Network._arrayDiff = function(a, b) { - var seen = []; - var diff = []; - - for (var i = 0; i < b.length; i++) - seen[b[i]] = true; - - for (var j = 0; j < a.length; j++) - if (!seen[a[j]]) - diff.push(a[j]); - - return diff; -}; - -Network._inArray = function(el, array) { - return array.indexOf(el) > -1; -}; - -Network._arrayPushOnce = function(el, array) { - var ret = false; - if (!Network._inArray(el, array)) { - array.push(el); - ret = true; - } - return ret; -}; - -Network._arrayRemove = function(el, array) { - var pos = array.indexOf(el); - if (pos >= 0) array.splice(pos, 1); - return array; -}; - -Network.prototype.connectedCopayers = function() { - var ret = []; - for (var i in this.connectedPeers) { - var copayerId = this.copayerForPeer[this.connectedPeers[i]]; - if (copayerId) ret.push(copayerId); - } - return ret; -}; - -Network.prototype._deletePeer = function(peerId) { - - delete this.isInboundPeerAuth[peerId]; - delete this.copayerForPeer[peerId]; - - if (this.connections[peerId]) { - this.connections[peerId].close(); - } - delete this.connections[peerId]; - this.connectedPeers = Network._arrayRemove(peerId, this.connectedPeers); -}; - -Network.prototype._onClose = function(peerID) { - this._deletePeer(peerID); - this.emit('disconnect', peerID); -}; - -Network.prototype.connectToCopayers = function(copayerIds) { - var self = this; - var arrayDiff = Network._arrayDiff(copayerIds, self.connectedCopayers()); - - arrayDiff.forEach(function(copayerId) { - if (self.allowedCopayerIds && !self.allowedCopayerIds[copayerId]) { - self._deletePeer(self.peerFromCopayer(copayerId)); - } else { - self.connectTo(copayerId); - } - }); -}; - -Network.prototype._sendHello = function(copayerId) { - this.send(copayerId, { - type: 'hello', - copayerId: this.copayerId, - }); -}; - -Network.prototype._addConnectedCopayer = function(copayerId, isInbound) { - var peerId = this.peerFromCopayer(copayerId); - this._addCopayerMap(peerId, copayerId); - Network._arrayPushOnce(peerId, this.connectedPeers); - this.emit('connect', copayerId); -}; - -Network.prototype.getKey = function() { - if (!this.key) { - var key = new bitcore.Key(); - key.private = new Buffer(this.privkey, 'hex'); - key.regenerateSync(); - this.key = key; - } - return this.key; -}; - -//hex version of one's own nonce -Network.prototype.setHexNonce = function(networkNonce) { - if (networkNonce) { - if (networkNonce.length !== 16) - throw new Error('incorrect length of hex nonce'); - this.networkNonce = new Buffer(networkNonce, 'hex'); - } - else - this.iterateNonce(); -}; - -//hex version of copayers' nonces -Network.prototype.setHexNonces = function(networkNonces) { - for (var i in networkNonces) { - if (!this.networkNonces) - this.networkNonces = {}; - if (networkNonces[i].length === 16) - this.networkNonces[i] = new Buffer(networkNonces[i], 'hex'); - } -}; - -//for oneself -Network.prototype.getHexNonce = function() { - return this.networkNonce.toString('hex'); -}; - -//for copayers -Network.prototype.getHexNonces = function() { - var networkNoncesHex = []; - for (var i in this.networkNonces) { - networkNoncesHex[i] = this.networkNonces[i].toString('hex'); - } - return networkNoncesHex; -}; - -Network.prototype.iterateNonce = function() { - if (!this.networkNonce || this.networkNonce.length !== 8) { - this.networkNonce = new Buffer(8); - this.networkNonce.fill(0); - } - //the first 4 bytes of a nonce is a unix timestamp in seconds - //the second 4 bytes is just an iterated "sub" nonce - //the whole thing is interpreted as one big endian number - var noncep1 = this.networkNonce.slice(0, 4); - noncep1.writeUInt32BE(Math.floor(Date.now()/1000), 0); - var noncep2uint = this.networkNonce.slice(4, 8).readUInt32BE(0); - var noncep2 = this.networkNonce.slice(4, 8); - noncep2.writeUInt32BE(noncep2uint + 1, 0); - return this.networkNonce; -}; - -Network.prototype._onData = function(enc, isInbound, peerId) { - var encUint8Array = new Uint8Array(enc); - var encbuf = new Buffer(encUint8Array); - var encstr = encbuf.toString(); - - var privkey = this.privkey; - var key = this.getKey(); - - try { - var encoded = JSON.parse(encstr); - var prevnonce = this.networkNonces ? this.networkNonces[peerId] : undefined; - var opts = {prevnonce: prevnonce}; - var decoded = this._decode(key, encoded, opts); - - //if no error thrown in the last step, we can set the copayer's nonce - if (!this.networkNonces) - this.networkNonces = {}; - this.networkNonces[peerId] = decoded.nonce; - - var databuf = decoded.payload; - var datastr = databuf.toString(); - var payload = JSON.parse(datastr); - } catch (e) { - this._deletePeer(peerId); - return; - } - - if (isInbound && payload.type === 'hello') { - var payloadStr = JSON.stringify(payload); - - //ensure claimed public key is actually the public key of the peer - //e.g., their public key should hash to be their peerId - if (peerId.toString() !== this.peerFromCopayer(payload.copayerId) || peerId.toString() !== this.peerFromCopayer(encoded.pubkey)) { - this._deletePeer(peerId, 'incorrect pubkey for peerId'); - return; - } - - if (this.allowedCopayerIds && !this.allowedCopayerIds[payload.copayerId]) { - this._deletePeer(peerId); - return; - } - - this._addConnectedCopayer(payload.copayerId, isInbound); - this._setInboundPeerAuth(peerId, true); - return; - } - - if (!this.copayerForPeer[peerId] || (isInbound && !this.isInboundPeerAuth[peerId])) { - this._deletePeer(peerId); - return; - } - - var self = this; - switch (payload.type) { - case 'disconnect': - this._onClose(peerId); - break; - default: - this.emit('data', self.copayerForPeer[peerId], payload, isInbound); - } -}; - -Network.prototype._checkAnyPeer = function(msg) { - if (this.connectedPeers.length === 1) { - this.emit('onlyYou'); - } -}; - -Network.prototype._setupConnectionHandlers = function(dataConn, toCopayerId) { - var self = this; - - var isInbound = toCopayerId ? false : true; - - dataConn.on('open', function() { - if (!Network._inArray(dataConn.peer, self.connectedPeers) && - !self.connections[dataConn.peer]) { - - self.connections[dataConn.peer] = dataConn; - - // The connecting peer send hello - if (toCopayerId) { - self.emit('connected'); - self._sendHello(toCopayerId); - self._addConnectedCopayer(toCopayerId); - } - } - }); - - dataConn.on('data', function(data) { - self._onData(data, isInbound, dataConn.peer); - }); - - dataConn.on('error', function(e) { - self._onClose(dataConn.peer); - self._checkAnyPeer(); - self.emit('dataError'); - }); - - dataConn.on('close', function() { - if (self.closing) return; - - self._onClose(dataConn.peer); - self._checkAnyPeer(); - }); -}; - -Network.prototype._handlePeerOpen = function(openCallback) { - this.connectedPeers = [this.peerId]; - this.copayerForPeer[this.peerId] = this.copayerId; - return openCallback(); -}; - -Network.prototype._handlePeerError = function(err) { - console.log('RECV ERROR: ', err); - if (err.message.match(/Could\snot\sconnect\sto peer/)) { - this._checkAnyPeer(); - } else { - this.criticalError = err.message; - } -}; - -Network.prototype._handlePeerConnection = function(dataConn) { - if (this.connectedPeers.length >= self.maxPeers) { - dataConn.on('open', function() { - dataConn.close(); - }); - } else { - this._setInboundPeerAuth(dataConn.peer, false); - this._setupConnectionHandlers(dataConn); - } -}; - -Network.prototype._setupPeerHandlers = function(openCallback) { - var p = this.peer; - p.on('open', this._handlePeerOpen.bind(this, openCallback)); - p.on('error', this._handlePeerError.bind(this)); - p.on('connection', this._handlePeerConnection.bind(this)); -}; - -Network.prototype._addCopayerMap = function(peerId, copayerId) { - if (!this.copayerForPeer[peerId]) { - if (Object.keys(this.copayerForPeer).length < this.maxPeers) { - this.copayerForPeer[peerId] = copayerId; - } else {} - } -}; - -Network.prototype._setInboundPeerAuth = function(peerId, isAuthenticated) { - this.isInboundPeerAuth[peerId] = isAuthenticated; -}; - -Network.prototype.setCopayerId = function(copayerId) { - if (this.started) { - throw new Error('network already started: can not change peerId') - } - this.copayerId = copayerId; - this.copayerIdBuf = new Buffer(copayerId, 'hex'); - this.peerId = this.peerFromCopayer(this.copayerId); - this._addCopayerMap(this.peerId, copayerId); -}; - - -// TODO cache this. -Network.prototype.peerFromCopayer = function(hex) { - var SIN = bitcore.SIN; - return new SIN(new Buffer(hex, 'hex')).toString(); -}; - -Network.prototype.start = function(opts, openCallback) { - opts = opts || {}; - - if (this.started) return openCallback(); - - if (!this.privkey) - this.privkey = opts.privkey; - - this.maxPeers = opts.maxPeers || this.maxPeers; - - if (opts.token) - this.opts.token = opts.token; - - if (!this.copayerId) - this.setCopayerId(opts.copayerId); - - var self = this; - var setupPeer = function() { - if (self.connectedPeers.length > 0) return; // Already connected! - if (self.peer) { - self.peer.destroy(); - self.peer.removeAllListeners(); - } - - if (!self.criticalError && self.tries < self.reconnectAttempts) { - self.tries++; - self.opts.token = util.sha256(self.peerId).toString('hex'); - self.peer = new Peer(self.peerId, self.opts); - self.started = true; - self._setupPeerHandlers(openCallback); - - setTimeout(setupPeer, 3000); // Schedule retry - return; - } - if (self.criticalError && self.criticalError.match(/taken/)) { - self.criticalError = ' Looks like you are already connected to this wallet please close all other Copay Wallets ' - } - - self.emit('serverError', self.criticalError); - self.cleanUp(); - } - - this.tries = 0; - setupPeer(); -}; - -Network.prototype.getOnlinePeerIDs = function() { - return this.connectedPeers; -}; - -Network.prototype.getPeer = function() { - return this.peer; -}; - -Network.prototype._encode = function(topubkey, fromkey, payload, opts) { - var encoded = Message.encode(topubkey, fromkey, payload, opts); - return encoded; -}; - - -Network.prototype._decode = function(key, encoded, opts) { - var decoded = Message.decode(key, encoded, opts); - return decoded; -}; - -Network.prototype._sendToOne = function(copayerId, payload, cb) { - if (!Buffer.isBuffer(payload)) - throw new Error('payload must be a buffer'); - - var peerId = this.peerFromCopayer(copayerId); - if (peerId !== this.peerId) { - var dataConn = this.connections[peerId]; - if (dataConn) { - dataConn.send(payload); - } - } - if (typeof cb === 'function') cb(); -}; - -Network.prototype.send = function(copayerIds, payload, cb) { - if (!payload) return cb(); - - var self = this; - if (!copayerIds) { - copayerIds = this.connectedCopayers(); - payload.isBroadcast = 1; - } - - if (typeof copayerIds === 'string') - copayerIds = [copayerIds]; - - var payloadStr = JSON.stringify(payload); - var payloadBuf = new Buffer(payloadStr); - - var l = copayerIds.length; - var i = 0; - copayerIds.forEach(function(copayerId) { - self.iterateNonce(); - var opts = {nonce: self.networkNonce}; - var copayerIdBuf = new Buffer(copayerId, 'hex'); - var encPayload = self._encode(copayerIdBuf, self.getKey(), payloadBuf, opts); - var enc = new Buffer(JSON.stringify(encPayload)); - self._sendToOne(copayerId, enc, function() { - if (++i === l && typeof cb === 'function') cb(); - }); - }); -}; - - -Network.prototype.isOnline = function() { - return !!this.peer; -}; - -Network.prototype.connectTo = function(copayerId) { - var self = this; - - var peerId = this.peerFromCopayer(copayerId); - var dataConn = this.peer.connect(peerId, { - serialization: 'none', - reliable: true, - }); - self._setupConnectionHandlers(dataConn, copayerId); -}; - -Network.prototype.lockIncommingConnections = function(allowedCopayerIdsArray) { - this.allowedCopayerIds = {}; - for (var i in allowedCopayerIdsArray) { - this.allowedCopayerIds[allowedCopayerIdsArray[i]] = true; - } -}; - -Network.prototype.disconnect = function(cb, forced) { - var self = this; - self.closing = 1; - self.send(null, { - type: 'disconnect' - }, function() { - self.cleanUp(); - if (typeof cb === 'function') cb(); - }); -}; - -module.exports = Network; diff --git a/test/index.html b/test/index.html index 6d75f29c7..3b99beef9 100644 --- a/test/index.html +++ b/test/index.html @@ -16,7 +16,7 @@ - + diff --git a/test/test.network.WebRTC.js b/test/test.network.WebRTC.js deleted file mode 100644 index 8231991dc..000000000 --- a/test/test.network.WebRTC.js +++ /dev/null @@ -1,507 +0,0 @@ -'use strict'; - -var chai = chai || require('chai'); -var should = chai.should(); -var expect = chai.expect; -var sinon = sinon || require('sinon'); -var bitcore = bitcore || require('bitcore'); -var WebRTC = require('../js/models/network/WebRTC'); - -describe('Network / WebRTC', function() { - - it('should create an instance', function() { - var n = new WebRTC(); - should.exist(n); - }); - - describe('#WebRTC constructor', function() { - - it('should set reconnect attempts', function() { - var n = new WebRTC(); - n.reconnectAttempts.should.equal(3); - }); - - it('should call cleanUp', function() { - var save = WebRTC.prototype.cleanUp; - WebRTC.prototype.cleanUp = sinon.spy(); - var n = new WebRTC(); - n.cleanUp.calledOnce.should.equal(true); - WebRTC.prototype.cleanUp = save; - }); - }); - - describe('#cleanUp', function() { - - it('should not set netKey', function() { - var n = new WebRTC(); - (n.netKey === undefined).should.equal(true); - }); - - it('should set privkey to null', function() { - var n = new WebRTC(); - n.cleanUp(); - expect(n.privkey).to.equal(null); - }); - - it('should remove handlers', function() { - var n = new WebRTC(); - var save = WebRTC.prototype.removeAllListeners; - var spy = WebRTC.prototype.removeAllListeners = sinon.spy(); - n.cleanUp(); - spy.calledOnce.should.equal(true); - WebRTC.prototype.removeAllListeners = save; - }); - }); - - - describe('#_setupPeerHandlers', function() { - var n = new WebRTC(); - n.peer = {}; - var spy = n.peer.on = sinon.spy(); - it('should setup handlers', function() { - n._setupPeerHandlers(); - spy.calledWith('connection').should.equal(true); - spy.calledWith('open').should.equal(true); - spy.calledWith('error').should.equal(true); - }); - }); - - describe('#_handlePeerOpen', function() { - var n = new WebRTC(); - it('should call openCallback handler', function(done) { - n.peerId = 1; - n.copayerId = 2; - n._handlePeerOpen(function() { - n.connectedPeers.should.deep.equal([1]); - n.copayerForPeer.should.deep.equal({ - 1: 2 - }); - done(); - }); - }); - }); - - describe('#_handlePeerError', function() { - var log = console.log; - var n = new WebRTC(); - it('should call _checkAnyPeer on could not connect error', function() { - var save = n._checkAnyPeer; - var spy = n._checkAnyPeer = sinon.spy(); - var logSpy = console.log = sinon.spy(); - n._handlePeerError({ - message: 'Could not connect to peer xxx' - }); - console.log = log; - spy.called.should.equal(true); - logSpy.called.should.equal(true); - n._checkAnyPeer = save; - }); - - it('should call not call _checkAnyPeer other error', function() { - var save = n._checkAnyPeer; - var spy = n._checkAnyPeer = sinon.spy(); - var otherMessage = 'Could connect to peer xxx'; - var logSpy = console.log = sinon.spy(); - n._handlePeerError({ - message: otherMessage, - }); - console.log = log; - spy.called.should.equal(false); - n.criticalError.should.equal(otherMessage); - logSpy.called.should.equal(true); - n._checkAnyPeer = save; - }); - - }); - - - - describe('#_encode', function() { - - it('should encode data successfully', function() { - var n = new WebRTC(); - var data = new bitcore.Buffer('my data to encode'); - var privkeystr = new bitcore.Buffer('test privkey'); - var privkey = bitcore.util.sha256(privkeystr); - var key = new bitcore.Key(); - key.private = privkey; - key.regenerateSync(); - var encoded = n._encode(key.public, key, data); - should.exist(encoded); - encoded.sig.length.should.not.equal(0); - encoded.pubkey.length.should.not.equal(0); - encoded.encrypted.length.should.not.equal(0); - }); - - }); - - describe('#_decode', function() { - - it('should decode that which was encoded', function() { - var n = new WebRTC(); - var data = new bitcore.Buffer('my data to encrypt'); - var privkeystr = new bitcore.Buffer('test privkey'); - var privkey = bitcore.util.sha256(privkeystr); - var key = new bitcore.Key(); - key.private = privkey; - key.regenerateSync(); - var encoded = n._encode(key.public, key, data); - var decoded = n._decode(key, encoded); - encoded.sig.should.not.equal(0); - decoded.payload.toString().should.equal('my data to encrypt'); - }); - - }); - - describe('#send', function() { - - it('should call _sendToOne for a copayer', function(done) { - var n = new WebRTC(); - n.privkey = bitcore.util.sha256('test'); - - var data = new bitcore.Buffer('my data to send'); - - var privkeystr = new bitcore.Buffer('test privkey'); - var privkey = bitcore.util.sha256(privkeystr); - var key = new bitcore.Key(); - key.private = privkey; - key.regenerateSync(); - - var copayerId = key.public.toString('hex'); - n._sendToOne = function(a1, a2, cb) { - cb(); - }; - var opts = {}; - n.send(copayerId, data, function() { - done(); - }); - - }); - - it('should call _sendToOne with encrypted data for a copayer', function(done) { - var n = new WebRTC(); - n.privkey = bitcore.util.sha256('test'); - - var data = new bitcore.Buffer('my data to send'); - - var privkeystr = new bitcore.Buffer('test privkey'); - var privkey = bitcore.util.sha256(privkeystr); - var key = new bitcore.Key(); - key.private = privkey; - key.regenerateSync(); - - var copayerId = key.public.toString('hex'); - n._sendToOne = function(a1, enc, cb) { - var encPayload = JSON.parse(enc.toString()); - encPayload.sig.length.should.be.greaterThan(0); - cb(); - }; - var opts = {}; - n.send(copayerId, data, function() { - done(); - }); - - }); - - it('should call _sendToOne for a list of copayers', function(done) { - var n = new WebRTC(); - n.privkey = bitcore.util.sha256('test'); - - var data = new bitcore.Buffer('my data to send'); - - var privkeystr = new bitcore.Buffer('test privkey'); - var privkey = bitcore.util.sha256(privkeystr); - var key = new bitcore.Key(); - key.private = privkey; - key.regenerateSync(); - - var copayerIds = [key.public.toString('hex')]; - n._sendToOne = function(a1, a2, cb) { - cb(); - }; - var opts = {}; - n.send(copayerIds, data, function() { - done(); - }); - - }); - }); - - describe('#_onData', function() { - var privkey1 = bitcore.util.sha256('test privkey 1'); - var privkey2 = bitcore.util.sha256('test privkey 2'); - var privkey3 = bitcore.util.sha256('test privkey 2'); - - var key1 = new bitcore.Key(); - key1.private = privkey1; - key1.regenerateSync(); - - var key2 = new bitcore.Key(); - key2.private = privkey2; - key2.regenerateSync(); - - var key3 = new bitcore.Key(); - key3.private = privkey3; - key3.regenerateSync(); - - it('should not reject data sent from a peer with hijacked pubkey', function() { - var n = new WebRTC(); - n.privkey = key2.private.toString('hex'); - - var message = { - type: 'hello', - copayerId: key1.public.toString('hex') - }; - var messagestr = JSON.stringify(message); - var messagebuf = new Buffer(messagestr); - - var encoded = n._encode(key2.public, key1, messagebuf); - var encodedstr = JSON.stringify(encoded); - var encodeduint = new Buffer(encodedstr); - - var isInbound = true; - var peerId = new bitcore.SIN(key1.public); - - n._deletePeer = sinon.spy(); - - n._onData(encodeduint, isInbound, peerId); - n._deletePeer.calledOnce.should.equal(false); - }); - - it('should reject data sent from a peer with hijacked pubkey', function() { - var n = new WebRTC(); - n.privkey = key2.private.toString('hex'); - - var message = { - type: 'hello', - copayerId: key3.public.toString('hex') //MITM pubkey 3 - }; - var messagestr = JSON.stringify(message); - var messagebuf = new Buffer(messagestr); - - var encoded = n._encode(key2.public, key1, messagebuf); - var encodedstr = JSON.stringify(encoded); - var encodeduint = new Buffer(encodedstr); - - var isInbound = true; - var peerId = new bitcore.SIN(key1.public); - - n._deletePeer = sinon.spy(); - - n._onData(encodeduint, isInbound, peerId); - n._deletePeer.calledOnce.should.equal(true); - n._deletePeer.getCall(0).args[0].should.equal(peerId); - n._deletePeer.getCall(0).args[1].should.equal('incorrect pubkey for peerId'); - }); - - it('should not reject data sent from a peer with no previously set nonce but who is setting one now', function() { - var n = new WebRTC(); - n.privkey = key2.private.toString('hex'); - //n.networkNonces = {}; - //n.networkNonces[(new bitcore.SIN(key1.public)).toString()] = new Buffer('0000000000000001', 'hex'); //previously used nonce - - var message = { - type: 'hello', - copayerId: key1.public.toString('hex') - }; - var messagestr = JSON.stringify(message); - var messagebuf = new Buffer(messagestr); - - var opts = {nonce: new Buffer('0000000000000001', 'hex')}; //message send with new nonce - var encoded = n._encode(key2.public, key1, messagebuf, opts); - var encodedstr = JSON.stringify(encoded); - var encodeduint = new Buffer(encodedstr); - - var isInbound = true; - var peerId = new bitcore.SIN(key1.public); - - n._deletePeer = sinon.spy(); - - n._onData(encodeduint, isInbound, peerId); - n._deletePeer.calledOnce.should.equal(false); - n.getHexNonces()[(new bitcore.SIN(key1.public)).toString()].toString('hex').should.equal('0000000000000001'); - }); - - it('should not reject data sent from a peer with a really big new nonce', function() { - var n = new WebRTC(); - n.privkey = key2.private.toString('hex'); - n.networkNonces = {}; - n.networkNonces[(new bitcore.SIN(key1.public)).toString()] = new Buffer('5000000000000001', 'hex'); //previously used nonce - - var message = { - type: 'hello', - copayerId: key1.public.toString('hex') - }; - var messagestr = JSON.stringify(message); - var messagebuf = new Buffer(messagestr); - - var opts = {nonce: new Buffer('5000000000000002', 'hex')}; //message send with new nonce - var encoded = n._encode(key2.public, key1, messagebuf, opts); - var encodedstr = JSON.stringify(encoded); - var encodeduint = new Buffer(encodedstr); - - var isInbound = true; - var peerId = new bitcore.SIN(key1.public); - - n._deletePeer = sinon.spy(); - - n._onData(encodeduint, isInbound, peerId); - n._deletePeer.calledOnce.should.equal(false); - }); - - it('should not reject data sent from a peer with a really big new nonce', function() { - var n = new WebRTC(); - n.privkey = key2.private.toString('hex'); - n.networkNonces = {}; - n.networkNonces[(new bitcore.SIN(key1.public)).toString()] = new Buffer('5000000000000001', 'hex'); //previously used nonce - - var message = { - type: 'hello', - copayerId: key1.public.toString('hex') - }; - var messagestr = JSON.stringify(message); - var messagebuf = new Buffer(messagestr); - - var opts = {nonce: new Buffer('5000000000000002', 'hex')}; //message send with new nonce - var encoded = n._encode(key2.public, key1, messagebuf, opts); - var encodedstr = JSON.stringify(encoded); - var encodeduint = new Buffer(encodedstr); - - var isInbound = true; - var peerId = new bitcore.SIN(key1.public); - - n._deletePeer = sinon.spy(); - - n._onData(encodeduint, isInbound, peerId); - n._deletePeer.calledOnce.should.equal(false); - }); - - it('should reject data sent from a peer with an outdated nonce', function() { - var n = new WebRTC(); - n.privkey = key2.private.toString('hex'); - n.networkNonces = {}; - n.networkNonces[(new bitcore.SIN(key1.public)).toString()] = new Buffer('0000000000000002', 'hex'); //previously used nonce - - var message = { - type: 'hello', - copayerId: key1.public.toString('hex') - }; - var messagestr = JSON.stringify(message); - var messagebuf = new Buffer(messagestr); - - var opts = {nonce: new Buffer('0000000000000001', 'hex')}; //message send with old nonce - var encoded = n._encode(key2.public, key1, messagebuf, opts); - var encodedstr = JSON.stringify(encoded); - var encodeduint = new Buffer(encodedstr); - - var isInbound = true; - var peerId = new bitcore.SIN(key1.public); - - n._deletePeer = sinon.spy(); - - n._onData(encodeduint, isInbound, peerId); - n._deletePeer.calledOnce.should.equal(true); - }); - - it('should reject data sent from a peer with a really big outdated nonce', function() { - var n = new WebRTC(); - n.privkey = key2.private.toString('hex'); - n.networkNonces = {}; - n.networkNonces[(new bitcore.SIN(key1.public)).toString()] = new Buffer('5000000000000002', 'hex'); //previously used nonce - - var message = { - type: 'hello', - copayerId: key1.public.toString('hex') - }; - var messagestr = JSON.stringify(message); - var messagebuf = new Buffer(messagestr); - - var opts = {nonce: new Buffer('5000000000000001', 'hex')}; //message send with old nonce - var encoded = n._encode(key2.public, key1, messagebuf, opts); - var encodedstr = JSON.stringify(encoded); - var encodeduint = new Buffer(encodedstr); - - var isInbound = true; - var peerId = new bitcore.SIN(key1.public); - - n._deletePeer = sinon.spy(); - - n._onData(encodeduint, isInbound, peerId); - n._deletePeer.calledOnce.should.equal(true); - }); - - }); - - describe('#setHexNonce', function() { - - it('should set a nonce from a hex value', function() { - var hex = '0000000000000000'; - var n = new WebRTC(); - n.setHexNonce(hex); - n.getHexNonce().should.equal(hex); - n.networkNonce.toString('hex').should.equal(hex); - }); - - }); - - describe('#setHexNonces', function() { - - it('should set a nonce from a hex value', function() { - var hex = '0000000000000000'; - var n = new WebRTC(); - n.setHexNonces({fakeid: hex}); - n.getHexNonces().fakeid.should.equal(hex); - }); - - }); - - describe('#getHexNonce', function() { - - it('should get a nonce hex value', function() { - var hex = '0000000000000000'; - var n = new WebRTC(); - n.setHexNonce(hex); - n.getHexNonce().should.equal(hex); - }); - - }); - - describe('#getHexNonces', function() { - - it('should get a nonce from a hex value', function() { - var hex = '0000000000000000'; - var n = new WebRTC(); - n.setHexNonces({fakeid: hex}); - n.getHexNonces().fakeid.should.equal(hex); - }); - - }); - - describe('#iterateNonce', function() { - - it('should set a nonce not already set', function() { - var n = new WebRTC(); - n.iterateNonce(); - n.networkNonce.slice(4, 8).toString('hex').should.equal('00000001'); - n.networkNonce.slice(0, 4).toString('hex').should.not.equal('00000000'); - }); - - it('called twice should increment', function() { - var n = new WebRTC(); - n.iterateNonce(); - n.networkNonce.slice(4, 8).toString('hex').should.equal('00000001'); - n.iterateNonce(); - n.networkNonce.slice(4, 8).toString('hex').should.equal('00000002'); - }); - - it('should set the first byte to the most significant "now" digit', function() { - var n = new WebRTC(); - n.iterateNonce(); - var buf = new Buffer(4); - buf.writeUInt32BE(Math.floor(Date.now()/1000), 0); - n.networkNonce[0].should.equal(buf[0]); - }); - - }); - -});