@libp2p/pnet 2.0.46-cf9aab5c8 → 2.0.47-a02cb0461

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,13 +1,24 @@
1
- import type { Source } from 'it-stream-types';
1
+ import { AbstractMultiaddrConnection } from '@libp2p/utils';
2
+ import type { AbortOptions, MultiaddrConnection } from '@libp2p/interface';
3
+ import type { MessageStreamInit, SendResult } from '@libp2p/utils';
2
4
  import type { Uint8ArrayList } from 'uint8arraylist';
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>;
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
+ }
11
22
  /**
12
23
  * Decode the version 1 psk from the given Uint8Array
13
24
  */
@@ -1 +1 @@
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
+ {"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,29 +1,65 @@
1
+ import { AbstractMultiaddrConnection } from '@libp2p/utils';
1
2
  import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string';
2
3
  import { toString as uint8ArrayToString } from 'uint8arrays/to-string';
3
4
  import xsalsa20 from 'xsalsa20';
4
5
  import * as Errors from './errors.js';
5
6
  import { KEY_LENGTH } from './key-generator.js';
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
- })();
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
+ }
27
63
  }
28
64
  /**
29
65
  * Decode the version 1 psk from the given Uint8Array
@@ -1 +1 @@
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"}
1
+ {"version":3,"file":"crypto.js","sourceRoot":"","sources":["../../src/crypto.ts"],"names":[],"mappings":"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"}
@@ -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): (components: ProtectorComponents) => ConnectionProtector;
76
+ export declare function preSharedKey(init: ProtectorInit): () => 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;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"}
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"}
package/dist/src/index.js CHANGED
@@ -57,24 +57,19 @@
57
57
  */
58
58
  import { randomBytes } from '@libp2p/crypto';
59
59
  import { InvalidParametersError } from '@libp2p/interface';
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';
60
+ import { byteStream } from '@libp2p/utils';
61
+ import { BoxMessageStream, decodeV1PSK } from './crypto.js';
65
62
  import { NONCE_LENGTH } from './key-generator.js';
66
63
  export { generateKey } from './key-generator.js';
