peer/bip151: rewrite bip151. handle bip151 on p2p network.
This commit is contained in:
parent
233af72b7f
commit
b455352708
@ -19,9 +19,9 @@ var INFO_KEY1 = new Buffer('BitcoinK1', 'ascii');
|
||||
var INFO_KEY2 = new Buffer('BitcoinK2', 'ascii');
|
||||
var INFO_SID = new Buffer('BitcoinSessionID', 'ascii');
|
||||
|
||||
function BIP151(cipher, key) {
|
||||
if (!(this instanceof BIP151))
|
||||
return new BIP151(cipher, key);
|
||||
function BIP151Stream(cipher, key) {
|
||||
if (!(this instanceof BIP151Stream))
|
||||
return new BIP151Stream(cipher, key);
|
||||
|
||||
EventEmitter.call(this);
|
||||
|
||||
@ -29,25 +29,21 @@ function BIP151(cipher, key) {
|
||||
this.privateKey = key || bcoin.ec.generatePrivateKey();
|
||||
this.cipher = cipher || 0;
|
||||
this.secret = null;
|
||||
this.prk = null;
|
||||
this.k1 = null;
|
||||
this.k2 = null;
|
||||
this.sid = null;
|
||||
|
||||
assert(this.cipher === 0, 'Unknown cipher type.');
|
||||
|
||||
this.chacha = new chachapoly.ChaCha20();
|
||||
this.aead = new chachapoly.AEAD();
|
||||
this.prk = null;
|
||||
this.tag = null;
|
||||
this.seq = 0;
|
||||
this.initReceived = false;
|
||||
this.ackReceived = false;
|
||||
this.initSent = false;
|
||||
this.ackSent = false;
|
||||
|
||||
this.highWaterMark = 1024 * (1 << 20);
|
||||
this.processed = 0;
|
||||
this.lastRekey = 0;
|
||||
this.timeout = null;
|
||||
this.callback = null;
|
||||
this.completed = false;
|
||||
this.handshake = false;
|
||||
|
||||
this.pendingHeader = [];
|
||||
this.pendingHeaderTotal = 0;
|
||||
@ -57,9 +53,9 @@ function BIP151(cipher, key) {
|
||||
this.waiting = 0;
|
||||
}
|
||||
|
||||
utils.inherits(BIP151, EventEmitter);
|
||||
utils.inherits(BIP151Stream, EventEmitter);
|
||||
|
||||
BIP151.prototype.init = function init(publicKey) {
|
||||
BIP151Stream.prototype.init = function init(publicKey) {
|
||||
var p = bcoin.writer();
|
||||
|
||||
this.publicKey = publicKey;
|
||||
@ -82,14 +78,17 @@ BIP151.prototype.init = function init(publicKey) {
|
||||
this.lastRekey = utils.ms();
|
||||
};
|
||||
|
||||
BIP151.prototype.isReady = function isReady() {
|
||||
return this.initSent
|
||||
&& this.ackReceived
|
||||
&& this.initReceived
|
||||
&& this.ackSent;
|
||||
BIP151Stream.prototype.maybeRekey = function maybeRekey(data) {
|
||||
var self = this;
|
||||
this.processed += data.length;
|
||||
if (this.processed >= this.highWaterMark) {
|
||||
this.processed -= this.highWaterMark;
|
||||
this.rekey();
|
||||
this.emit('rekey');
|
||||
}
|
||||
};
|
||||
|
||||
BIP151.prototype.rekey = function rekey() {
|
||||
BIP151Stream.prototype.rekey = function rekey() {
|
||||
assert(this.prk, 'Cannot rekey before initialization.');
|
||||
|
||||
this.k1 = utils.hash256(this.k1);
|
||||
@ -104,193 +103,54 @@ BIP151.prototype.rekey = function rekey() {
|
||||
this.lastRekey = utils.ms();
|
||||
};
|
||||
|
||||
BIP151.prototype.sequence = function sequence() {
|
||||
BIP151Stream.prototype.sequence = function sequence() {
|
||||
this.seq++;
|
||||
this.chacha.init(this.k1, this.iv());
|
||||
this.aead.init(this.k2, this.iv());
|
||||
this.aead.aad(this.sid);
|
||||
};
|
||||
|
||||
BIP151.prototype.iv = function iv() {
|
||||
BIP151Stream.prototype.iv = function iv() {
|
||||
var p = bcoin.writer();
|
||||
p.writeU64(this.seq);
|
||||
p.writeU32(0);
|
||||
return p.render();
|
||||
};
|
||||
|
||||
BIP151.prototype.getPublicKey = function getPublicKey() {
|
||||
BIP151Stream.prototype.getPublicKey = function getPublicKey() {
|
||||
return bcoin.ec.publicKeyCreate(this.privateKey, true);
|
||||
};
|
||||
|
||||
BIP151.prototype.encryptSize = function encryptSize(size) {
|
||||
BIP151Stream.prototype.encryptSize = function encryptSize(size) {
|
||||
var data = new Buffer(4);
|
||||
data.writeUInt32LE(size, 0, true);
|
||||
return this.chacha.encrypt(data);
|
||||
};
|
||||
|
||||
BIP151.prototype.decryptSize = function decryptSize(data) {
|
||||
BIP151Stream.prototype.decryptSize = function decryptSize(data) {
|
||||
data = data.slice(0, 4);
|
||||
this.chacha.encrypt(data);
|
||||
return data.readUInt32LE(0, true);
|
||||
};
|
||||
|
||||
BIP151.prototype.encrypt = function encrypt(data) {
|
||||
BIP151Stream.prototype.encrypt = function encrypt(data) {
|
||||
return this.aead.encrypt(data);
|
||||
};
|
||||
|
||||
BIP151.prototype.decrypt = function decrypt(data) {
|
||||
BIP151Stream.prototype.decrypt = function decrypt(data) {
|
||||
return this.aead.decrypt(data);
|
||||
};
|
||||
|
||||
BIP151.prototype.finish = function finish(data) {
|
||||
BIP151Stream.prototype.finish = function finish(data) {
|
||||
this.tag = this.aead.finish(data);
|
||||
return this.tag;
|
||||
};
|
||||
|
||||
BIP151.prototype.verify = function verify(tag) {
|
||||
BIP151Stream.prototype.verify = function verify(tag) {
|
||||
return chachapoly.Poly1305.verify(this.tag, tag);
|
||||
};
|
||||
|
||||
BIP151.prototype.toEncinit = function toEncinit(writer) {
|
||||
var p = bcoin.writer(writer);
|
||||
|
||||
p.writeBytes(this.getPublicKey());
|
||||
p.writeU8(this.cipher);
|
||||
|
||||
if (!writer)
|
||||
p = p.render();
|
||||
|
||||
this.initSent = true;
|
||||
|
||||
return p;
|
||||
};
|
||||
|
||||
BIP151.prototype.encinit = function encinit(data) {
|
||||
var p = bcoin.reader(data);
|
||||
var publicKey = p.readBytes(33);
|
||||
|
||||
// this.cipher = p.readU8();
|
||||
assert(p.readU8() === this.cipher, 'Wrong cipher type.');
|
||||
|
||||
assert(!this.initReceived, 'Already initialized.');
|
||||
|
||||
if (!this.ackReceived) {
|
||||
this.init(publicKey);
|
||||
} else {
|
||||
assert(utils.equal(publicKey, this.publicKey),
|
||||
'Bad pubkey.');
|
||||
}
|
||||
|
||||
this.initReceived = true;
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
BIP151.fromEncinit = function fromEncinit(data) {
|
||||
return new BIP151().encinit(data);
|
||||
};
|
||||
|
||||
BIP151.prototype.toEncack = function toEncack(writer) {
|
||||
var p = bcoin.writer(writer);
|
||||
|
||||
p.writeBytes(this.getPublicKey());
|
||||
|
||||
if (!writer)
|
||||
p = p.render();
|
||||
|
||||
if (!this.ackSent) {
|
||||
this.ackSent = true;
|
||||
if (this.isReady()) {
|
||||
this.handshake = true;
|
||||
this.emit('handshake');
|
||||
}
|
||||
}
|
||||
|
||||
return p;
|
||||
};
|
||||
|
||||
BIP151.prototype.toRekey = function toRekey(writer) {
|
||||
var p = bcoin.writer(writer);
|
||||
|
||||
p.writeBytes(constants.ZERO_KEY);
|
||||
|
||||
if (!writer)
|
||||
p = p.render();
|
||||
|
||||
return p;
|
||||
};
|
||||
|
||||
BIP151.prototype.maybeRekey = function maybeRekey(data) {
|
||||
var self = this;
|
||||
this.processed += data.length;
|
||||
if (this.processed >= this.highWaterMark) {
|
||||
this.processed -= this.highWaterMark;
|
||||
utils.nextTick(function() {
|
||||
self.emit('rekey');
|
||||
self.rekey();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
BIP151.prototype.complete = function complete(err) {
|
||||
assert(!this.completed, 'Already completed.');
|
||||
assert(this.callback, 'No completion callback.');
|
||||
|
||||
this.completed = true;
|
||||
|
||||
clearTimeout(this.timeout);
|
||||
this.timeout = null;
|
||||
|
||||
this.callback(err);
|
||||
this.callback = null;
|
||||
};
|
||||
|
||||
BIP151.prototype.wait = function wait(timeout, callback) {
|
||||
var self = this;
|
||||
|
||||
assert(!this.handshake, 'Cannot wait for init after handshake.');
|
||||
|
||||
this.callback = callback;
|
||||
|
||||
this.timeout = setTimeout(function() {
|
||||
self.complete(new Error('Timed out.'));
|
||||
}, timeout);
|
||||
|
||||
this.once('handshake', function() {
|
||||
self.complete();
|
||||
});
|
||||
};
|
||||
|
||||
BIP151.prototype.encack = function encack(data) {
|
||||
var p = bcoin.reader(data);
|
||||
var publicKey = p.readBytes(33);
|
||||
|
||||
assert(this.initSent, 'Unsolicited ACK.');
|
||||
|
||||
if (utils.equal(publicKey, constants.ZERO_KEY)) {
|
||||
assert(this.ackReceived, 'No ACK before rekey.');
|
||||
assert(this.handshake, 'No initialization before rekey.');
|
||||
this.rekey();
|
||||
return;
|
||||
}
|
||||
|
||||
assert(!this.ackReceived, 'Already ACKed.');
|
||||
this.ackReceived = true;
|
||||
|
||||
if (!this.initReceived) {
|
||||
this.init(publicKey);
|
||||
} else {
|
||||
assert(utils.equal(publicKey, this.publicKey),
|
||||
'Bad pubkey.');
|
||||
}
|
||||
|
||||
if (this.isReady()) {
|
||||
this.handshake = true;
|
||||
this.emit('handshake');
|
||||
}
|
||||
};
|
||||
|
||||
BIP151.prototype.feed = function feed(data) {
|
||||
BIP151Stream.prototype.feed = function feed(data) {
|
||||
var chunk, payload, tag, p, cmd, body;
|
||||
|
||||
this.maybeRekey(data);
|
||||
@ -371,7 +231,7 @@ BIP151.prototype.feed = function feed(data) {
|
||||
};
|
||||
|
||||
// TODO: We could batch packets here!
|
||||
BIP151.prototype.packet = function packet(cmd, body) {
|
||||
BIP151Stream.prototype.packet = function packet(cmd, body) {
|
||||
var p = bcoin.writer();
|
||||
var payload, packet;
|
||||
|
||||
@ -393,4 +253,167 @@ BIP151.prototype.packet = function packet(cmd, body) {
|
||||
return packet;
|
||||
};
|
||||
|
||||
function BIP151(cipher) {
|
||||
if (!(this instanceof BIP151))
|
||||
return new BIP151(cipher);
|
||||
|
||||
EventEmitter.call(this);
|
||||
|
||||
this.input = new BIP151Stream(cipher);
|
||||
this.output = null;
|
||||
|
||||
this.initReceived = false;
|
||||
this.ackReceived = false;
|
||||
this.initSent = false;
|
||||
this.ackSent = false;
|
||||
this.timeout = null;
|
||||
this.callback = null;
|
||||
this.completed = false;
|
||||
this.handshake = false;
|
||||
|
||||
this._init();
|
||||
}
|
||||
|
||||
utils.inherits(BIP151, EventEmitter);
|
||||
|
||||
BIP151.prototype._init = function _init() {
|
||||
var self = this;
|
||||
|
||||
this.input.on('rekey', function() {
|
||||
self.emit('rekey');
|
||||
});
|
||||
|
||||
this.input.on('packet', function(cmd, body) {
|
||||
self.emit('packet', cmd, body);
|
||||
});
|
||||
};
|
||||
|
||||
BIP151.prototype.isReady = function isReady() {
|
||||
return this.initSent
|
||||
&& this.ackReceived
|
||||
&& this.initReceived
|
||||
&& this.ackSent;
|
||||
};
|
||||
|
||||
BIP151.prototype.toEncinit = function toEncinit(writer) {
|
||||
var p = bcoin.writer(writer);
|
||||
|
||||
p.writeBytes(this.input.getPublicKey());
|
||||
p.writeU8(this.input.cipher);
|
||||
|
||||
if (!writer)
|
||||
p = p.render();
|
||||
|
||||
this.initSent = true;
|
||||
|
||||
return p;
|
||||
};
|
||||
|
||||
BIP151.prototype.encack = function encack(data) {
|
||||
var p = bcoin.reader(data);
|
||||
var publicKey = p.readBytes(33);
|
||||
|
||||
assert(this.initSent, 'Unsolicited ACK.');
|
||||
|
||||
if (utils.equal(publicKey, constants.ZERO_KEY)) {
|
||||
assert(this.handshake, 'No initialization before rekey.');
|
||||
this.output.rekey();
|
||||
return;
|
||||
}
|
||||
|
||||
assert(!this.ackReceived, 'Already ACKed.');
|
||||
this.ackReceived = true;
|
||||
|
||||
this.input.init(publicKey);
|
||||
|
||||
if (this.isReady()) {
|
||||
this.handshake = true;
|
||||
this.emit('handshake');
|
||||
}
|
||||
};
|
||||
|
||||
BIP151.prototype.encinit = function encinit(data) {
|
||||
var p = bcoin.reader(data);
|
||||
var publicKey = p.readBytes(33);
|
||||
|
||||
assert(!this.initReceived, 'Already initialized.');
|
||||
|
||||
this.output = new BIP151Stream(p.readU8());
|
||||
this.output.init(publicKey);
|
||||
|
||||
this.initReceived = true;
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
BIP151.prototype.toEncack = function toEncack(writer) {
|
||||
var p = bcoin.writer(writer);
|
||||
|
||||
assert(this.output, 'Cannot ack before init.');
|
||||
|
||||
p.writeBytes(this.output.getPublicKey());
|
||||
|
||||
if (!writer)
|
||||
p = p.render();
|
||||
|
||||
if (!this.ackSent) {
|
||||
this.ackSent = true;
|
||||
if (this.isReady()) {
|
||||
this.handshake = true;
|
||||
this.emit('handshake');
|
||||
}
|
||||
}
|
||||
|
||||
return p;
|
||||
};
|
||||
|
||||
BIP151.prototype.toRekey = function toRekey(writer) {
|
||||
var p = bcoin.writer(writer);
|
||||
|
||||
p.writeBytes(constants.ZERO_KEY);
|
||||
|
||||
if (!writer)
|
||||
p = p.render();
|
||||
|
||||
return p;
|
||||
};
|
||||
|
||||
BIP151.prototype.complete = function complete(err) {
|
||||
assert(!this.completed, 'Already completed.');
|
||||
assert(this.callback, 'No completion callback.');
|
||||
|
||||
this.completed = true;
|
||||
|
||||
clearTimeout(this.timeout);
|
||||
this.timeout = null;
|
||||
|
||||
this.callback(err);
|
||||
this.callback = null;
|
||||
};
|
||||
|
||||
BIP151.prototype.wait = function wait(timeout, callback) {
|
||||
var self = this;
|
||||
|
||||
assert(!this.handshake, 'Cannot wait for init after handshake.');
|
||||
|
||||
this.callback = callback;
|
||||
|
||||
this.timeout = setTimeout(function() {
|
||||
self.complete(new Error('BIP151 handshake timed out.'));
|
||||
}, timeout);
|
||||
|
||||
this.once('handshake', function() {
|
||||
self.complete();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
BIP151.prototype.feed = function feed(data) {
|
||||
return this.input.feed(data);
|
||||
};
|
||||
|
||||
BIP151.prototype.packet = function packet(cmd, body) {
|
||||
return this.output.packet(cmd, body);
|
||||
};
|
||||
|
||||
module.exports = BIP151;
|
||||
|
||||
@ -18,6 +18,7 @@ var VersionPacket = bcoin.packets.VersionPacket;
|
||||
var GetBlocksPacket = bcoin.packets.GetBlocksPacket;
|
||||
var RejectPacket = bcoin.packets.RejectPacket;
|
||||
var NetworkAddress = bcoin.packets.NetworkAddress;
|
||||
var Packet = bcoin.protocol.parser.Packet;
|
||||
|
||||
/**
|
||||
* Represents a remote peer.
|
||||
@ -109,6 +110,10 @@ function Peer(pool, options) {
|
||||
this.compactMode = null;
|
||||
this.compactBlocks = {};
|
||||
this.sentAddr = false;
|
||||
this.bip151 = null;
|
||||
|
||||
if (options.bip151)
|
||||
this.bip151 = new bcoin.bip151();
|
||||
|
||||
this.challenge = null;
|
||||
this.lastPong = -1;
|
||||
@ -215,7 +220,10 @@ Peer.prototype._init = function init() {
|
||||
});
|
||||
|
||||
this.socket.on('data', function(chunk) {
|
||||
self.parser.feed(chunk);
|
||||
if (self.bip151 && self.bip151.handshake)
|
||||
self.bip151.feed(chunk);
|
||||
else
|
||||
self.parser.feed(chunk);
|
||||
});
|
||||
|
||||
this.parser.on('packet', function(packet) {
|
||||
@ -227,6 +235,16 @@ Peer.prototype._init = function init() {
|
||||
self.reject(null, 'malformed', 'error parsing message', 10);
|
||||
});
|
||||
|
||||
if (this.bip151) {
|
||||
this.bip151.on('error', function(err) {
|
||||
self.reject(null, 'malformed', 'error parsing message', 10);
|
||||
self._error(err, true);
|
||||
});
|
||||
this.bip151.on('rekey', function() {
|
||||
self.write(self.framer.encack(self.bip151.toRekey()));
|
||||
});
|
||||
}
|
||||
|
||||
if (this.connected) {
|
||||
utils.nextTick(function() {
|
||||
self._onConnect();
|
||||
@ -253,6 +271,36 @@ Peer.prototype._onConnect = function _onConnect() {
|
||||
this._connectTimeout = null;
|
||||
}
|
||||
|
||||
// Send encinit. Wait for handshake to complete.
|
||||
if (this.bip151 && !this.bip151.completed) {
|
||||
this.logger.info('Attempting BIP151 handshake (%s).', this.hostname);
|
||||
this.write(this.framer.encinit(this.bip151.toEncinit()));
|
||||
this.bip151.wait(5000, function(err) {
|
||||
if (err)
|
||||
self.logger.error(err);
|
||||
assert(self.bip151.completed);
|
||||
self._onConnect();
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.bip151 && this.bip151.handshake) {
|
||||
this.logger.info('BIP151 handshake complete (%s).', this.hostname);
|
||||
this.logger.info('Connection is encrypted (%s).', this.hostname);
|
||||
this.bip151.on('packet', function(cmd, body) {
|
||||
var packet = new Packet(cmd, body.length);
|
||||
try {
|
||||
packet.payload = self.parser.parsePayload(cmd, body);
|
||||
} catch (e) {
|
||||
return self.parser._error(e);
|
||||
}
|
||||
self.parser.emit('packet', packet);
|
||||
});
|
||||
this.framer.packet = function packet(cmd, body) {
|
||||
return self.bip151.packet(cmd, body);
|
||||
};
|
||||
}
|
||||
|
||||
this.request('verack', function(err) {
|
||||
self._onAck(err);
|
||||
});
|
||||
@ -766,6 +814,13 @@ Peer.prototype._onPacket = function onPacket(packet) {
|
||||
var cmd = packet.cmd;
|
||||
var payload = packet.payload;
|
||||
|
||||
if (this.bip151
|
||||
&& !this.bip151.completed
|
||||
&& cmd !== 'encinit'
|
||||
&& cmd !== 'encack') {
|
||||
this.bip151.complete(new Error('Message before handshake.'));
|
||||
}
|
||||
|
||||
if (this.lastBlock && cmd !== 'tx')
|
||||
this._flushMerkle();
|
||||
|
||||
@ -1819,6 +1874,18 @@ Peer.prototype._handleAlert = function _handleAlert(alert) {
|
||||
*/
|
||||
|
||||
Peer.prototype._handleEncinit = function _handleEncinit(payload) {
|
||||
if (!this.bip151)
|
||||
return;
|
||||
|
||||
try {
|
||||
this.bip151.encinit(payload);
|
||||
} catch (e) {
|
||||
this._error(e);
|
||||
return;
|
||||
}
|
||||
|
||||
this.write(this.framer.encack(this.bip151.toEncack()));
|
||||
|
||||
this.fire('encinit', payload);
|
||||
};
|
||||
|
||||
@ -1829,6 +1896,16 @@ Peer.prototype._handleEncinit = function _handleEncinit(payload) {
|
||||
*/
|
||||
|
||||
Peer.prototype._handleEncack = function _handleEncack(payload) {
|
||||
if (!this.bip151)
|
||||
return;
|
||||
|
||||
try {
|
||||
this.bip151.encack(payload);
|
||||
} catch (e) {
|
||||
this._error(e);
|
||||
return;
|
||||
}
|
||||
|
||||
this.fire('encack', payload);
|
||||
};
|
||||
|
||||
|
||||
@ -936,7 +936,11 @@ Framer.feeFilter = function feeFilter(data, writer) {
|
||||
*/
|
||||
|
||||
Framer.encinit = function encinit(data, writer) {
|
||||
return data.toEncinit(writer);
|
||||
if (writer) {
|
||||
writer.writeBytes(data);
|
||||
return writer;
|
||||
}
|
||||
return data;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -947,7 +951,11 @@ Framer.encinit = function encinit(data, writer) {
|
||||
*/
|
||||
|
||||
Framer.encack = function encack(data, writer) {
|
||||
return data.toEncack(writer);
|
||||
if (writer) {
|
||||
writer.writeBytes(data);
|
||||
return writer;
|
||||
}
|
||||
return data;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -705,6 +705,8 @@ function Packet(cmd, size, checksum) {
|
||||
this.payload = null;
|
||||
}
|
||||
|
||||
Parser.Packet = Packet;
|
||||
|
||||
/*
|
||||
* Expose
|
||||
*/
|
||||
|
||||
@ -10,7 +10,9 @@ var assert = require('assert');
|
||||
describe('BIP151', function() {
|
||||
var client = new bcoin.bip151();
|
||||
var server = new bcoin.bip151();
|
||||
var payload = new Buffer('deadbeef', 'hex');
|
||||
function payload() {
|
||||
return new Buffer('deadbeef', 'hex');
|
||||
}
|
||||
|
||||
it('should do encinit', function() {
|
||||
client.encinit(server.toEncinit());
|
||||
@ -34,7 +36,7 @@ describe('BIP151', function() {
|
||||
});
|
||||
|
||||
it('should encrypt payload from client to server', function() {
|
||||
var packet = client.packet('fake', payload);
|
||||
var packet = client.packet('fake', payload());
|
||||
var emitted = false;
|
||||
server.once('packet', function(cmd, body) {
|
||||
emitted = true;
|
||||
@ -46,7 +48,7 @@ describe('BIP151', function() {
|
||||
});
|
||||
|
||||
it('should encrypt payload from server to client', function() {
|
||||
var packet = server.packet('fake', payload);
|
||||
var packet = server.packet('fake', payload());
|
||||
var emitted = false;
|
||||
client.once('packet', function(cmd, body) {
|
||||
emitted = true;
|
||||
@ -58,7 +60,7 @@ describe('BIP151', function() {
|
||||
});
|
||||
|
||||
it('should encrypt payload from client to server (2)', function() {
|
||||
var packet = client.packet('fake', payload);
|
||||
var packet = client.packet('fake', payload());
|
||||
var emitted = false;
|
||||
server.once('packet', function(cmd, body) {
|
||||
emitted = true;
|
||||
@ -70,7 +72,7 @@ describe('BIP151', function() {
|
||||
});
|
||||
|
||||
it('should encrypt payload from server to client (2)', function() {
|
||||
var packet = server.packet('fake', payload);
|
||||
var packet = server.packet('fake', payload());
|
||||
var emitted = false;
|
||||
client.once('packet', function(cmd, body) {
|
||||
emitted = true;
|
||||
@ -83,7 +85,7 @@ describe('BIP151', function() {
|
||||
|
||||
it('client should rekey', function() {
|
||||
var rekeyed = false;
|
||||
var bytes = client.processed;
|
||||
var bytes = client.input.processed;
|
||||
|
||||
client.once('rekey', function() {
|
||||
rekeyed = true;
|
||||
@ -99,19 +101,19 @@ describe('BIP151', function() {
|
||||
});
|
||||
|
||||
// Force a rekey after 1gb processed.
|
||||
client.maybeRekey({ length: 1024 * (1 << 20) });
|
||||
client.input.maybeRekey({ length: 1024 * (1 << 20) });
|
||||
|
||||
utils.nextTick(function() {
|
||||
assert(rekeyed);
|
||||
|
||||
// Reset so as not to mess up
|
||||
// the symmetry of client and server.
|
||||
client.processed = bytes + 33 + 31;
|
||||
client.input.processed = bytes + 33 + 31;
|
||||
});
|
||||
});
|
||||
|
||||
it('should encrypt payload from client to server after rekey', function() {
|
||||
var packet = client.packet('fake', payload);
|
||||
var packet = client.packet('fake', payload());
|
||||
var emitted = false;
|
||||
server.once('packet', function(cmd, body) {
|
||||
emitted = true;
|
||||
@ -123,7 +125,7 @@ describe('BIP151', function() {
|
||||
});
|
||||
|
||||
it('should encrypt payload from server to client after rekey', function() {
|
||||
var packet = server.packet('fake', payload);
|
||||
var packet = server.packet('fake', payload());
|
||||
var emitted = false;
|
||||
client.once('packet', function(cmd, body) {
|
||||
emitted = true;
|
||||
@ -135,7 +137,7 @@ describe('BIP151', function() {
|
||||
});
|
||||
|
||||
it('should encrypt payload from client to server after rekey (2)', function() {
|
||||
var packet = client.packet('fake', payload);
|
||||
var packet = client.packet('fake', payload());
|
||||
var emitted = false;
|
||||
server.once('packet', function(cmd, body) {
|
||||
emitted = true;
|
||||
@ -147,7 +149,7 @@ describe('BIP151', function() {
|
||||
});
|
||||
|
||||
it('should encrypt payload from server to client after rekey (2)', function() {
|
||||
var packet = server.packet('fake', payload);
|
||||
var packet = server.packet('fake', payload());
|
||||
var emitted = false;
|
||||
client.once('packet', function(cmd, body) {
|
||||
emitted = true;
|
||||
@ -157,4 +159,25 @@ describe('BIP151', function() {
|
||||
client.feed(packet);
|
||||
assert(emitted);
|
||||
});
|
||||
|
||||
it('should encrypt payloads both ways asynchronously', function() {
|
||||
var spacket = server.packet('fake', payload());
|
||||
var cpacket = client.packet('fake', payload());
|
||||
var cemitted = false;
|
||||
var semitted = false;
|
||||
client.once('packet', function(cmd, body) {
|
||||
cemitted = true;
|
||||
assert.equal(cmd, 'fake');
|
||||
assert.equal(body.toString('hex'), 'deadbeef');
|
||||
});
|
||||
server.once('packet', function(cmd, body) {
|
||||
semitted = true;
|
||||
assert.equal(cmd, 'fake');
|
||||
assert.equal(body.toString('hex'), 'deadbeef');
|
||||
});
|
||||
client.feed(spacket);
|
||||
server.feed(cpacket);
|
||||
assert(cemitted);
|
||||
assert(semitted);
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user