diff --git a/package.json b/package.json index 9bf500f..f65a50e 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "@babel/preset-typescript": "^7.6.0", "@babel/register": "^7.6.2", "@babel/runtime": "^7.6.3", + "@types/bl": "^2.1.0", "@types/chai": "^4.2.4", "@types/mocha": "^5.2.7", "@typescript-eslint/eslint-plugin": "^2.6.0", diff --git a/src/encoder.ts b/src/encoder.ts index d8c93f7..477dbb8 100644 --- a/src/encoder.ts +++ b/src/encoder.ts @@ -4,7 +4,8 @@ import {MessageBuffer} from "./@types/handshake"; export const uint16BEEncode = (value, target, offset) => { target = target || Buffer.allocUnsafe(2); - return target.writeUInt16BE(value, offset); + target.writeUInt16BE(value, offset); + return target; }; uint16BEEncode.bytes = 2; diff --git a/src/noise.ts b/src/noise.ts index bf6c989..5a9c13c 100644 --- a/src/noise.ts +++ b/src/noise.ts @@ -4,7 +4,7 @@ import Wrap from 'it-pb-rpc'; import DuplexPair from 'it-pair/duplex'; import ensureBuffer from 'it-buffer'; import pipe from 'it-pipe'; -import lp from 'it-length-prefixed'; +import {encode, decode} from 'it-length-prefixed'; import {XXHandshake} from "./handshake-xx"; import {IKHandshake} from "./handshake-ik"; @@ -19,6 +19,7 @@ import {IHandshake} from "./@types/handshake-interface"; import {KeyCache} from "./keycache"; import {logger} from "./logger"; import PeerId from "peer-id"; +import {NOISE_MSG_MAX_LENGTH_BYTES} from "./constants"; export type WrappedConnection = ReturnType; @@ -66,7 +67,14 @@ export class Noise implements INoiseConnection { * @returns {Promise} */ public async secureOutbound(localPeer: PeerId, connection: any, remotePeer: PeerId): Promise { - const wrappedConnection = Wrap(connection); + const wrappedConnection = Wrap( + connection, + { + lengthEncoder: uint16BEEncode, + lengthDecoder: uint16BEDecode, + maxDataLength: NOISE_MSG_MAX_LENGTH_BYTES + } + ); const handshake = await this.performHandshake({ connection: wrappedConnection, isInitiator: true, @@ -89,7 +97,14 @@ export class Noise implements INoiseConnection { * @returns {Promise} */ public async secureInbound(localPeer: PeerId, connection: any, remotePeer?: PeerId): Promise { - const wrappedConnection = Wrap(connection); + const wrappedConnection = Wrap( + connection, + { + lengthEncoder: uint16BEEncode, + lengthDecoder: uint16BEDecode, + maxDataLength: NOISE_MSG_MAX_LENGTH_BYTES + } + ); const handshake = await this.performHandshake({ connection: wrappedConnection, isInitiator: false, @@ -213,9 +228,9 @@ export class Noise implements INoiseConnection { secure, // write to wrapper ensureBuffer, // ensure any type of data is converted to buffer encryptStream(handshake), // data is encrypted - lp.encode({ lengthEncoder: uint16BEEncode }), // prefix with message length + encode({ lengthEncoder: uint16BEEncode }), // prefix with message length network, // send to the remote peer - lp.decode({ lengthDecoder: uint16BEDecode }), // read message length prefix + decode({ lengthDecoder: uint16BEDecode, maxDataLength: NOISE_MSG_MAX_LENGTH_BYTES }), // read message length prefix ensureBuffer, // ensure any type of data is converted to buffer decryptStream(handshake), // decrypt the incoming data secure // pipe to the wrapper diff --git a/test/noise.test.ts b/test/noise.test.ts index dcee669..fa63b17 100644 --- a/test/noise.test.ts +++ b/test/noise.test.ts @@ -13,12 +13,13 @@ import { getHandshakePayload, getPayload, signPayload } from "../src/utils"; -import {decode0, decode1, encode1} from "../src/encoder"; +import {decode0, decode1, encode1, uint16BEDecode, uint16BEEncode} from "../src/encoder"; import {XX} from "../src/handshakes/xx"; import {Buffer} from "buffer"; import {getKeyPairFromPeerId} from "./utils"; import {KeyCache} from "../src/keycache"; -import {XXFallbackHandshake} from "../src/handshake-xx-fallback"; +import {NOISE_MSG_MAX_LENGTH_BYTES} from "../src/constants"; +import BufferList from "bl"; describe("Noise", () => { let remotePeer, localPeer; @@ -60,7 +61,14 @@ describe("Noise", () => { const [outbound, { wrapped, handshake }] = await Promise.all([ noiseInit.secureOutbound(localPeer, outboundConnection, remotePeer), (async () => { - const wrapped = Wrap(inboundConnection); + const wrapped = Wrap( + inboundConnection, + { + lengthEncoder: uint16BEEncode, + lengthDecoder: uint16BEDecode, + maxDataLength: NOISE_MSG_MAX_LENGTH_BYTES + } + ); const prologue = Buffer.alloc(0); const staticKeys = generateKeypair(); const xx = new XX(); @@ -90,7 +98,7 @@ describe("Noise", () => { try { const wrappedOutbound = Wrap(outbound.conn); - wrappedOutbound.write(Buffer.from("test")); + wrappedOutbound.write(new BufferList([Buffer.from("test")])); // Check that noise message is prefixed with 16-bit big-endian unsigned integer const receivedEncryptedPayload = (await wrapped.read()).slice(); diff --git a/yarn.lock b/yarn.lock index 59418cd..8f63fb4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1049,6 +1049,13 @@ resolved "https://registry.yarnpkg.com/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz#8da5c6530915653f3a1f38fd5f101d8c3f8079c5" integrity sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ== +"@types/bl@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@types/bl/-/bl-2.1.0.tgz#45c881c97feae1223d63bbc5b83166153fcb2a15" + integrity sha512-1TdA9IXOy4sdqn8vgieQ6GZAiHiPNrOiO1s2GJjuYPw4QVY7gYoVjkW049avj33Ez7IcIvu43hQsMsoUFbCn2g== + dependencies: + "@types/node" "*" + "@types/chai@^4.2.4": version "4.2.4" resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.2.4.tgz#8936cffad3c96ec470a2dc26a38c3ba8b9b6f619" @@ -1074,6 +1081,11 @@ resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-5.2.7.tgz#315d570ccb56c53452ff8638738df60726d5b6ea" integrity sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ== +"@types/node@*": + version "13.7.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-13.7.1.tgz#238eb34a66431b71d2aaddeaa7db166f25971a0d" + integrity sha512-Zq8gcQGmn4txQEJeiXo/KiLpon8TzAl0kmKH4zdWctPj05nWwp1ClMdAVEloqrQKfaC48PNLdgN/aVaLqUrluA== + "@types/node@^10.1.0": version "10.17.3" resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.3.tgz#65a8d9a6a0f6af55595a2d0020617959130d6495"