67
64
  class PreSharedKeyConnectionProtector {
68
65
  tag;
69
- log;
70
66
  psk;
71
67
  timeout;
72
68
  /**
73
69
  * Takes a Private Shared Key (psk) and provides a `protect` method
74
70
  * for wrapping existing connections in a private encryption stream.
75
71
  */
76
- constructor(components, init) {
77
- this.log = components.logger.forComponent('libp2p:pnet');
72
+ constructor(init) {
78
73
  this.timeout = init.timeout ?? 1000;
79
74
  const decodedPSK = decodeV1PSK(init.psk);
80
75
  this.psk = decodedPSK.psk;
@@ -86,40 +81,40 @@ class PreSharedKeyConnectionProtector {
86
81
  * between its two peers from the PSK the Protector instance was
87
82
  * created with.
88
83
  */
89
- async protect(connection) {
84
+ async protect(connection, options) {
90
85
  if (connection == null) {
91
86
  throw new InvalidParametersError('No connection for the handshake provided');
92
87
  }
93
88
  // Exchange nonces
94
- this.log('protecting the connection');
89
+ const log = connection.log.newScope('pnet');
90
+ log('protecting the connection');
95
91
  const localNonce = randomBytes(NONCE_LENGTH);
96
- const signal = AbortSignal.timeout(this.timeout);
92
+ if (options == null) {
93
+ options = {
94
+ signal: AbortSignal.timeout(this.timeout)
95
+ };
96
+ }
97
97
  const bytes = byteStream(connection);
98
- const [, result] = await Promise.all([
99
- bytes.write(localNonce, {
100
- signal
101
- }),
98
+ const [result] = await Promise.all([
102
99
  bytes.read({
103
100
  bytes: NONCE_LENGTH,
104
- signal
105
- })
101
+ ...options
102
+ }),
103
+ bytes.write(localNonce, options)
106
104
  ]);
107
105
  const remoteNonce = result.subarray();
108
106
  // Create the boxing/unboxing pipe
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
- };
107
+ log('exchanged nonces');
108
+ return new BoxMessageStream({
109
+ localNonce,
110
+ remoteNonce,
111
+ psk: this.psk,
112
+ maConn: connection,
113
+ log
114
+ });
120
115
  }
121
116
  }
122
117
  export function preSharedKey(init) {
123
- return (components) => new PreSharedKeyConnectionProtector(components, init);
118
+ return () => new PreSharedKeyConnectionProtector(init);
124
119
  }
125
120
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@libp2p/pnet",
3
- "version": "2.0.46-cf9aab5c8",
3
+ "version": "2.0.47-a02cb0461",
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,25 +43,17 @@
43
43
  "doc-check": "aegir doc-check"
44
44
  },
45
45
  "dependencies": {
46
- "@libp2p/crypto": "5.1.7-cf9aab5c8",
47
- "@libp2p/interface": "2.10.5-cf9aab5c8",
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",
46
+ "@libp2p/crypto": "5.1.8-a02cb0461",
47
+ "@libp2p/interface": "2.11.0-a02cb0461",
48
+ "@libp2p/utils": "6.7.2-a02cb0461",
53
49
  "uint8arraylist": "^2.4.8",
54
50
  "uint8arrays": "^5.1.0",
55
51
  "xsalsa20": "^1.2.0"
56
52
  },
57
53
  "devDependencies": {
58
- "@libp2p/interface-compliance-tests": "6.4.16-cf9aab5c8",
59
- "@libp2p/logger": "5.1.21-cf9aab5c8",
60
- "@libp2p/peer-id": "5.1.8-cf9aab5c8",
61
- "@multiformats/multiaddr": "^12.4.4",
62
54
  "@types/xsalsa20": "^1.1.3",
63
- "aegir": "^47.0.14",
64
- "it-all": "^3.0.8"
55
+ "aegir": "^47.0.21",
56
+ "p-event": "^6.0.1"
65
57
  },
66
58
  "sideEffects": false
67
59
  }
package/src/crypto.ts CHANGED
@@ -1,35 +1,83 @@
1
+ import { AbstractMultiaddrConnection } from '@libp2p/utils'
1
2
  import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
2
3
  import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
3
4
  import xsalsa20 from 'xsalsa20'
4
5
  import * as Errors from './errors.js'
5
6
  import { KEY_LENGTH } from './key-generator.js'
6
- import type { Source } from 'it-stream-types'
7
+ import type { AbortOptions, MultiaddrConnection } from '@libp2p/interface'
8
+ import type { MessageStreamInit, SendResult } from '@libp2p/utils'
7
9
  import type { Uint8ArrayList } from 'uint8arraylist'
8
10
 
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)
14
-
15
- return (source: Source<Uint8Array | Uint8ArrayList>) => (async function * () {
16
- for await (const chunk of source) {
17
- yield Uint8Array.from(xor.update(chunk.subarray()))
18
- }
19
- })()
11
+ export interface BoxMessageStreamInit extends MessageStreamInit {
12
+ maConn: MultiaddrConnection
13
+ localNonce: Uint8Array
14
+ remoteNonce: Uint8Array
15
+ psk: Uint8Array
20
16
  }
21
17
 
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)
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
+ }
28
62
 
29
- for await (const chunk of source) {
30
- yield Uint8Array.from(xor.update(chunk.subarray()))
63
+ sendData (data: Uint8ArrayList): SendResult {
64
+ return {
65
+ sentBytes: data.byteLength,
66
+ canSendMore: this.maConn.send(this.outboundXor.update(data.subarray()))
31
67
  }
32
- })()
68
+ }
69
+
70
+ sendReset (err: Error): void {
71
+ this.maConn.abort(err)
72
+ }
73
+
74
+ sendPause (): void {
75
+ this.maConn.pause()
76
+ }
77
+
78
+ sendResume (): void {
79
+ this.maConn.resume()
80
+ }
33
81
  }
34
82
 
