@libp2p/pnet 1.0.1 → 2.0.0-18dd3cb26

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,8 +1,9 @@
1
1
  import type { Source } from 'it-stream-types';
2
+ import type { Uint8ArrayList } from 'uint8arraylist';
2
3
  /**
3
4
  * Creates a stream iterable to encrypt messages in a private network
4
5
  */
5
- export declare function createBoxStream(nonce: Uint8Array, psk: Uint8Array): (source: Source<Uint8Array>) => AsyncIterable<Uint8Array>;
6
+ export declare function createBoxStream(nonce: Uint8Array, psk: Uint8Array): (source: Source<Uint8Array | Uint8ArrayList>) => AsyncGenerator<Uint8Array | Uint8ArrayList>;
6
7
  /**
7
8
  * Creates a stream iterable to decrypt messages in a private network
8
9
  */
@@ -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;AAE7C;;GAEG;AACH,wBAAgB,eAAe,CAAE,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,UAAU,CAAC,KAAK,aAAa,CAAC,UAAU,CAAC,CAQ9H;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAE,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,YACnD,OAAO,UAAU,CAAC,+CAOnC;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,YACnD,OAAO,UAAU,CAAC,+CAOnC;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"}
@@ -10,7 +10,7 @@ export function createBoxStream(nonce, psk) {
10
10
  const xor = xsalsa20(nonce, psk);
11
11
  return (source) => (async function* () {
12
12
  for await (const chunk of source) {
13
- yield Uint8Array.from(xor.update(chunk.slice()));
13
+ yield Uint8Array.from(xor.update(chunk.subarray()));
14
14
  }
15
15
  })();
16
16
  }
@@ -21,7 +21,7 @@ export function createUnboxStream(nonce, psk) {
21
21
  return (source) => (async function* () {
22
22
  const xor = xsalsa20(nonce, psk);
23
23
  for await (const chunk of source) {
24
- yield Uint8Array.from(xor.update(chunk.slice()));
24
+ yield Uint8Array.from(xor.update(chunk.subarray()));
25
25
  }
26
26
  })();
27
27
  }
@@ -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;AAG/C;;GAEG;AACH,MAAM,UAAU,eAAe,CAAE,KAAiB,EAAE,GAAe;IACjE,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;IAEhC,OAAO,CAAC,MAA0B,EAAE,EAAE,CAAC,CAAC,KAAK,SAAU,CAAC;QACtD,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,EAAE;YAChC,MAAM,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA;SACjD;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;YAChC,MAAM,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA;SACjD;IACH,CAAC,CAAC,EAAE,CAAA;AACN,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAE,SAAqB;IAChD,IAAI;QACF,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;YACjC,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,CAAA;SACpC;QAED,OAAO;YACL,GAAG,EAAE,MAAM;YACX,SAAS,EAAE,KAAK;YAChB,GAAG;SACJ,CAAA;KACF;IAAC,OAAO,GAAQ,EAAE;QACjB,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,CAAA;KACpC;AACH,CAAC"}
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"}
@@ -3,5 +3,4 @@ export declare const INVALID_PSK = "Your private shared key is invalid";
3
3
  export declare const NO_LOCAL_ID = "No local private key provided";
4
4
  export declare const NO_HANDSHAKE_CONNECTION = "No connection for the handshake provided";
5
5
  export declare const STREAM_ENDED = "Stream ended prematurely";
6
- export declare const ERR_INVALID_PARAMETERS = "ERR_INVALID_PARAMETERS";
7
6
  //# sourceMappingURL=errors.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY,gCAAgC,CAAA;AACzD,eAAO,MAAM,WAAW,uCAAuC,CAAA;AAC/D,eAAO,MAAM,WAAW,kCAAkC,CAAA;AAC1D,eAAO,MAAM,uBAAuB,6CAA6C,CAAA;AACjF,eAAO,MAAM,YAAY,6BAA6B,CAAA;AACtD,eAAO,MAAM,sBAAsB,2BAA2B,CAAA"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY,gCAAgC,CAAA;AACzD,eAAO,MAAM,WAAW,uCAAuC,CAAA;AAC/D,eAAO,MAAM,WAAW,kCAAkC,CAAA;AAC1D,eAAO,MAAM,uBAAuB,6CAA6C,CAAA;AACjF,eAAO,MAAM,YAAY,6BAA6B,CAAA"}
