From b5df5e80d17b4369e00907d6f0f23a48f4f70181 Mon Sep 17 00:00:00 2001 From: Marin Petrunic Date: Wed, 10 Aug 2022 16:23:17 +0200 Subject: [PATCH 1/2] chore: update protons and connection encryption interface --- package.json | 17 ++++----- src/noise.ts | 8 ++--- src/proto/payload.ts | 84 +++++++++++++++++++++++++++++++++++++++----- 3 files changed, 89 insertions(+), 20 deletions(-) diff --git a/package.json b/package.json index 5506500..784c0b6 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,7 @@ }, "dependencies": { "@libp2p/crypto": "^1.0.0", - "@libp2p/interface-connection-encrypter": "^1.0.2", + "@libp2p/interface-connection-encrypter": "^2.0.1", "@libp2p/interface-keys": "^1.0.2", "@libp2p/interface-peer-id": "^1.0.2", "@libp2p/logger": "^2.0.0", @@ -78,22 +78,23 @@ "@stablelib/x25519": "^1.0.1", "it-length-prefixed": "^8.0.2", "it-pair": "^2.0.2", + "it-stream-types": "^1.0.4", "it-pb-stream": "^2.0.1", "it-pipe": "^2.0.3", - "it-stream-types": "^1.0.4", - "protons-runtime": "^2.0.1", - "uint8arraylist": "^2.0.0", - "uint8arrays": "^3.0.0" + "protons-runtime": "^3.0.1", + "uint8arraylist": "^2.3.2", + "uint8arrays": "^3.1.0" }, "devDependencies": { - "@libp2p/interface-connection-encrypter-compliance-tests": "^1.0.1", + "@libp2p/interface-connection-encrypter-compliance-tests": "^2.0.1", "@libp2p/peer-id-factory": "^1.0.8", "aegir": "^37.3.0", "benchmark": "^2.1.4", "iso-random-stream": "^2.0.2", "mkdirp": "^1.0.4", - "protons": "^4.0.0", - "sinon": "^14.0.0" + "protons": "^5.0.0", + "sinon": "^14.0.0", + "util": "^0.12.4" }, "browser": { "./dist/src/alloc-unsafe.js": "./dist/src/alloc-unsafe-browser.js", diff --git a/src/noise.ts b/src/noise.ts index d049913..65e9c94 100644 --- a/src/noise.ts +++ b/src/noise.ts @@ -52,11 +52,11 @@ export class Noise implements INoiseConnection { * Encrypt outgoing data to the remote party (handshake as initiator) * * @param {PeerId} localPeer - PeerId of the receiving peer - * @param {any} connection - streaming iterable duplex that will be encrypted + * @param {Duplex} connection - streaming iterable duplex that will be encrypted * @param {PeerId} remotePeer - PeerId of the remote peer. Used to validate the integrity of the remote peer. * @returns {Promise} */ - public async secureOutbound (localPeer: PeerId, connection: any, remotePeer: PeerId): Promise { + public async secureOutbound (localPeer: PeerId, connection: Duplex, remotePeer: PeerId): Promise { const wrappedConnection = pbStream( connection, { @@ -84,11 +84,11 @@ export class Noise implements INoiseConnection { * Decrypt incoming data (handshake as responder). * * @param {PeerId} localPeer - PeerId of the receiving peer. - * @param {any} connection - streaming iterable duplex that will be encryption. + * @param {Duplex} connection - streaming iterable duplex that will be encryption. * @param {PeerId} remotePeer - optional PeerId of the initiating peer, if known. This may only exist during transport upgrades. * @returns {Promise} */ - public async secureInbound (localPeer: PeerId, connection: any, remotePeer?: PeerId): Promise { + public async secureInbound (localPeer: PeerId, connection: Duplex, remotePeer?: PeerId): Promise { const wrappedConnection = pbStream( connection, { diff --git a/src/proto/payload.ts b/src/proto/payload.ts index 1c75bc4..0bdada6 100644 --- a/src/proto/payload.ts +++ b/src/proto/payload.ts @@ -1,9 +1,9 @@ /* eslint-disable import/export */ /* eslint-disable @typescript-eslint/no-namespace */ -import { encodeMessage, decodeMessage, message, bytes } from 'protons-runtime' -import type { Codec } from 'protons-runtime' +import { encodeMessage, decodeMessage, message } from 'protons-runtime' import type { Uint8ArrayList } from 'uint8arraylist' +import type { Codec } from 'protons-runtime' export namespace pb { export interface NoiseHandshakePayload { @@ -13,15 +13,83 @@ export namespace pb { } export namespace NoiseHandshakePayload { + let _codec: Codec + export const codec = (): Codec => { - return message({ - 1: { name: 'identityKey', codec: bytes }, - 2: { name: 'identitySig', codec: bytes }, - 3: { name: 'data', codec: bytes } - }) + if (_codec == null) { + _codec = message((obj, writer, opts = {}) => { + if (opts.lengthDelimited !== false) { + writer.fork() + } + + if (obj.identityKey != null) { + writer.uint32(10) + writer.bytes(obj.identityKey) + } else { + throw new Error('Protocol error: required field "identityKey" was not found in object') + } + + if (obj.identitySig != null) { + writer.uint32(18) + writer.bytes(obj.identitySig) + } else { + throw new Error('Protocol error: required field "identitySig" was not found in object') + } + + if (obj.data != null) { + writer.uint32(26) + writer.bytes(obj.data) + } else { + throw new Error('Protocol error: required field "data" was not found in object') + } + + if (opts.lengthDelimited !== false) { + writer.ldelim() + } + }, (reader, length) => { + const obj: any = {} + + const end = length == null ? reader.len : reader.pos + length + + while (reader.pos < end) { + const tag = reader.uint32() + + switch (tag >>> 3) { + case 1: + obj.identityKey = reader.bytes() + break + case 2: + obj.identitySig = reader.bytes() + break + case 3: + obj.data = reader.bytes() + break + default: + reader.skipType(tag & 7) + break + } + } + + if (obj.identityKey == null) { + throw new Error('Protocol error: value for required field "identityKey" was not found in protobuf') + } + + if (obj.identitySig == null) { + throw new Error('Protocol error: value for required field "identitySig" was not found in protobuf') + } + + if (obj.data == null) { + throw new Error('Protocol error: value for required field "data" was not found in protobuf') + } + + return obj + }) + } + + return _codec } - export const encode = (obj: NoiseHandshakePayload): Uint8ArrayList => { + export const encode = (obj: NoiseHandshakePayload): Uint8Array => { return encodeMessage(obj, NoiseHandshakePayload.codec()) } From 912efe2a95fa33db7898ad3ffa901677d81a51a6 Mon Sep 17 00:00:00 2001 From: Marin Petrunic Date: Thu, 11 Aug 2022 10:58:12 +0200 Subject: [PATCH 2/2] address PR comments --- package.json | 6 +++--- src/proto/payload.ts | 6 +++++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 784c0b6..5474c96 100644 --- a/package.json +++ b/package.json @@ -79,9 +79,9 @@ "it-length-prefixed": "^8.0.2", "it-pair": "^2.0.2", "it-stream-types": "^1.0.4", - "it-pb-stream": "^2.0.1", + "it-pb-stream": "^2.0.2", "it-pipe": "^2.0.3", - "protons-runtime": "^3.0.1", + "protons-runtime": "^3.1.0", "uint8arraylist": "^2.3.2", "uint8arrays": "^3.1.0" }, @@ -92,7 +92,7 @@ "benchmark": "^2.1.4", "iso-random-stream": "^2.0.2", "mkdirp": "^1.0.4", - "protons": "^5.0.0", + "protons": "^5.1.0", "sinon": "^14.0.0", "util": "^0.12.4" }, diff --git a/src/proto/payload.ts b/src/proto/payload.ts index 0bdada6..0d1af33 100644 --- a/src/proto/payload.ts +++ b/src/proto/payload.ts @@ -47,7 +47,11 @@ export namespace pb { writer.ldelim() } }, (reader, length) => { - const obj: any = {} + const obj: any = { + identityKey: new Uint8Array(0), + identitySig: new Uint8Array(0), + data: new Uint8Array(0) + } const end = length == null ? reader.len : reader.pos + length