35
83
  /**
package/src/index.ts CHANGED
@@ -58,18 +58,10 @@
58
58
 
59
59
  import { randomBytes } from '@libp2p/crypto'
60
60
  import { InvalidParametersError } from '@libp2p/interface'
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'
61
+ import { byteStream } from '@libp2p/utils'
62
+ import { BoxMessageStream, decodeV1PSK } from './crypto.js'
70
63
  import { NONCE_LENGTH } from './key-generator.js'
71
- import type { ComponentLogger, Logger, ConnectionProtector, MultiaddrConnection } from '@libp2p/interface'
72
- import type { Uint8ArrayList } from 'uint8arraylist'
64
+ import type { ComponentLogger, ConnectionProtector, MultiaddrConnection, AbortOptions } from '@libp2p/interface'
73
65
 
74
66
  export { generateKey } from './key-generator.js'
75
67
 
@@ -93,7 +85,6 @@ export interface ProtectorComponents {
93
85
 
94
86
  class PreSharedKeyConnectionProtector implements ConnectionProtector {
95
87
  public tag: string
96
- private readonly log: Logger
97
88
  private readonly psk: Uint8Array
98
89
  private readonly timeout: number
99
90
 
@@ -101,8 +92,7 @@ class PreSharedKeyConnectionProtector implements ConnectionProtector {
101
92
  * Takes a Private Shared Key (psk) and provides a `protect` method
102
93
  * for wrapping existing connections in a private encryption stream.
103
94
  */
104
- constructor (components: ProtectorComponents, init: ProtectorInit) {
105
- this.log = components.logger.forComponent('libp2p:pnet')
95
+ constructor (init: ProtectorInit) {
106
96
  this.timeout = init.timeout ?? 1000
107
97
 
108
98
  const decodedPSK = decodeV1PSK(init.psk)
@@ -117,54 +107,49 @@ class PreSharedKeyConnectionProtector implements ConnectionProtector {
117
107
  * between its two peers from the PSK the Protector instance was
118
108
  * created with.
119
109
  */
120
- async protect (connection: MultiaddrConnection): Promise<MultiaddrConnection> {
110
+ async protect (connection: MultiaddrConnection, options?: AbortOptions): Promise<MultiaddrConnection> {
121
111
  if (connection == null) {
122
112
  throw new InvalidParametersError('No connection for the handshake provided')
123
113
  }
124
114
 
125
115
  // Exchange nonces
126
- this.log('protecting the connection')
116
+ const log = connection.log.newScope('pnet')
117
+ log('protecting the connection')
127
118
  const localNonce = randomBytes(NONCE_LENGTH)
128
119
 
129
- const signal = AbortSignal.timeout(this.timeout)
120
+ if (options == null) {
121
+ options = {
122
+ signal: AbortSignal.timeout(this.timeout)
123
+ }
124
+ }
130
125
 
131
126
  const bytes = byteStream(connection)
132
127
 
133
128
  const [
134
- , result
129
+ result
135
130
  ] = await Promise.all([
136
- bytes.write(localNonce, {
137
- signal
138
- }),
139
131
  bytes.read({
140
132
  bytes: NONCE_LENGTH,
141
- signal
142
- })
133
+ ...options
134
+ }),
135
+ bytes.write(localNonce, options)
143
136
  ])
144
137
 
145
138
  const remoteNonce = result.subarray()
146
139
 
147
140
  // Create the boxing/unboxing pipe
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
- }
141
+ log('exchanged nonces')
142
+
143
+ return new BoxMessageStream({
144
+ localNonce,
145
+ remoteNonce,
146
+ psk: this.psk,
147
+ maConn: connection,
148
+ log
149
+ })
165
150
  }
166
151
  }
167
152
 
168
- export function preSharedKey (init: ProtectorInit): (components: ProtectorComponents) => ConnectionProtector {
169
- return (components) => new PreSharedKeyConnectionProtector(components, init)
153
+ export function preSharedKey (init: ProtectorInit): () => ConnectionProtector {
154
+ return () => new PreSharedKeyConnectionProtector(init)
170
155
  }