@libp2p/pnet 2.0.47-8484de8a2 → 2.0.47-87bc8d4fb

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,24 +1,13 @@
1
- import { AbstractMultiaddrConnection } from '@libp2p/utils';
2
- import type { AbortOptions, MultiaddrConnection } from '@libp2p/interface';
3
- import type { MessageStreamInit, SendResult } from '@libp2p/utils';
1
+ import type { Source } from 'it-stream-types';
4
2
  import type { Uint8ArrayList } from 'uint8arraylist';
5
- export interface BoxMessageStreamInit extends MessageStreamInit {
6
- maConn: MultiaddrConnection;
7
- localNonce: Uint8Array;
8
- remoteNonce: Uint8Array;
9
- psk: Uint8Array;
10
- }
11
- export declare class BoxMessageStream extends AbstractMultiaddrConnection {
12
- private maConn;
13
- private inboundXor;
14
- private outboundXor;
15
- constructor(init: BoxMessageStreamInit);
16
- sendClose(options?: AbortOptions): Promise<void>;
17
- sendData(data: Uint8ArrayList): SendResult;
18
- sendReset(err: Error): void;
19
- sendPause(): void;
20
- sendResume(): void;
21
- }
3
+ /**
4
+ * Creates a stream iterable to encrypt messages in a private network
5
+ */
6
+ export declare function createBoxStream(nonce: Uint8Array, psk: Uint8Array): (source: Source<Uint8Array | Uint8ArrayList>) => AsyncGenerator<Uint8Array | Uint8ArrayList>;
7
+ /**
8
+ * Creates a stream iterable to decrypt messages in a private network
9
+ */
10
+ export declare function createUnboxStream(nonce: Uint8Array, psk: Uint8Array): (source: Source<Uint8Array>) => AsyncGenerator<Uint8Array<ArrayBuffer>, void, unknown>;
22
11
  /**
23
12
  * Decode the version 1 psk from the given Uint8Array
24
13
  */
@@ -1 +1 @@
1
- {"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../../src/crypto.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,MAAM,eAAe,CAAA;AAM3D,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AAC1E,OAAO,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAClE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAEpD,MAAM,WAAW,oBAAqB,SAAQ,iBAAiB;IAC7D,MAAM,EAAE,mBAAmB,CAAA;IAC3B,UAAU,EAAE,UAAU,CAAA;IACtB,WAAW,EAAE,UAAU,CAAA;IACvB,GAAG,EAAE,UAAU,CAAA;CAChB;AAED,qBAAa,gBAAiB,SAAQ,2BAA2B;IAC/D,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,UAAU,CAAc;IAChC,OAAO,CAAC,WAAW,CAAc;gBAEpB,IAAI,EAAE,oBAAoB;IAoCjC,SAAS,CAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvD,QAAQ,CAAE,IAAI,EAAE,cAAc,GAAG,UAAU;IAO3C,SAAS,CAAE,GAAG,EAAE,KAAK,GAAG,IAAI;IAI5B,SAAS,IAAK,IAAI;IAIlB,UAAU,IAAK,IAAI;CAGpB;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAE,SAAS,EAAE,UAAU,GAAG;IAAE,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,GAAG,EAAE,UAAU,CAAA;CAAE,CAyB/H"}
1
+ {"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../../src/crypto.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAC7C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAEpD;;GAEG;AACH,wBAAgB,eAAe,CAAE,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,UAAU,GAAG,cAAc,CAAC,KAAK,cAAc,CAAC,UAAU,GAAG,cAAc,CAAC,CAQjK;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAE,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,IAC3D,QAAQ,MAAM,CAAC,UAAU,CAAC,4DAOnC;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAE,SAAS,EAAE,UAAU,GAAG;IAAE,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,GAAG,EAAE,UAAU,CAAA;CAAE,CAyB/H"}
@@ -1,65 +1,29 @@
1
- import { AbstractMultiaddrConnection } from '@libp2p/utils';
2
1
  import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string';