@@ -3,5 +3,4 @@ export const INVALID_PSK = 'Your private shared key is invalid';
3
3
  export const NO_LOCAL_ID = 'No local private key provided';
4
4
  export const NO_HANDSHAKE_CONNECTION = 'No connection for the handshake provided';
5
5
  export const STREAM_ENDED = 'Stream ended prematurely';
6
- export const ERR_INVALID_PARAMETERS = 'ERR_INVALID_PARAMETERS';
7
6
  //# sourceMappingURL=errors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,YAAY,GAAG,6BAA6B,CAAA;AACzD,MAAM,CAAC,MAAM,WAAW,GAAG,oCAAoC,CAAA;AAC/D,MAAM,CAAC,MAAM,WAAW,GAAG,+BAA+B,CAAA;AAC1D,MAAM,CAAC,MAAM,uBAAuB,GAAG,0CAA0C,CAAA;AACjF,MAAM,CAAC,MAAM,YAAY,GAAG,0BAA0B,CAAA;AACtD,MAAM,CAAC,MAAM,sBAAsB,GAAG,wBAAwB,CAAA"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,YAAY,GAAG,6BAA6B,CAAA;AACzD,MAAM,CAAC,MAAM,WAAW,GAAG,oCAAoC,CAAA;AAC/D,MAAM,CAAC,MAAM,WAAW,GAAG,+BAA+B,CAAA;AAC1D,MAAM,CAAC,MAAM,uBAAuB,GAAG,0CAA0C,CAAA;AACjF,MAAM,CAAC,MAAM,YAAY,GAAG,0BAA0B,CAAA"}
@@ -45,7 +45,7 @@
45
45
  *
46
46
  * ### Programmatically
47
47
  *
48
- * ```js
48
+ * ```TypeScript
49
49
  * import fs from 'fs'
50
50
  * import { generateKey } from '@libp2p/pnet'
51
51
  *
@@ -55,12 +55,19 @@
55
55
  * fs.writeFileSync('swarm.key', swarmKey)
56
56
  * ```
57
57
  */
58
- import type { ComponentLogger } from '@libp2p/interface';
59
- import type { ConnectionProtector } from '@libp2p/interface/connection';
58
+ import type { ComponentLogger, ConnectionProtector } from '@libp2p/interface';
60
59
  export { generateKey } from './key-generator.js';
61
60
  export interface ProtectorInit {
62
- enabled?: boolean;
61
+ /**
62
+ * A pre-shared key. This must be the same byte value for all peers in the
63
+ * swarm in order for them to communicate.
64
+ */
63
65
  psk: Uint8Array;
66
+ /**
67
+ * The initial nonce exchange must complete within this many milliseconds
68
+ * (default: 1000)
69
+ */
70
+ timeout?: number;
64
71
  }
65
72
  export interface ProtectorComponents {
66
73
  logger: ComponentLogger;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AAeH,OAAO,KAAK,EAAE,eAAe,EAAU,MAAM,mBAAmB,CAAA;AAChE,OAAO,KAAK,EAAE,mBAAmB,EAAuB,MAAM,8BAA8B,CAAA;AAE5F,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAEhD,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,GAAG,EAAE,UAAU,CAAA;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,eAAe,CAAA;CACxB;AA6ED,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;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;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,eAAe,CAAA;CACxB;AA2ED,wBAAgB,YAAY,CAAE,IAAI,EAAE,aAAa,GAAG,CAAC,UAAU,EAAE,mBAAmB,KAAK,mBAAmB,CAE3G"}
package/dist/src/index.js CHANGED
@@ -45,7 +45,7 @@
45
45
  *
46
46
  * ### Programmatically
47
47
  *
48
- * ```js
48
+ * ```TypeScript
49
49
  * import fs from 'fs'
50
50
  * import { generateKey } from '@libp2p/pnet'
51
51
  *
@@ -56,66 +56,60 @@
56
56
  * ```
57
57
  */
58
58
  import { randomBytes } from '@libp2p/crypto';
59
- import { CodeError } from '@libp2p/interface/errors';
60
- import { handshake } from 'it-handshake';
59
+ import { InvalidParametersError } from '@libp2p/interface';
60
+ import { byteStream } from 'it-byte-stream';
61
61
  import map from 'it-map';
