@libp2p/pnet 1.0.0-f81be145a → 1.0.1
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.
- package/README.md +1 -1
- package/dist/index.min.js +8 -8
- package/dist/src/crypto.d.ts +1 -2
- package/dist/src/crypto.d.ts.map +1 -1
- package/dist/src/crypto.js +2 -2
- package/dist/src/crypto.js.map +1 -1
- package/dist/src/index.d.ts +3 -10
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +25 -19
- package/dist/src/index.js.map +1 -1
- package/dist/src/key-generator.js.map +1 -1
- package/package.json +9 -14
- package/src/crypto.ts +4 -5
- package/src/index.ts +30 -34
package/dist/src/crypto.d.ts
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
import type { Source } from 'it-stream-types';
|
2
|
-
import type { Uint8ArrayList } from 'uint8arraylist';
|
3
2
|
/**
|
4
3
|
* Creates a stream iterable to encrypt messages in a private network
|
5
4
|
*/
|
6
|
-
export declare function createBoxStream(nonce: Uint8Array, psk: Uint8Array): (source: Source<Uint8Array
|
5
|
+
export declare function createBoxStream(nonce: Uint8Array, psk: Uint8Array): (source: Source<Uint8Array>) => AsyncIterable<Uint8Array>;
|
7
6
|
/**
|
8
7
|
* Creates a stream iterable to decrypt messages in a private network
|
9
8
|
*/
|
package/dist/src/crypto.d.ts.map
CHANGED
@@ -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;
|
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"}
|
package/dist/src/crypto.js
CHANGED
@@ -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.
|
13
|
+
yield Uint8Array.from(xor.update(chunk.slice()));
|
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.
|
24
|
+
yield Uint8Array.from(xor.update(chunk.slice()));
|
25
25
|
}
|
26
26
|
})();
|
27
27
|
}
|
package/dist/src/crypto.js.map
CHANGED
@@ -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;
|
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"}
|
package/dist/src/index.d.ts
CHANGED
@@ -55,19 +55,12 @@
|
|
55
55
|
* fs.writeFileSync('swarm.key', swarmKey)
|
56
56
|
* ```
|
57
57
|
*/
|
58
|
-
import type { ComponentLogger
|
58
|
+
import type { ComponentLogger } from '@libp2p/interface';
|
59
|
+
import type { ConnectionProtector } from '@libp2p/interface/connection';
|
59
60
|
export { generateKey } from './key-generator.js';
|
60
61
|
export interface ProtectorInit {
|
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
|
-
*/
|
62
|
+
enabled?: boolean;
|
65
63
|
psk: Uint8Array;
|
66
|
-
/**
|
67
|
-
* The initial nonce exchange must complete within this many milliseconds
|
68
|
-
* (default: 1000)
|
69
|
-
*/
|
70
|
-
timeout?: number;
|
71
64
|
}
|
72
65
|
export interface ProtectorComponents {
|
73
66
|
logger: ComponentLogger;
|
package/dist/src/index.d.ts.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwDG;AAeH,OAAO,KAAK,EAAE,eAAe,EAAU,mBAAmB,EAAuB,MAAM,
|
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"}
|
package/dist/src/index.js
CHANGED
@@ -56,8 +56,8 @@
|
|
56
56
|
* ```
|
57
57
|
*/
|
58
58
|
import { randomBytes } from '@libp2p/crypto';
|
59
|
-
import { CodeError } from '@libp2p/interface';
|
60
|
-
import {
|
59
|
+
import { CodeError } from '@libp2p/interface/errors';
|
60
|
+
import { handshake } from 'it-handshake';
|
61
61
|
import map from 'it-map';
|
62
62
|
import { duplexPair } from 'it-pair/duplex';
|
63
63
|
import { pipe } from 'it-pipe';
|
@@ -69,17 +69,23 @@ class PreSharedKeyConnectionProtector {
|
|
69
69
|
tag;
|
70
70
|
log;
|
71
71
|
psk;
|
72
|
-
|
72
|
+
enabled;
|
73
73
|
/**
|
74
74
|
* Takes a Private Shared Key (psk) and provides a `protect` method
|
75
75
|
* for wrapping existing connections in a private encryption stream.
|
76
76
|
*/
|
77
77
|
constructor(components, init) {
|
78
78
|
this.log = components.logger.forComponent('libp2p:pnet');
|
79
|
-
this.
|
80
|
-
|
81
|
-
|
82
|
-
|
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
|
+
}
|
83
89
|
}
|
84
90
|
/**
|
85
91
|
* Takes a given Connection and creates a private encryption stream
|
@@ -87,29 +93,29 @@ class PreSharedKeyConnectionProtector {
|
|
87
93
|
* created with.
|
88
94
|
*/
|
89
95
|
async protect(connection) {
|
96
|
+
if (!this.enabled) {
|
97
|
+
return connection;
|
98
|
+
}
|
90
99
|
if (connection == null) {
|
91
100
|
throw new CodeError(Errors.NO_HANDSHAKE_CONNECTION, Errors.ERR_INVALID_PARAMETERS);
|
92
101
|
}
|
93
102
|
// Exchange nonces
|
94
103
|
this.log('protecting the connection');
|
95
104
|
const localNonce = randomBytes(NONCE_LENGTH);
|
96
|
-
const
|
97
|
-
|
98
|
-
const
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
})
|
105
|
-
]);
|
106
|
-
const remoteNonce = result.subarray();
|
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();
|
107
113
|
// Create the boxing/unboxing pipe
|
108
114
|
this.log('exchanged nonces');
|
109
115
|
const [internal, external] = duplexPair();
|
110
116
|
pipe(external,
|
111
117
|
// Encrypt all outbound traffic
|
112
|
-
createBoxStream(localNonce, this.psk),
|
118
|
+
createBoxStream(localNonce, this.psk), shake.stream, (source) => map(source, (buf) => buf.subarray()),
|
113
119
|
// Decrypt all inbound traffic
|
114
120
|
createUnboxStream(remoteNonce, this.psk), external).catch(this.log.error);
|
115
121
|
return {
|
package/dist/src/index.js.map
CHANGED
@@ -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,SAAS,EAAE,MAAM,
|
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
|
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"}
|
package/package.json
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
{
|
2
2
|
"name": "@libp2p/pnet",
|
3
|
-
"version": "1.0.
|
3
|
+
"version": "1.0.1",
|
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/
|
6
|
+
"homepage": "https://github.com/libp2p/js-libp2p/tree/master/packages/pnet#readme",
|
7
7
|
"repository": {
|
8
8
|
"type": "git",
|
9
9
|
"url": "git+https://github.com/libp2p/js-libp2p.git"
|
@@ -11,10 +11,6 @@
|
|
11
11
|
"bugs": {
|
12
12
|
"url": "https://github.com/libp2p/js-libp2p/issues"
|
13
13
|
},
|
14
|
-
"publishConfig": {
|
15
|
-
"access": "public",
|
16
|
-
"provenance": true
|
17
|
-
},
|
18
14
|
"type": "module",
|
19
15
|
"types": "./dist/src/index.d.ts",
|
20
16
|
"files": [
|
@@ -49,21 +45,20 @@
|
|
49
45
|
"dep-check": "aegir dep-check"
|
50
46
|
},
|
51
47
|
"dependencies": {
|
52
|
-
"@libp2p/crypto": "
|
53
|
-
"@libp2p/interface": "1.
|
54
|
-
"it-
|
48
|
+
"@libp2p/crypto": "^2.0.5",
|
49
|
+
"@libp2p/interface": "^0.1.3",
|
50
|
+
"it-handshake": "^4.1.3",
|
55
51
|
"it-map": "^3.0.4",
|
56
52
|
"it-pair": "^2.0.6",
|
57
53
|
"it-pipe": "^3.0.1",
|
58
54
|
"it-stream-types": "^2.0.1",
|
59
|
-
"
|
60
|
-
"uint8arrays": "^5.0.0",
|
55
|
+
"uint8arrays": "^4.0.6",
|
61
56
|
"xsalsa20": "^1.1.0"
|
62
57
|
},
|
63
58
|
"devDependencies": {
|
64
|
-
"@libp2p/interface-compliance-tests": "
|
65
|
-
"@libp2p/logger": "
|
66
|
-
"@libp2p/peer-id-factory": "
|
59
|
+
"@libp2p/interface-compliance-tests": "^4.1.1",
|
60
|
+
"@libp2p/logger": "^3.1.0",
|
61
|
+
"@libp2p/peer-id-factory": "^3.0.5",
|
67
62
|
"@multiformats/multiaddr": "^12.1.10",
|
68
63
|
"@types/xsalsa20": "^1.1.0",
|
69
64
|
"aegir": "^41.0.2",
|
package/src/crypto.ts
CHANGED
@@ -4,17 +4,16 @@ 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'
|
8
7
|
|
9
8
|
/**
|
10
9
|
* Creates a stream iterable to encrypt messages in a private network
|
11
10
|
*/
|
12
|
-
export function createBoxStream (nonce: Uint8Array, psk: Uint8Array): (source: Source<Uint8Array
|
11
|
+
export function createBoxStream (nonce: Uint8Array, psk: Uint8Array): (source: Source<Uint8Array>) => AsyncIterable<Uint8Array> {
|
13
12
|
const xor = xsalsa20(nonce, psk)
|
14
13
|
|
15
|
-
return (source: Source<Uint8Array
|
14
|
+
return (source: Source<Uint8Array>) => (async function * () {
|
16
15
|
for await (const chunk of source) {
|
17
|
-
yield Uint8Array.from(xor.update(chunk.
|
16
|
+
yield Uint8Array.from(xor.update(chunk.slice()))
|
18
17
|
}
|
19
18
|
})()
|
20
19
|
}
|
@@ -27,7 +26,7 @@ export function createUnboxStream (nonce: Uint8Array, psk: Uint8Array) {
|
|
27
26
|
const xor = xsalsa20(nonce, psk)
|
28
27
|
|
29
28
|
for await (const chunk of source) {
|
30
|
-
yield Uint8Array.from(xor.update(chunk.
|
29
|
+
yield Uint8Array.from(xor.update(chunk.slice()))
|
31
30
|
}
|
32
31
|
})()
|
33
32
|
}
|
package/src/index.ts
CHANGED
@@ -57,8 +57,8 @@
|
|
57
57
|
*/
|
58
58
|
|
59
59
|
import { randomBytes } from '@libp2p/crypto'
|
60
|
-
import { CodeError } from '@libp2p/interface'
|
61
|
-
import {
|
60
|
+
import { CodeError } from '@libp2p/interface/errors'
|
61
|
+
import { handshake } from 'it-handshake'
|
62
62
|
import map from 'it-map'
|
63
63
|
import { duplexPair } from 'it-pair/duplex'
|
64
64
|
import { pipe } from 'it-pipe'
|
@@ -69,22 +69,14 @@ import {
|
|
69
69
|
} from './crypto.js'
|
70
70
|
import * as Errors from './errors.js'
|
71
71
|
import { NONCE_LENGTH } from './key-generator.js'
|
72
|
-
import type { ComponentLogger, Logger
|
73
|
-
import type {
|
72
|
+
import type { ComponentLogger, Logger } from '@libp2p/interface'
|
73
|
+
import type { ConnectionProtector, MultiaddrConnection } from '@libp2p/interface/connection'
|
74
74
|
|
75
75
|
export { generateKey } from './key-generator.js'
|
76
76
|
|
77
77
|
export interface ProtectorInit {
|
78
|
-
|
79
|
-
* A pre-shared key. This must be the same byte value for all peers in the
|
80
|
-
* swarm in order for them to communicate.
|
81
|
-
*/
|
78
|
+
enabled?: boolean
|
82
79
|
psk: Uint8Array
|
83
|
-
/**
|
84
|
-
* The initial nonce exchange must complete within this many milliseconds
|
85
|
-
* (default: 1000)
|
86
|
-
*/
|
87
|
-
timeout?: number
|
88
80
|
}
|
89
81
|
|
90
82
|
export interface ProtectorComponents {
|
@@ -95,7 +87,7 @@ class PreSharedKeyConnectionProtector implements ConnectionProtector {
|
|
95
87
|
public tag: string
|
96
88
|
private readonly log: Logger
|
97
89
|
private readonly psk: Uint8Array
|
98
|
-
private readonly
|
90
|
+
private readonly enabled: boolean
|
99
91
|
|
100
92
|
/**
|
101
93
|
* Takes a Private Shared Key (psk) and provides a `protect` method
|
@@ -103,11 +95,16 @@ class PreSharedKeyConnectionProtector implements ConnectionProtector {
|
|
103
95
|
*/
|
104
96
|
constructor (components: ProtectorComponents, init: ProtectorInit) {
|
105
97
|
this.log = components.logger.forComponent('libp2p:pnet')
|
106
|
-
this.
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
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
|
+
}
|
111
108
|
}
|
112
109
|
|
113
110
|
/**
|
@@ -116,6 +113,10 @@ class PreSharedKeyConnectionProtector implements ConnectionProtector {
|
|
116
113
|
* created with.
|
117
114
|
*/
|
118
115
|
async protect (connection: MultiaddrConnection): Promise<MultiaddrConnection> {
|
116
|
+
if (!this.enabled) {
|
117
|
+
return connection
|
118
|
+
}
|
119
|
+
|
119
120
|
if (connection == null) {
|
120
121
|
throw new CodeError(Errors.NO_HANDSHAKE_CONNECTION, Errors.ERR_INVALID_PARAMETERS)
|
121
122
|
}
|
@@ -124,31 +125,26 @@ class PreSharedKeyConnectionProtector implements ConnectionProtector {
|
|
124
125
|
this.log('protecting the connection')
|
125
126
|
const localNonce = randomBytes(NONCE_LENGTH)
|
126
127
|
|
127
|
-
const
|
128
|
+
const shake = handshake(connection)
|
129
|
+
shake.write(localNonce)
|
128
130
|
|
129
|
-
const
|
131
|
+
const result = await shake.reader.next(NONCE_LENGTH)
|
130
132
|
|
131
|
-
|
132
|
-
,
|
133
|
-
|
134
|
-
bytes.write(localNonce, {
|
135
|
-
signal
|
136
|
-
}),
|
137
|
-
bytes.read(NONCE_LENGTH, {
|
138
|
-
signal
|
139
|
-
})
|
140
|
-
])
|
133
|
+
if (result.value == null) {
|
134
|
+
throw new CodeError(Errors.STREAM_ENDED, Errors.ERR_INVALID_PARAMETERS)
|
135
|
+
}
|
141
136
|
|
142
|
-
const remoteNonce = result.
|
137
|
+
const remoteNonce = result.value.slice()
|
138
|
+
shake.rest()
|
143
139
|
|
144
140
|
// Create the boxing/unboxing pipe
|
145
141
|
this.log('exchanged nonces')
|
146
|
-
const [internal, external] = duplexPair<Uint8Array
|
142
|
+
const [internal, external] = duplexPair<Uint8Array>()
|
147
143
|
pipe(
|
148
144
|
external,
|
149
145
|
// Encrypt all outbound traffic
|
150
146
|
createBoxStream(localNonce, this.psk),
|
151
|
-
|
147
|
+
shake.stream,
|
152
148
|
(source) => map(source, (buf) => buf.subarray()),
|
153
149
|
// Decrypt all inbound traffic
|
154
150
|
createUnboxStream(remoteNonce, this.psk),
|