3
2
  import { toString as uint8ArrayToString } from 'uint8arrays/to-string';
4
3
  import xsalsa20 from 'xsalsa20';
5
4
  import * as Errors from './errors.js';
6
5
  import { KEY_LENGTH } from './key-generator.js';
7
- export class BoxMessageStream extends AbstractMultiaddrConnection {
8
- maConn;
9
- inboundXor;
10
- outboundXor;
11
- constructor(init) {
12
- super({
13
- ...init,
14
- remoteAddr: init.maConn.remoteAddr,
15
- direction: init.maConn.direction
16
- });
17
- this.inboundXor = xsalsa20(init.remoteNonce, init.psk);
18
- this.outboundXor = xsalsa20(init.localNonce, init.psk);
19
- this.maConn = init.maConn;
20
- this.maConn.addEventListener('message', (evt) => {
21
- const data = evt.data;
22
- if (data instanceof Uint8Array) {
23
- this.onData(this.inboundXor.update(data));
24
- }
25
- else {
26
- for (const buf of data) {
27
- this.onData(this.inboundXor.update(buf));
28
- }
29
- }
30
- });
31
- this.maConn.addEventListener('close', (evt) => {
32
- if (evt.error != null) {
33
- if (evt.local) {
34
- this.abort(evt.error);
35
- }
36
- else {
37
- this.onRemoteReset();
38
- }
39
- }
40
- else {
41
- this.onTransportClosed();
42
- }
43
- });
44
- }
45
- async sendClose(options) {
46
- await this.maConn.close(options);
47
- }
48
- sendData(data) {
49
- return {
50
- sentBytes: data.byteLength,
51
- canSendMore: this.maConn.send(this.outboundXor.update(data.subarray()))
52
- };
53
- }
54
- sendReset(err) {
55
- this.maConn.abort(err);
56
- }
57
- sendPause() {
58
- this.maConn.pause();
59
- }
60
- sendResume() {
61
- this.maConn.resume();
62
- }
6
+ /**
7
+ * Creates a stream iterable to encrypt messages in a private network
8
+ */
9
+ export function createBoxStream(nonce, psk) {
10
+ const xor = xsalsa20(nonce, psk);
11
+ return (source) => (async function* () {
12
+ for await (const chunk of source) {
13
+ yield Uint8Array.from(xor.update(chunk.subarray()));
14
+ }
15
+ })();
16
+ }
17
+ /**
18
+ * Creates a stream iterable to decrypt messages in a private network
19
+ */
20
+ export function createUnboxStream(nonce, psk) {
21
+ return (source) => (async function* () {
22
+ const xor = xsalsa20(nonce, psk);
23
+ for await (const chunk of source) {
24
+ yield Uint8Array.from(xor.update(chunk.subarray()));
25
+ }
26
+ })();
63
27
  }
64
28
  /**
65
29
  * Decode the version 1 psk from the given Uint8Array
@@ -1 +1 @@
1
- {"version":3,"file":"crypto.js","sourceRoot":"","sources":["../../src/crypto.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"crypto.js","sourceRoot":"","sources":["../../src/crypto.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,IAAI,oBAAoB,EAAE,MAAM,yBAAyB,CAAA;AAC5E,OAAO,EAAE,QAAQ,IAAI,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AACtE,OAAO,QAAQ,MAAM,UAAU,CAAA;AAC/B,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAI/C;;GAEG;AACH,MAAM,UAAU,eAAe,CAAE,KAAiB,EAAE,GAAe;IACjE,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;IAEhC,OAAO,CAAC,MAA2C,EAAE,EAAE,CAAC,CAAC,KAAK,SAAU,CAAC;QACvE,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YACjC,MAAM,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAA;QACrD,CAAC;IACH,CAAC,CAAC,EAAE,CAAA;AACN,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAE,KAAiB,EAAE,GAAe;IACnE,OAAO,CAAC,MAA0B,EAAE,EAAE,CAAC,CAAC,KAAK,SAAU,CAAC;QACtD,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;QAEhC,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YACjC,MAAM,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAA;QACrD,CAAC;IACH,CAAC,CAAC,EAAE,CAAA;AACN,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAE,SAAqB;IAChD,IAAI,CAAC;QACH,0DAA0D;QAC1D,6DAA6D;QAC7D,yDAAyD;QACzD,2DAA2D;QAC3D,0BAA0B;QAC1B,MAAM,QAAQ,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAA;QACvE,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAA;QAC/B,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAA;QAC9B,MAAM,SAAS,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAA;QAClC,MAAM,GAAG,GAAG,oBAAoB,CAAC,SAAS,IAAI,EAAE,EAAE,QAAQ,CAAC,CAAA;QAE3D,IAAI,GAAG,CAAC,UAAU,KAAK,UAAU,EAAE,CAAC;YAClC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,CAAA;QACrC,CAAC;QAED,OAAO;YACL,GAAG,EAAE,MAAM;YACX,SAAS,EAAE,KAAK;YAChB,GAAG;SACJ,CAAA;IACH,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,CAAA;IACrC,CAAC;AACH,CAAC"}
@@ -73,5 +73,5 @@ export interface ProtectorInit {
73
73
  export interface ProtectorComponents {
74
74
  logger: ComponentLogger;
75
75
  }
76
- export declare function preSharedKey(init: ProtectorInit): () => ConnectionProtector;
76
+ export declare function preSharedKey(init: ProtectorInit): (components: ProtectorComponents) => ConnectionProtector;
77
77
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AAOH,OAAO,KAAK,EAAE,eAAe,EAAE,mBAAmB,EAAqC,MAAM,mBAAmB,CAAA;AAEhH,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAEhD,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,GAAG,EAAE,UAAU,CAAA;IACf;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,eAAe,CAAA;CACxB;AAqED,wBAAgB,YAAY,CAAE,IAAI,EAAE,aAAa,GAAG,MAAM,mBAAmB,CAE5E"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AAcH,OAAO,KAAK,EAAE,eAAe,EAAU,mBAAmB,EAAuB,MAAM,mBAAmB,CAAA;AAG1G,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAEhD,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,GAAG,EAAE,UAAU,CAAA;IACf;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,eAAe,CAAA;CACxB;AA4ED,wBAAgB,YAAY,CAAE,IAAI,EAAE,aAAa,GAAG,CAAC,UAAU,EAAE,mBAAmB,KAAK,mBAAmB,CAE3G"}
package/dist/src/index.js CHANGED
@@ -57,19 +57,24 @@
57
57
  */
58
58
  import { randomBytes } from '@libp2p/crypto';
59
59
  import { InvalidParametersError } from '@libp2p/interface';
60
- import { byteStream } from '@libp2p/utils';
61
- import { BoxMessageStream, decodeV1PSK } from './crypto.js';
60
+ import { byteStream } from 'it-byte-stream';
61
+ import map from 'it-map';
62
+ import { duplexPair } from 'it-pair/duplex';
63
+ import { pipe } from 'it-pipe';
64
+ import { createBoxStream, createUnboxStream, decodeV1PSK } from './crypto.js';
62
65
  import { NONCE_LENGTH } from './key-generator.js';
63
66
  export { generateKey } from './key-generator.js';
64
67
  class PreSharedKeyConnectionProtector {
65
68
  tag;
69
+ log;
66
70
  psk;
67
71
  timeout;
68
72
  /**
69
73
  * Takes a Private Shared Key (psk) and provides a `protect` method
70
74
  * for wrapping existing connections in a private encryption stream.
71
75
  */
72
- constructor(init) {
76
+ constructor(components, init) {
77
+ this.log = components.logger.forComponent('libp2p:pnet');
73
78
  this.timeout = init.timeout ?? 1000;
74
79
  const decodedPSK = decodeV1PSK(init.psk);
75
80
  this.psk = decodedPSK.psk;
@@ -81,40 +86,40 @@ class PreSharedKeyConnectionProtector {
81
86
  * between its two peers from the PSK the Protector instance was
82
87
  * created with.
83
88
  */
84
- async protect(connection, options) {
89
+ async protect(connection) {
85
90
  if (connection == null) {
86
91
  throw new InvalidParametersError('No connection for the handshake provided');
87
92
  }
88
93
  // Exchange nonces
89
- const log = connection.log.newScope('pnet');
90
- log('protecting the connection');
94
+ this.log('protecting the connection');
91
95
  const localNonce = randomBytes(NONCE_LENGTH);
92
- if (options == null) {
93
- options = {
94
- signal: AbortSignal.timeout(this.timeout)
95
- };
96
- }
96
+ const signal = AbortSignal.timeout(this.timeout);
97
97
  const bytes = byteStream(connection);
98
- const [result] = await Promise.all([
98
+ const [, result] = await Promise.all([
99
+ bytes.write(localNonce, {
100
+ signal
101
+ }),
99
102
  bytes.read({
100
103
  bytes: NONCE_LENGTH,
101
- ...options
102
- }),
103
- bytes.write(localNonce, options)
104
+ signal
105
+ })
104
106
  ]);
105
107
  const remoteNonce = result.subarray();
106
108
  // Create the boxing/unboxing pipe
107
- log('exchanged nonces');
108
- return new BoxMessageStream({
109
- localNonce,
110
- remoteNonce,
111
- psk: this.psk,
112
- maConn: connection,
113
- log
114
- });
109
+ this.log('exchanged nonces');
110
+ const [internal, external] = duplexPair();
111
+ pipe(external,
112
+ // Encrypt all outbound traffic
113
+ createBoxStream(localNonce, this.psk), bytes.unwrap(), (source) => map(source, (buf) => buf.subarray()),
114
+ // Decrypt all inbound traffic
115
+ createUnboxStream(remoteNonce, this.psk), external).catch(this.log.error);
116
+ return {
117
+ ...connection,
118
+ ...internal
119
+ };
115
120
  }
116
121
  }
117
122
  export function preSharedKey(init) {
118
- return () => new PreSharedKeyConnectionProtector(init);
123
+ return (components) => new PreSharedKeyConnectionProtector(components, init);
119
124
  }
120
125
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAC5C,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAA;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAC1C,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAGjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAoBhD,MAAM,+BAA+B;IAC5B,GAAG,CAAQ;IACD,GAAG,CAAY;IACf,OAAO,CAAQ;IAEhC;;;OAGG;IACH,YAAa,IAAmB;QAC9B,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,IAAI,CAAA;QAEnC,MAAM,UAAU,GAAG,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACxC,IAAI,CAAC,GAAG,GAAG,UAAU,CAAC,GAAG,CAAA;QACzB,IAAI,CAAC,GAAG,GAAG,UAAU,CAAC,GAAG,IAAI,EAAE,CAAA;IACjC,CAAC;IAEQ,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,cAAc,CAAA;IAE9C;;;;OAIG;IACH,KAAK,CAAC,OAAO,CAAE,UAA+B,EAAE,OAAsB;QACpE,IAAI,UAAU,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,IAAI,sBAAsB,CAAC,0CAA0C,CAAC,CAAA;QAC9E,CAAC;QAED,kBAAkB;QAClB,MAAM,GAAG,GAAG,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;QAC3C,GAAG,CAAC,2BAA2B,CAAC,CAAA;QAChC,MAAM,UAAU,GAAG,WAAW,CAAC,YAAY,CAAC,CAAA;QAE5C,IAAI,OAAO,IAAI,IAAI,EAAE,CAAC;YACpB,OAAO,GAAG;gBACR,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;aAC1C,CAAA;QACH,CAAC;QAED,MAAM,KAAK,GAAG,UAAU,CAAC,UAAU,CAAC,CAAA;QAEpC,MAAM,CACJ,MAAM,CACP,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YACpB,KAAK,CAAC,IAAI,CAAC;gBACT,KAAK,EAAE,YAAY;gBACnB,GAAG,OAAO;aACX,CAAC;YACF,KAAK,CAAC,KAAK,CAAC,UAAU,EAAE,OAAO,CAAC;SACjC,CAAC,CAAA;QAEF,MAAM,WAAW,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAA;QAErC,kCAAkC;QAClC,GAAG,CAAC,kBAAkB,CAAC,CAAA;QAEvB,OAAO,IAAI,gBAAgB,CAAC;YAC1B,UAAU;YACV,WAAW;YACX,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,MAAM,EAAE,UAAU;YAClB,GAAG;SACJ,CAAC,CAAA;IACJ,CAAC;CACF;AAED,MAAM,UAAU,YAAY,CAAE,IAAmB;IAC/C,OAAO,GAAG,EAAE,CAAC,IAAI,+BAA+B,CAAC,IAAI,CAAC,CAAA;AACxD,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@libp2p/pnet",
3
- "version": "2.0.47-8484de8a2",
3
+ "version": "2.0.47-87bc8d4fb",
4
4
  "description": "Implementation of Connection protection management via a shared secret",
5
5
  "license": "Apache-2.0 OR MIT",
6
6
  "homepage": "https://github.com/libp2p/js-libp2p/tree/main/packages/pnet#readme",
@@ -43,17 +43,25 @@
43
43
  "doc-check": "aegir doc-check"
44
44
  },
45
45
  "dependencies": {
46
- "@libp2p/crypto": "5.1.8-8484de8a2",
47
- "@libp2p/interface": "2.11.0-8484de8a2",
48
- "@libp2p/utils": "6.7.2-8484de8a2",
46
+ "@libp2p/crypto": "5.1.8-87bc8d4fb",
47
+ "@libp2p/interface": "2.11.0-87bc8d4fb",
48
+ "it-byte-stream": "^2.0.2",
49
+ "it-map": "^3.1.3",
50
+ "it-pair": "^2.0.6",
51
+ "it-pipe": "^3.0.1",
52
+ "it-stream-types": "^2.0.2",
49
53
  "uint8arraylist": "^2.4.8",
50
54
  "uint8arrays": "^5.1.0",
51
55
  "xsalsa20": "^1.2.0"
52
56
  },
53
57
  "devDependencies": {
58
+ "@libp2p/interface-compliance-tests": "6.5.0-87bc8d4fb",
59
+ "@libp2p/logger": "5.2.0-87bc8d4fb",
60
+ "@libp2p/peer-id": "5.1.9-87bc8d4fb",
61
+ "@multiformats/multiaddr": "^12.4.4",
54
62
  "@types/xsalsa20": "^1.1.3",
55
- "aegir": "^47.0.21",
56
- "p-event": "^6.0.1"
63
+ "aegir": "^47.0.14",
64
+ "it-all": "^3.0.8"
57
65
  },
58
66
  "sideEffects": false
59
67
  }
package/src/crypto.ts CHANGED
@@ -1,83 +1,35 @@
1
- import { AbstractMultiaddrConnection } from '@libp2p/utils'
2
1
  import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
3
2
  import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
4
3
  import xsalsa20 from 'xsalsa20'
5
4
  import * as Errors from './errors.js'
6
5
  import { KEY_LENGTH } from './key-generator.js'
7
- import type { AbortOptions, MultiaddrConnection } from '@libp2p/interface'
8
- import type { MessageStreamInit, SendResult } from '@libp2p/utils'
6
+ import type { Source } from 'it-stream-types'
9
7
  import type { Uint8ArrayList } from 'uint8arraylist'
10
8
 
11
- export interface BoxMessageStreamInit extends MessageStreamInit {
12
- maConn: MultiaddrConnection
13
- localNonce: Uint8Array
14
- remoteNonce: Uint8Array
15
- psk: Uint8Array
16
- }
17
-
18
- export class BoxMessageStream extends AbstractMultiaddrConnection {
19
- private maConn: MultiaddrConnection
20
- private inboundXor: xsalsa20.Xor
21
- private outboundXor: xsalsa20.Xor
22
-
23
- constructor (init: BoxMessageStreamInit) {
24
- super({
25
- ...init,
26
- remoteAddr: init.maConn.remoteAddr,
27
- direction: init.maConn.direction
28
- })
29
-
30
- this.inboundXor = xsalsa20(init.remoteNonce, init.psk)
31
- this.outboundXor = xsalsa20(init.localNonce, init.psk)
32
- this.maConn = init.maConn
33
-
34
- this.maConn.addEventListener('message', (evt) => {
35
- const data = evt.data
36
-
37
- if (data instanceof Uint8Array) {
38
- this.onData(this.inboundXor.update(data))
39
- } else {
40
- for (const buf of data) {
41
- this.onData(this.inboundXor.update(buf))
42
- }
43
- }
44
- })
45
-
46
- this.maConn.addEventListener('close', (evt) => {
47
- if (evt.error != null) {
48
- if (evt.local) {
49
- this.abort(evt.error)
50
- } else {
51
- this.onRemoteReset()
52
- }
53
- } else {
54
- this.onTransportClosed()
55
- }
56
- })
57
- }
58
-
59
- async sendClose (options?: AbortOptions): Promise<void> {
60
- await this.maConn.close(options)
61
- }
9
+ /**
10
+ * Creates a stream iterable to encrypt messages in a private network
11
+ */
12
+ export function createBoxStream (nonce: Uint8Array, psk: Uint8Array): (source: Source<Uint8Array | Uint8ArrayList>) => AsyncGenerator<Uint8Array | Uint8ArrayList> {
13
+ const xor = xsalsa20(nonce, psk)
62
14
 
63
- sendData (data: Uint8ArrayList): SendResult {
64
- return {
65
- sentBytes: data.byteLength,
66
- canSendMore: this.maConn.send(this.outboundXor.update(data.subarray()))
15
+ return (source: Source<Uint8Array | Uint8ArrayList>) => (async function * () {
16
+ for await (const chunk of source) {
17
+ yield Uint8Array.from(xor.update(chunk.subarray()))
67
18
  }
68
- }
69
-
70
- sendReset (err: Error): void {
71
- this.maConn.abort(err)
72
- }
19
+ })()
20
+ }
73
21
 
74
- sendPause (): void {
75
- this.maConn.pause()
76
- }
22
+ /**
23
+ * Creates a stream iterable to decrypt messages in a private network
24
+ */
25
+ export function createUnboxStream (nonce: Uint8Array, psk: Uint8Array) {
26
+ return (source: Source<Uint8Array>) => (async function * () {
27
+ const xor = xsalsa20(nonce, psk)
77
28
 
78
- sendResume (): void {
79
- this.maConn.resume()
80
- }
29
+ for await (const chunk of source) {
30
+ yield Uint8Array.from(xor.update(chunk.subarray()))
31
+ }
32
+ })()
81
33
  }
82
34
 
83
35
  /**
package/src/index.ts CHANGED
@@ -58,10 +58,18 @@
58
58
 
59
59
  import { randomBytes } from '@libp2p/crypto'
60
60
  import { InvalidParametersError } from '@libp2p/interface'
61
- import { byteStream } from '@libp2p/utils'
62
- import { BoxMessageStream, decodeV1PSK } from './crypto.js'
61
+ import { byteStream } from 'it-byte-stream'
62
+ import map from 'it-map'
63
+ import { duplexPair } from 'it-pair/duplex'
64
+ import { pipe } from 'it-pipe'
65
+ import {
66
+ createBoxStream,
67
+ createUnboxStream,
68
+ decodeV1PSK
69
+ } from './crypto.js'
63
70
  import { NONCE_LENGTH } from './key-generator.js'
64
- import type { ComponentLogger, ConnectionProtector, MultiaddrConnection, AbortOptions } from '@libp2p/interface'
71
+ import type { ComponentLogger, Logger, ConnectionProtector, MultiaddrConnection } from '@libp2p/interface'
72
+ import type { Uint8ArrayList } from 'uint8arraylist'
65
73
 
66
74
  export { generateKey } from './key-generator.js'
67
75
 
@@ -85,6 +93,7 @@ export interface ProtectorComponents {
85
93
 
86
94
  class PreSharedKeyConnectionProtector implements ConnectionProtector {
87
95
  public tag: string
96
+ private readonly log: Logger
88
97
  private readonly psk: Uint8Array
89
98
  private readonly timeout: number
90
99
 
@@ -92,7 +101,8 @@ class PreSharedKeyConnectionProtector implements ConnectionProtector {
92
101
  * Takes a Private Shared Key (psk) and provides a `protect` method
93
102
  * for wrapping existing connections in a private encryption stream.
94
103
  */
95
- constructor (init: ProtectorInit) {
104
+ constructor (components: ProtectorComponents, init: ProtectorInit) {
105
+ this.log = components.logger.forComponent('libp2p:pnet')
96
106
  this.timeout = init.timeout ?? 1000
97
107
 
98
108
  const decodedPSK = decodeV1PSK(init.psk)
@@ -107,49 +117,54 @@ class PreSharedKeyConnectionProtector implements ConnectionProtector {
107
117
  * between its two peers from the PSK the Protector instance was
108
118
  * created with.
109
119
  */
110
- async protect (connection: MultiaddrConnection, options?: AbortOptions): Promise<MultiaddrConnection> {
120
+ async protect (connection: MultiaddrConnection): Promise<MultiaddrConnection> {
111
121
  if (connection == null) {
112
122
  throw new InvalidParametersError('No connection for the handshake provided')
113
123
  }
114
124
 
115
125
  // Exchange nonces
116
- const log = connection.log.newScope('pnet')
117
- log('protecting the connection')
126
+ this.log('protecting the connection')
118
127
  const localNonce = randomBytes(NONCE_LENGTH)
119
128
 
120
- if (options == null) {
121
- options = {
122
- signal: AbortSignal.timeout(this.timeout)
123
- }
124
- }
129
+ const signal = AbortSignal.timeout(this.timeout)
125
130
 
126
131
  const bytes = byteStream(connection)
127
132
 
128
133
  const [
129
- result
134
+ , result
130
135
  ] = await Promise.all([
136
+ bytes.write(localNonce, {
137
+ signal
138
+ }),
131
139
  bytes.read({
132
140
  bytes: NONCE_LENGTH,
133
- ...options
134
- }),
135
- bytes.write(localNonce, options)
141
+ signal
142
+ })
136
143
  ])
137
144
 
138
145
  const remoteNonce = result.subarray()
139
146
 
140
147
  // Create the boxing/unboxing pipe
141
- log('exchanged nonces')
142
-
143
- return new BoxMessageStream({
144
- localNonce,
145
- remoteNonce,
146
- psk: this.psk,
147
- maConn: connection,
148
- log
149
- })
148
+ this.log('exchanged nonces')
149
+ const [internal, external] = duplexPair<Uint8Array | Uint8ArrayList>()
150
+ pipe(
151
+ external,
152
+ // Encrypt all outbound traffic
153
+ createBoxStream(localNonce, this.psk),
154
+ bytes.unwrap(),
155
+ (source) => map(source, (buf) => buf.subarray()),
156
+ // Decrypt all inbound traffic
157
+ createUnboxStream(remoteNonce, this.psk),
158
+ external
159
+ ).catch(this.log.error)
160
+
161
+ return {
162
+ ...connection,
163
+ ...internal
164
+ }
150
165
  }
151
166
  }
152
167
 
153
- export function preSharedKey (init: ProtectorInit): () => ConnectionProtector {
154
- return () => new PreSharedKeyConnectionProtector(init)
168
+ export function preSharedKey (init: ProtectorInit): (components: ProtectorComponents) => ConnectionProtector {
169
+ return (components) => new PreSharedKeyConnectionProtector(components, init)
155
170
  }