62
62
  import { duplexPair } from 'it-pair/duplex';
63
63
  import { pipe } from 'it-pipe';
64
64
  import { createBoxStream, createUnboxStream, decodeV1PSK } from './crypto.js';
65
- import * as Errors from './errors.js';
66
65
  import { NONCE_LENGTH } from './key-generator.js';
67
66
  export { generateKey } from './key-generator.js';
68
67
  class PreSharedKeyConnectionProtector {
69
68
  tag;
70
69
  log;
71
70
  psk;
72
- enabled;
71
+ timeout;
73
72
  /**
74
73
  * Takes a Private Shared Key (psk) and provides a `protect` method
75
74
  * for wrapping existing connections in a private encryption stream.
76
75
  */
77
76
  constructor(components, init) {
78
77
  this.log = components.logger.forComponent('libp2p:pnet');
79
- this.enabled = init.enabled !== false;
80
- if (this.enabled) {
81
- const decodedPSK = decodeV1PSK(init.psk);
82
- this.psk = decodedPSK.psk;
83
- this.tag = decodedPSK.tag ?? '';
84
- }
85
- else {
86
- this.psk = new Uint8Array();
87
- this.tag = '';
88
- }
78
+ this.timeout = init.timeout ?? 1000;
79
+ const decodedPSK = decodeV1PSK(init.psk);
80
+ this.psk = decodedPSK.psk;
81
+ this.tag = decodedPSK.tag ?? '';
89
82
  }
83
+ [Symbol.toStringTag] = '@libp2p/pnet';
90
84
  /**
91
85
  * Takes a given Connection and creates a private encryption stream
92
86
  * between its two peers from the PSK the Protector instance was
93
87
  * created with.
94
88
  */
95
89
  async protect(connection) {
96
- if (!this.enabled) {
97
- return connection;
98
- }
99
90
  if (connection == null) {
100
- throw new CodeError(Errors.NO_HANDSHAKE_CONNECTION, Errors.ERR_INVALID_PARAMETERS);
91
+ throw new InvalidParametersError('No connection for the handshake provided');
101
92
  }
102
93
  // Exchange nonces
103
94
  this.log('protecting the connection');
104
95
  const localNonce = randomBytes(NONCE_LENGTH);
105
- const shake = handshake(connection);
106
- shake.write(localNonce);
107
- const result = await shake.reader.next(NONCE_LENGTH);
108
- if (result.value == null) {
109
- throw new CodeError(Errors.STREAM_ENDED, Errors.ERR_INVALID_PARAMETERS);
110
- }
111
- const remoteNonce = result.value.slice();
112
- shake.rest();
96
+ const signal = AbortSignal.timeout(this.timeout);
97
+ const bytes = byteStream(connection);
98
+ const [, result] = await Promise.all([
99
+ bytes.write(localNonce, {
100
+ signal
101
+ }),
102
+ bytes.read(NONCE_LENGTH, {
103
+ signal
104
+ })
105
+ ]);
106
+ const remoteNonce = result.subarray();
113
107
  // Create the boxing/unboxing pipe
114
108
  this.log('exchanged nonces');
115
109
  const [internal, external] = duplexPair();
116
110
  pipe(external,
117
111
  // Encrypt all outbound traffic
118
- createBoxStream(localNonce, this.psk), shake.stream, (source) => map(source, (buf) => buf.subarray()),
112
+ createBoxStream(localNonce, this.psk), bytes.unwrap(), (source) => map(source, (buf) => buf.subarray()),
119
113
  // Decrypt all inbound traffic
120
114
  createUnboxStream(remoteNonce, this.psk), external).catch(this.log.error);
121
115
  return {
@@ -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":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"key-generator.js","sourceRoot":"","sources":["../../src/key-generator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAC5C,OAAO,EAAE,UAAU,IAAI,oBAAoB,EAAE,MAAM,yBAAyB,CAAA;AAC5E,OAAO,EAAE,QAAQ,IAAI,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAEtE;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAE,KAAsC;IACjE,MAAM,GAAG,GAAG,kBAAkB,CAAC,WAAW,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC,CAAA;IACjE,MAAM,GAAG,GAAG,oBAAoB,CAAC,mCAAmC,GAAG,GAAG,CAAC,CAAA;IAE3E,IAAI,KAAK,YAAY,UAAU,EAAE;QAC/B,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;KACf;SAAM;QACL,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;KACjB;AACH,CAAC;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,EAAE,CAAA;AAC9B,MAAM,CAAC,MAAM,UAAU,GAAG,EAAE,CAAA"}
1
+ {"version":3,"file":"key-generator.js","sourceRoot":"","sources":["../../src/key-generator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAC5C,OAAO,EAAE,UAAU,IAAI,oBAAoB,EAAE,MAAM,yBAAyB,CAAA;AAC5E,OAAO,EAAE,QAAQ,IAAI,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAEtE;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAE,KAAsC;IACjE,MAAM,GAAG,GAAG,kBAAkB,CAAC,WAAW,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC,CAAA;IACjE,MAAM,GAAG,GAAG,oBAAoB,CAAC,mCAAmC,GAAG,GAAG,CAAC,CAAA;IAE3E,IAAI,KAAK,YAAY,UAAU,EAAE,CAAC;QAChC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAChB,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAClB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,EAAE,CAAA;AAC9B,MAAM,CAAC,MAAM,UAAU,GAAG,EAAE,CAAA"}
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@libp2p/pnet",
3
- "version": "1.0.1",
3
+ "version": "2.0.0-18dd3cb26",
4
4
  "description": "Implementation of Connection protection management via a shared secret",
5
5
  "license": "Apache-2.0 OR MIT",
6
- "homepage": "https://github.com/libp2p/js-libp2p/tree/master/packages/pnet#readme",
6
+ "homepage": "https://github.com/libp2p/js-libp2p/tree/main/packages/pnet#readme",
7
7
  "repository": {
8
8
  "type": "git",
9
9
  "url": "git+https://github.com/libp2p/js-libp2p.git"
@@ -11,6 +11,10 @@
11
11
  "bugs": {
12
12
  "url": "https://github.com/libp2p/js-libp2p/issues"
13
13
  },
14
+ "publishConfig": {
15
+ "access": "public",
16
+ "provenance": true
17
+ },
14
18
  "type": "module",
15
19
  "types": "./dist/src/index.d.ts",
16
20
  "files": [
@@ -42,26 +46,29 @@
42
46
  "test:firefox": "aegir test -t browser -- --browser firefox",
43
47
  "test:firefox-webworker": "aegir test -t webworker -- --browser firefox",
44
48
  "test:node": "aegir test -t node --cov",
45
- "dep-check": "aegir dep-check"
49
+ "dep-check": "aegir dep-check",
50
+ "doc-check": "aegir doc-check"
46
51
  },
47
52
  "dependencies": {
48
- "@libp2p/crypto": "^2.0.5",
49
- "@libp2p/interface": "^0.1.3",
50
- "it-handshake": "^4.1.3",
51
- "it-map": "^3.0.4",
53
+ "@libp2p/crypto": "5.0.0-18dd3cb26",
54
+ "@libp2p/interface": "2.0.0-18dd3cb26",
55
+ "it-byte-stream": "^1.0.10",
56
+ "it-map": "^3.1.0",
52
57
  "it-pair": "^2.0.6",
53
58
  "it-pipe": "^3.0.1",
54
59
  "it-stream-types": "^2.0.1",
55
- "uint8arrays": "^4.0.6",
56
- "xsalsa20": "^1.1.0"
60
+ "uint8arraylist": "^2.4.8",
61
+ "uint8arrays": "^5.1.0",
62
+ "xsalsa20": "^1.2.0"
57
63
  },
58
64
  "devDependencies": {
59
- "@libp2p/interface-compliance-tests": "^4.1.1",
60
- "@libp2p/logger": "^3.1.0",
61
- "@libp2p/peer-id-factory": "^3.0.5",
62
- "@multiformats/multiaddr": "^12.1.10",
63
- "@types/xsalsa20": "^1.1.0",
64
- "aegir": "^41.0.2",
65
- "it-all": "^3.0.3"
66
- }
65
+ "@libp2p/interface-compliance-tests": "6.0.0-18dd3cb26",
66
+ "@libp2p/logger": "5.0.0-18dd3cb26",
67
+ "@libp2p/peer-id": "5.0.0-18dd3cb26",
68
+ "@multiformats/multiaddr": "^12.2.3",
69
+ "@types/xsalsa20": "^1.1.3",
70
+ "aegir": "^44.0.1",
71
+ "it-all": "^3.0.6"
72
+ },
73
+ "sideEffects": false
67
74
  }
package/src/crypto.ts CHANGED
@@ -4,16 +4,17 @@ import xsalsa20 from 'xsalsa20'
4
4
  import * as Errors from './errors.js'
5
5
  import { KEY_LENGTH } from './key-generator.js'
6
6
  import type { Source } from 'it-stream-types'
7
+ import type { Uint8ArrayList } from 'uint8arraylist'
7
8
 
8
9
  /**
9
10
  * Creates a stream iterable to encrypt messages in a private network
10
11
  */
11
- export function createBoxStream (nonce: Uint8Array, psk: Uint8Array): (source: Source<Uint8Array>) => AsyncIterable<Uint8Array> {
12
+ export function createBoxStream (nonce: Uint8Array, psk: Uint8Array): (source: Source<Uint8Array | Uint8ArrayList>) => AsyncGenerator<Uint8Array | Uint8ArrayList> {
12
13
  const xor = xsalsa20(nonce, psk)
13
14
 
14
- return (source: Source<Uint8Array>) => (async function * () {
15
+ return (source: Source<Uint8Array | Uint8ArrayList>) => (async function * () {
15
16
  for await (const chunk of source) {
16
- yield Uint8Array.from(xor.update(chunk.slice()))
17
+ yield Uint8Array.from(xor.update(chunk.subarray()))
17
18
  }
18
19
  })()
19
20
  }
@@ -26,7 +27,7 @@ export function createUnboxStream (nonce: Uint8Array, psk: Uint8Array) {
26
27
  const xor = xsalsa20(nonce, psk)
27
28
 
28
29
  for await (const chunk of source) {
29
- yield Uint8Array.from(xor.update(chunk.slice()))
30
+ yield Uint8Array.from(xor.update(chunk.subarray()))
30
31
  }
31
32
  })()
32
33
  }
package/src/errors.ts CHANGED
@@ -3,4 +3,3 @@ export const INVALID_PSK = 'Your private shared key is invalid'
3
3
  export const NO_LOCAL_ID = 'No local private key provided'
4
4
  export const NO_HANDSHAKE_CONNECTION = 'No connection for the handshake provided'
5
5
  export const STREAM_ENDED = 'Stream ended prematurely'
6
- export const ERR_INVALID_PARAMETERS = 'ERR_INVALID_PARAMETERS'
package/src/index.ts CHANGED
@@ -45,7 +45,7 @@
45
45
  *
46
46
  * ### Programmatically
47
47
  *
48
- * ```js
48
+ * ```TypeScript
49
49
  * import fs from 'fs'
50
50
  * import { generateKey } from '@libp2p/pnet'
51
51
  *
@@ -57,8 +57,8 @@
57
57
  */
58
58
 
59
59
  import { randomBytes } from '@libp2p/crypto'
60
- import { CodeError } from '@libp2p/interface/errors'
61
- import { handshake } from 'it-handshake'
60
+ import { InvalidParametersError } from '@libp2p/interface'
61
+ import { byteStream } from 'it-byte-stream'
62
62
  import map from 'it-map'
63
63
  import { duplexPair } from 'it-pair/duplex'
64
64
  import { pipe } from 'it-pipe'
@@ -67,16 +67,23 @@ import {
67
67
  createUnboxStream,
68
68
  decodeV1PSK
69
69
  } from './crypto.js'
70
- import * as Errors from './errors.js'
71
70
  import { NONCE_LENGTH } from './key-generator.js'
72
- import type { ComponentLogger, Logger } from '@libp2p/interface'
73
- import type { ConnectionProtector, MultiaddrConnection } from '@libp2p/interface/connection'
71
+ import type { ComponentLogger, Logger, ConnectionProtector, MultiaddrConnection } from '@libp2p/interface'
72
+ import type { Uint8ArrayList } from 'uint8arraylist'
74
73
 
75
74
  export { generateKey } from './key-generator.js'
76
75
 
77
76
  export interface ProtectorInit {
78
- enabled?: boolean
77
+ /**
78
+ * A pre-shared key. This must be the same byte value for all peers in the
79
+ * swarm in order for them to communicate.
80
+ */
79
81
  psk: Uint8Array
82
+ /**
83
+ * The initial nonce exchange must complete within this many milliseconds
84
+ * (default: 1000)
85
+ */
86
+ timeout?: number
80
87
  }
81
88
 
82
89
  export interface ProtectorComponents {
@@ -87,7 +94,7 @@ class PreSharedKeyConnectionProtector implements ConnectionProtector {
87
94
  public tag: string
88
95
  private readonly log: Logger
89
96
  private readonly psk: Uint8Array
90
- private readonly enabled: boolean
97
+ private readonly timeout: number
91
98
 
92
99
  /**
93
100
  * Takes a Private Shared Key (psk) and provides a `protect` method
@@ -95,56 +102,54 @@ class PreSharedKeyConnectionProtector implements ConnectionProtector {
95
102
  */
96
103
  constructor (components: ProtectorComponents, init: ProtectorInit) {
97
104
  this.log = components.logger.forComponent('libp2p:pnet')
98
- this.enabled = init.enabled !== false
99
-
100
- if (this.enabled) {
101
- const decodedPSK = decodeV1PSK(init.psk)
102
- this.psk = decodedPSK.psk
103
- this.tag = decodedPSK.tag ?? ''
104
- } else {
105
- this.psk = new Uint8Array()
106
- this.tag = ''
107
- }
105
+ this.timeout = init.timeout ?? 1000
106
+
107
+ const decodedPSK = decodeV1PSK(init.psk)
108
+ this.psk = decodedPSK.psk
109
+ this.tag = decodedPSK.tag ?? ''
108
110
  }
109
111
 
112
+ readonly [Symbol.toStringTag] = '@libp2p/pnet'
113
+
110
114
  /**
111
115
  * Takes a given Connection and creates a private encryption stream
112
116
  * between its two peers from the PSK the Protector instance was
113
117
  * created with.
114
118
  */
115
119
  async protect (connection: MultiaddrConnection): Promise<MultiaddrConnection> {
116
- if (!this.enabled) {
117
- return connection
118
- }
119
-
120
120
  if (connection == null) {
121
- throw new CodeError(Errors.NO_HANDSHAKE_CONNECTION, Errors.ERR_INVALID_PARAMETERS)
121
+ throw new InvalidParametersError('No connection for the handshake provided')
122
122
  }
123
123
 
124
124
  // Exchange nonces
125
125
  this.log('protecting the connection')
126
126
  const localNonce = randomBytes(NONCE_LENGTH)
127
127
 
128
- const shake = handshake(connection)
129
- shake.write(localNonce)
128
+ const signal = AbortSignal.timeout(this.timeout)
130
129
 
131
- const result = await shake.reader.next(NONCE_LENGTH)
130
+ const bytes = byteStream(connection)
132
131
 
133
- if (result.value == null) {
134
- throw new CodeError(Errors.STREAM_ENDED, Errors.ERR_INVALID_PARAMETERS)
135
- }
132
+ const [
133
+ , result
134
+ ] = await Promise.all([
135
+ bytes.write(localNonce, {
136
+ signal
137
+ }),
138
+ bytes.read(NONCE_LENGTH, {
139
+ signal
140
+ })
141
+ ])
136
142
 
137
- const remoteNonce = result.value.slice()
138
- shake.rest()
143
+ const remoteNonce = result.subarray()
139
144
 
140
145
  // Create the boxing/unboxing pipe
141
146
  this.log('exchanged nonces')
142
- const [internal, external] = duplexPair<Uint8Array>()
147
+ const [internal, external] = duplexPair<Uint8Array | Uint8ArrayList>()
143
148
  pipe(
144
149
  external,
145
150
  // Encrypt all outbound traffic
146
151
  createBoxStream(localNonce, this.psk),
147
- shake.stream,
152
+ bytes.unwrap(),
148
153
  (source) => map(source, (buf) => buf.subarray()),
149
154
  // Decrypt all inbound traffic
150
155
  createUnboxStream(remoteNonce, this.psk),