Skip to content

Commit 359265a

Browse files
oott123achingbrain
andauthored
fix: send raw plaintext public key during handshake (#2599)
In js, all "public keys" are marshaled using protobuf PublicKey message. However, according to [specs](https://github.com/libp2p/specs/blob/master/plaintext/README.md) and other implementations, the `Data` field should contains the raw key, instead of the protobuf marshaled key, and then put in to the exchange. Otherwise, js-libp2p will not connect to golang or rust libp2p, raising the "Public key did not match id" error. --------- Co-authored-by: Alex Potsides <[email protected]>
1 parent 52ac523 commit 359265a

File tree

4 files changed

+27
-9
lines changed

4 files changed

+27
-9
lines changed

packages/connection-encrypter-plaintext/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,9 @@
5252
"doc-check": "aegir doc-check"
5353
},
5454
"dependencies": {
55+
"@libp2p/crypto": "^4.1.9",
5556
"@libp2p/interface": "^1.7.0",
57+
"@libp2p/peer-id-factory": "^4.2.4",
5658
"@libp2p/peer-id": "^4.2.4",
5759
"it-protobuf-stream": "^1.1.3",
5860
"it-stream-types": "^2.0.1",
@@ -62,7 +64,6 @@
6264
"devDependencies": {
6365
"@libp2p/interface-compliance-tests": "^5.4.12",
6466
"@libp2p/logger": "^4.0.20",
65-
"@libp2p/peer-id-factory": "^4.2.4",
6667
"@multiformats/multiaddr": "^12.2.3",
6768
"aegir": "^44.0.1",
6869
"protons": "^7.5.0",

packages/connection-encrypter-plaintext/src/index.ts

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@
2020
* ```
2121
*/
2222

23+
import { supportedKeys } from '@libp2p/crypto/keys'
2324
import { UnexpectedPeerError, InvalidCryptoExchangeError, serviceCapabilities } from '@libp2p/interface'
24-
import { peerIdFromBytes, peerIdFromKeys } from '@libp2p/peer-id'
25+
import { peerIdFromBytes } from '@libp2p/peer-id'
26+
import { createFromPubKey } from '@libp2p/peer-id-factory'
2527
import { pbStream } from 'it-protobuf-stream'
26-
import { Exchange, KeyType } from './pb/proto.js'
27-
import type { ComponentLogger, Logger, MultiaddrConnection, ConnectionEncrypter, SecuredConnection, PeerId } from '@libp2p/interface'
28+
import { Exchange, KeyType, PublicKey } from './pb/proto.js'
29+
import type { ComponentLogger, Logger, MultiaddrConnection, ConnectionEncrypter, SecuredConnection, PeerId, PublicKey as PubKey } from '@libp2p/interface'
2830
import type { Duplex } from 'it-stream-types'
2931
import type { Uint8ArrayList } from 'uint8arraylist'
3032

@@ -91,7 +93,7 @@ class Plaintext implements ConnectionEncrypter {
9193
id: localId.toBytes(),
9294
pubkey: {
9395
Type: type,
94-
Data: localId.publicKey ?? new Uint8Array(0)
96+
Data: localId.publicKey == null ? new Uint8Array(0) : (PublicKey.decode(localId.publicKey).Data ?? new Uint8Array(0))
9597
}
9698
}, {
9799
signal
@@ -116,7 +118,19 @@ class Plaintext implements ConnectionEncrypter {
116118
throw new Error('Remote id missing')
117119
}
118120

119-
peerId = await peerIdFromKeys(response.pubkey.Data)
121+
let pubKey: PubKey
122+
123+
if (response.pubkey.Type === KeyType.RSA) {
124+
pubKey = supportedKeys.rsa.unmarshalRsaPublicKey(response.pubkey.Data)
125+
} else if (response.pubkey.Type === KeyType.Ed25519) {
126+
pubKey = supportedKeys.ed25519.unmarshalEd25519PublicKey(response.pubkey.Data)
127+
} else if (response.pubkey.Type === KeyType.Secp256k1) {
128+
pubKey = supportedKeys.secp256k1.unmarshalSecp256k1PublicKey(response.pubkey.Data)
129+
} else {
130+
throw new Error('Unknown public key type')
131+
}
132+
133+
peerId = await createFromPubKey(pubKey)
120134

121135
if (!peerId.equals(peerIdFromBytes(response.id))) {
122136
throw new Error('Public key did not match id')

packages/integration-tests/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,15 +49,15 @@
4949
"@libp2p/interface": "^1.3.1",
5050
"@libp2p/interface-compliance-tests": "^5.4.4",
5151
"@libp2p/interface-internal": "^1.2.1",
52-
"@libp2p/interop": "^12.1.0",
52+
"@libp2p/interop": "^12.2.0",
5353
"@libp2p/kad-dht": "^12.0.16",
5454
"@libp2p/logger": "^4.0.12",
5555
"@libp2p/mdns": "^10.0.23",
5656
"@libp2p/mplex": "^10.0.23",
5757
"@libp2p/peer-id": "^4.1.1",
5858
"@libp2p/peer-id-factory": "^4.1.1",
5959
"@libp2p/ping": "^1.0.18",
60-
"@libp2p/plaintext": "^1.0.23",
60+
"@libp2p/plaintext": "^1.1.5",
6161
"@libp2p/tcp": "^9.0.25",
6262
"@libp2p/tls": "^1.0.10",
6363
"@libp2p/webrtc": "^4.0.32",
@@ -70,7 +70,7 @@
7070
"delay": "^6.0.0",
7171
"detect-browser": "^5.3.0",
7272
"execa": "^9.1.0",
73-
"go-libp2p": "^1.2.0",
73+
"go-libp2p": "^1.5.0",
7474
"it-all": "^3.0.6",
7575
"it-pipe": "^3.0.1",
7676
"libp2p": "^1.5.2",

packages/integration-tests/test/interop.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { kadDHT, passthroughMapper } from '@libp2p/kad-dht'
1313
import { logger } from '@libp2p/logger'
1414
import { mplex } from '@libp2p/mplex'
1515
import { peerIdFromKeys } from '@libp2p/peer-id'
16+
import { plaintext } from '@libp2p/plaintext'
1617
import { tcp } from '@libp2p/tcp'
1718
import { tls } from '@libp2p/tls'
1819
import { multiaddr } from '@multiformats/multiaddr'
@@ -160,6 +161,8 @@ async function createJsPeer (options: SpawnOptions): Promise<Daemon> {
160161
opts.connectionEncryption?.push(noise())
161162
} else if (options.encryption === 'tls') {
162163
opts.connectionEncryption?.push(tls())
164+
} else if (options.encryption === 'plaintext') {
165+
opts.connectionEncryption?.push(plaintext())
163166
}
164167

165168
if (options.muxer === 'mplex') {

0 commit comments

Comments
 (0)