diff --git a/packages/connection-encrypter-plaintext/src/index.ts b/packages/connection-encrypter-plaintext/src/index.ts index af482b25c7..30bf267386 100644 --- a/packages/connection-encrypter-plaintext/src/index.ts +++ b/packages/connection-encrypter-plaintext/src/index.ts @@ -31,6 +31,7 @@ import type { Uint8ArrayList } from 'uint8arraylist' const PROTOCOL = '/plaintext/2.0.0' export interface PlaintextComponents { + peerId: PeerId logger: ComponentLogger } @@ -44,10 +45,12 @@ export interface PlaintextInit { class Plaintext implements ConnectionEncrypter { public protocol: string = PROTOCOL + private readonly peerId: PeerId private readonly log: Logger private readonly timeout: number constructor (components: PlaintextComponents, init: PlaintextInit = {}) { + this.peerId = components.peerId this.log = components.logger.forComponent('libp2p:plaintext') this.timeout = init.timeout ?? 1000 } @@ -58,12 +61,12 @@ class Plaintext implements ConnectionEncrypter { '@libp2p/connection-encryption' ] - async secureInbound > = MultiaddrConnection> (localId: PeerId, conn: Stream, remoteId?: PeerId): Promise> { - return this._encrypt(localId, conn, remoteId) + async secureInbound > = MultiaddrConnection> (conn: Stream, remoteId?: PeerId): Promise> { + return this._encrypt(this.peerId, conn, remoteId) } - async secureOutbound > = MultiaddrConnection> (localId: PeerId, conn: Stream, remoteId?: PeerId): Promise> { - return this._encrypt(localId, conn, remoteId) + async secureOutbound > = MultiaddrConnection> (conn: Stream, remoteId?: PeerId): Promise> { + return this._encrypt(this.peerId, conn, remoteId) } /** diff --git a/packages/connection-encrypter-plaintext/test/compliance.spec.ts b/packages/connection-encrypter-plaintext/test/compliance.spec.ts index 9678a0bff8..c1024441fe 100644 --- a/packages/connection-encrypter-plaintext/test/compliance.spec.ts +++ b/packages/connection-encrypter-plaintext/test/compliance.spec.ts @@ -2,12 +2,14 @@ import suite from '@libp2p/interface-compliance-tests/connection-encryption' import { defaultLogger } from '@libp2p/logger' +import { createEd25519PeerId } from '@libp2p/peer-id-factory' import { plaintext } from '../src/index.js' describe('plaintext compliance', () => { suite({ - async setup () { + async setup (opts) { return plaintext()({ + peerId: opts?.peerId ?? await createEd25519PeerId(), logger: defaultLogger() }) }, diff --git a/packages/connection-encrypter-plaintext/test/index.spec.ts b/packages/connection-encrypter-plaintext/test/index.spec.ts index 8a5a403003..c2a72f2dbb 100644 --- a/packages/connection-encrypter-plaintext/test/index.spec.ts +++ b/packages/connection-encrypter-plaintext/test/index.spec.ts @@ -15,6 +15,7 @@ describe('plaintext', () => { let remotePeer: PeerId let wrongPeer: PeerId let encrypter: ConnectionEncrypter + let encrypterRemote: ConnectionEncrypter beforeEach(async () => { [localPeer, remotePeer, wrongPeer] = await Promise.all([ @@ -24,6 +25,11 @@ describe('plaintext', () => { ]) encrypter = plaintext()({ + peerId: localPeer, + logger: defaultLogger() + }) + encrypterRemote = plaintext()({ + peerId: remotePeer, logger: defaultLogger() }) }) @@ -42,8 +48,8 @@ describe('plaintext', () => { }) await Promise.all([ - encrypter.secureInbound(remotePeer, inbound), - encrypter.secureOutbound(localPeer, outbound, wrongPeer) + encrypterRemote.secureInbound(inbound), + encrypter.secureOutbound(outbound, wrongPeer) ]).then(() => expect.fail('should have failed'), (err) => { expect(err).to.exist() expect(err).to.have.property('name', 'UnexpectedPeerError') @@ -54,6 +60,11 @@ describe('plaintext', () => { const peer = await createRSAPeerId() remotePeer = peerIdFromBytes(peer.toBytes()) + encrypter = plaintext()({ + peerId: remotePeer, + logger: defaultLogger() + }) + const { inbound, outbound } = mockMultiaddrConnPair({ remotePeer, addrs: [ @@ -63,8 +74,8 @@ describe('plaintext', () => { }) await expect(Promise.all([ - encrypter.secureInbound(localPeer, inbound), - encrypter.secureOutbound(remotePeer, outbound, localPeer) + encrypter.secureInbound(inbound), + encrypterRemote.secureOutbound(outbound, localPeer) ])) .to.eventually.be.rejected.with.property('name', 'InvalidCryptoExchangeError') }) diff --git a/packages/connection-encrypter-tls/src/index.ts b/packages/connection-encrypter-tls/src/index.ts index 745865a406..36d843d8c0 100644 --- a/packages/connection-encrypter-tls/src/index.ts +++ b/packages/connection-encrypter-tls/src/index.ts @@ -19,11 +19,12 @@ */ import { TLS } from './tls.js' -import type { ComponentLogger, ConnectionEncrypter } from '@libp2p/interface' +import type { ComponentLogger, ConnectionEncrypter, PeerId } from '@libp2p/interface' export const PROTOCOL = '/tls/1.0.0' export interface TLSComponents { + peerId: PeerId logger: ComponentLogger } diff --git a/packages/connection-encrypter-tls/src/tls.ts b/packages/connection-encrypter-tls/src/tls.ts index 722bacd6ad..d64b19033f 100644 --- a/packages/connection-encrypter-tls/src/tls.ts +++ b/packages/connection-encrypter-tls/src/tls.ts @@ -31,10 +31,12 @@ import type { Uint8ArrayList } from 'uint8arraylist' export class TLS implements ConnectionEncrypter { public protocol: string = PROTOCOL private readonly log: Logger + private readonly peerId: PeerId private readonly timeout: number constructor (components: TLSComponents, init: TLSInit = {}) { this.log = components.logger.forComponent('libp2p:tls') + this.peerId = components.peerId this.timeout = init.timeout ?? 1000 } @@ -44,20 +46,20 @@ export class TLS implements ConnectionEncrypter { '@libp2p/connection-encryption' ] - async secureInbound > = MultiaddrConnection> (localId: PeerId, conn: Stream, remoteId?: PeerId): Promise> { - return this._encrypt(localId, conn, true, remoteId) + async secureInbound > = MultiaddrConnection> (conn: Stream, remoteId?: PeerId): Promise> { + return this._encrypt(conn, true, remoteId) } - async secureOutbound > = MultiaddrConnection> (localId: PeerId, conn: Stream, remoteId?: PeerId): Promise> { - return this._encrypt(localId, conn, false, remoteId) + async secureOutbound > = MultiaddrConnection> (conn: Stream, remoteId?: PeerId): Promise> { + return this._encrypt(conn, false, remoteId) } /** * Encrypt connection */ - async _encrypt > = MultiaddrConnection> (localId: PeerId, conn: Stream, isServer: boolean, remoteId?: PeerId): Promise> { + async _encrypt > = MultiaddrConnection> (conn: Stream, isServer: boolean, remoteId?: PeerId): Promise> { const opts: TLSSocketOptions = { - ...await generateCertificate(localId), + ...await generateCertificate(this.peerId), isServer, // require TLS 1.3 or later minVersion: 'TLSv1.3', diff --git a/packages/connection-encrypter-tls/test/compliance.spec.ts b/packages/connection-encrypter-tls/test/compliance.spec.ts index 1b606899a9..d926cda042 100644 --- a/packages/connection-encrypter-tls/test/compliance.spec.ts +++ b/packages/connection-encrypter-tls/test/compliance.spec.ts @@ -2,12 +2,14 @@ import suite from '@libp2p/interface-compliance-tests/connection-encryption' import { defaultLogger } from '@libp2p/logger' +import { createEd25519PeerId } from '@libp2p/peer-id-factory' import { tls } from '../src/index.js' describe('tls compliance', () => { suite({ - async setup () { + async setup (opts) { return tls()({ + peerId: opts?.peerId ?? await createEd25519PeerId(), logger: defaultLogger() }) }, diff --git a/packages/connection-encrypter-tls/test/index.spec.ts b/packages/connection-encrypter-tls/test/index.spec.ts index 7a1af061f7..135d3a3f03 100644 --- a/packages/connection-encrypter-tls/test/index.spec.ts +++ b/packages/connection-encrypter-tls/test/index.spec.ts @@ -24,6 +24,7 @@ describe('tls', () => { ]) encrypter = tls()({ + peerId: await createEd25519PeerId(), logger: defaultLogger() }) }) @@ -42,8 +43,8 @@ describe('tls', () => { }) await Promise.all([ - encrypter.secureInbound(remotePeer, inbound), - encrypter.secureOutbound(localPeer, outbound, wrongPeer) + encrypter.secureInbound(inbound, remotePeer), + encrypter.secureOutbound(outbound, wrongPeer) ]).then(() => expect.fail('should have failed'), (err) => { expect(err).to.exist() expect(err).to.have.property('name', 'UnexpectedPeerError') @@ -54,6 +55,11 @@ describe('tls', () => { const peer = await createRSAPeerId() remotePeer = peerIdFromBytes(peer.toBytes()) + encrypter = tls()({ + peerId: remotePeer, + logger: defaultLogger() + }) + const { inbound, outbound } = mockMultiaddrConnPair({ remotePeer, addrs: [ @@ -63,8 +69,8 @@ describe('tls', () => { }) await expect(Promise.all([ - encrypter.secureInbound(localPeer, inbound), - encrypter.secureOutbound(remotePeer, outbound, localPeer) + encrypter.secureInbound(inbound), + encrypter.secureOutbound(outbound, localPeer) ])) .to.eventually.be.rejected.with.property('name', 'InvalidParametersError') }) diff --git a/packages/interface-compliance-tests/src/connection-encryption/index.ts b/packages/interface-compliance-tests/src/connection-encryption/index.ts index 87ceff1c84..7918e69b7a 100644 --- a/packages/interface-compliance-tests/src/connection-encryption/index.ts +++ b/packages/interface-compliance-tests/src/connection-encryption/index.ts @@ -9,9 +9,14 @@ import { createMaConnPair } from './utils/index.js' import type { TestSetup } from '../index.js' import type { ConnectionEncrypter, PeerId } from '@libp2p/interface' -export default (common: TestSetup): void => { +export interface ConnectionEncrypterSetupArgs { + peerId: PeerId +} + +export default (common: TestSetup): void => { describe('interface-connection-encrypter compliance tests', () => { let crypto: ConnectionEncrypter + let cryptoRemote: ConnectionEncrypter let localPeer: PeerId let remotePeer: PeerId let mitmPeer: PeerId @@ -19,11 +24,13 @@ export default (common: TestSetup): void => { before(async () => { [ crypto, + cryptoRemote, localPeer, remotePeer, mitmPeer ] = await Promise.all([ - common.setup(), + common.setup({ peerId: await PeerIdFactory.createFromJSON(peers[0]) }), + common.setup({ peerId: await PeerIdFactory.createFromJSON(peers[1]) }), PeerIdFactory.createFromJSON(peers[0]), PeerIdFactory.createFromJSON(peers[1]), PeerIdFactory.createFromJSON(peers[2]) @@ -46,8 +53,8 @@ export default (common: TestSetup): void => { inboundResult, outboundResult ] = await Promise.all([ - crypto.secureInbound(remotePeer, localConn), - crypto.secureOutbound(localPeer, remoteConn, remotePeer) + cryptoRemote.secureInbound(localConn), + crypto.secureOutbound(remoteConn, remotePeer) ]) // Echo server @@ -76,8 +83,8 @@ export default (common: TestSetup): void => { inboundResult, outboundResult ] = await Promise.all([ - crypto.secureInbound(remotePeer, localConn), - crypto.secureOutbound(localPeer, remoteConn, remotePeer) + cryptoRemote.secureInbound(localConn), + crypto.secureOutbound(remoteConn, remotePeer) ]) // Inbound should return the initiator (local) peer @@ -90,8 +97,8 @@ export default (common: TestSetup): void => { const [localConn, remoteConn] = createMaConnPair() await Promise.all([ - crypto.secureInbound(remotePeer, localConn, mitmPeer), - crypto.secureOutbound(localPeer, remoteConn, remotePeer) + cryptoRemote.secureInbound(localConn, mitmPeer), + crypto.secureOutbound(remoteConn, remotePeer) ]).then(() => expect.fail(), (err) => { expect(err).to.exist() expect(err).to.have.property('name', 'UnexpectedPeerError') diff --git a/packages/interface/src/connection-encrypter/index.ts b/packages/interface/src/connection-encrypter/index.ts index 8b2aac4729..40e85919e4 100644 --- a/packages/interface/src/connection-encrypter/index.ts +++ b/packages/interface/src/connection-encrypter/index.ts @@ -15,14 +15,14 @@ export interface ConnectionEncrypter { * pass it for extra verification, otherwise it will be determined during * the handshake. */ - secureOutbound > = MultiaddrConnection> (localPeer: PeerId, connection: Stream, remotePeer?: PeerId): Promise> + secureOutbound > = MultiaddrConnection> (connection: Stream, remotePeer?: PeerId): Promise> /** * Decrypt incoming data. If the remote PeerId is known, * pass it for extra verification, otherwise it will be determined during * the handshake */ - secureInbound > = MultiaddrConnection> (localPeer: PeerId, connection: Stream, remotePeer?: PeerId): Promise> + secureInbound > = MultiaddrConnection> (connection: Stream, remotePeer?: PeerId): Promise> } export interface SecuredConnection { diff --git a/packages/libp2p/src/upgrader.ts b/packages/libp2p/src/upgrader.ts index 53e0aa4bc7..d3d8d49186 100644 --- a/packages/libp2p/src/upgrader.ts +++ b/packages/libp2p/src/upgrader.ts @@ -640,7 +640,7 @@ export class DefaultUpgrader implements Upgrader { connection.log('encrypting inbound connection using', protocol) return { - ...await encrypter.secureInbound(this.components.peerId, stream), + ...await encrypter.secureInbound(stream), protocol } } catch (err: any) { @@ -677,7 +677,7 @@ export class DefaultUpgrader implements Upgrader { connection.log('encrypting outbound connection to %p using %s', remotePeerId, encrypter) return { - ...await encrypter.secureOutbound(this.components.peerId, stream, remotePeerId), + ...await encrypter.secureOutbound(stream, remotePeerId), protocol } } catch (err: any) { diff --git a/packages/libp2p/test/upgrading/upgrader.spec.ts b/packages/libp2p/test/upgrading/upgrader.spec.ts index 7ad8680c8f..8e71d835bb 100644 --- a/packages/libp2p/test/upgrading/upgrader.spec.ts +++ b/packages/libp2p/test/upgrading/upgrader.spec.ts @@ -173,7 +173,7 @@ describe('Upgrader', () => { }) remoteUpgrader = new DefaultUpgrader(remoteComponents, { connectionEncryption: [ - plaintext()(localComponents) + plaintext()(remoteComponents) ], muxers: [], inboundUpgradeTimeout: 1000 @@ -360,19 +360,19 @@ describe('Upgrader', () => { }) remoteUpgrader = new DefaultUpgrader(remoteComponents, { connectionEncryption: [ - plaintext()(localComponents) + plaintext()(remoteComponents) ], muxers: [ - yamux()(localComponents), - mplex()(localComponents) + yamux()(remoteComponents), + mplex()(remoteComponents) ], inboundUpgradeTimeout: 1000 }) // Wait for the results of each side of the connection const results = await Promise.allSettled([ - localUpgrader.upgradeOutbound(outbound), - remoteUpgrader.upgradeInbound(inbound) + localUpgrader.upgradeOutbound(inbound), + remoteUpgrader.upgradeInbound(outbound) ]) // Ensure both sides fail diff --git a/packages/transport-webrtc/src/private-to-public/transport.ts b/packages/transport-webrtc/src/private-to-public/transport.ts index 885de69abd..d10b926cbc 100644 --- a/packages/transport-webrtc/src/private-to-public/transport.ts +++ b/packages/transport-webrtc/src/private-to-public/transport.ts @@ -190,8 +190,6 @@ export class WebRTCDirectTransport implements Transport { // wait for peerconnection.onopen to fire, or for the datachannel to open const handshakeDataChannel = await dataChannelOpenPromise - const myPeerId = this.components.peerId - // Do noise handshake. // Set the Noise Prologue to libp2p-webrtc-noise: before starting the actual Noise handshake. // is the concatenation of the of the two TLS fingerprints of A and B in their multihash byte representation, sorted in ascending order. @@ -260,7 +258,7 @@ export class WebRTCDirectTransport implements Transport { // For outbound connections, the remote is expected to start the noise handshake. // Therefore, we need to secure an inbound noise connection from the remote. - await connectionEncrypter.secureInbound(myPeerId, wrappedDuplex, theirPeerId) + await connectionEncrypter.secureInbound(wrappedDuplex, theirPeerId) return await options.upgrader.upgradeOutbound(maConn, { skipProtection: true, skipEncryption: true, muxerFactory }) } catch (err) { diff --git a/packages/transport-webtransport/src/index.ts b/packages/transport-webtransport/src/index.ts index 5dddd498cf..d5fd844280 100644 --- a/packages/transport-webtransport/src/index.ts +++ b/packages/transport-webtransport/src/index.ts @@ -85,7 +85,6 @@ export type WebTransportDialEvents = interface AuthenticateWebTransportOptions extends DialTransportOptions { wt: WebTransport - localPeer: PeerId remotePeer?: PeerId certhashes: Array> } @@ -129,10 +128,6 @@ class WebTransportTransport implements Transport { } this.log('dialing %s', ma) - const localPeer = this.components.peerId - if (localPeer === undefined) { - throw new InvalidParametersError('Need a local peerid') - } options = options ?? {} @@ -206,7 +201,7 @@ class WebTransportTransport implements Transport { cleanUpWTSession('remote_close') }) - authenticated = await raceSignal(this.authenticateWebTransport({ wt, localPeer, remotePeer, certhashes, ...options }), options.signal) + authenticated = await raceSignal(this.authenticateWebTransport({ wt, remotePeer, certhashes, ...options }), options.signal) if (!authenticated) { throw new InvalidCryptoExchangeError('Failed to authenticate webtransport') @@ -257,7 +252,7 @@ class WebTransportTransport implements Transport { } } - async authenticateWebTransport ({ wt, localPeer, remotePeer, certhashes, onProgress, signal }: AuthenticateWebTransportOptions): Promise { + async authenticateWebTransport ({ wt, remotePeer, certhashes, onProgress, signal }: AuthenticateWebTransportOptions): Promise { signal?.throwIfAborted() onProgress?.(new CustomProgressEvent('webtransport:open-authentication-stream')) @@ -295,7 +290,7 @@ class WebTransportTransport implements Transport { const n = noise()(this.components) onProgress?.(new CustomProgressEvent('webtransport:secure-outbound-connection')) - const { remoteExtensions } = await n.secureOutbound(localPeer, duplex, remotePeer) + const { remoteExtensions } = await n.secureOutbound(duplex, remotePeer) onProgress?.(new CustomProgressEvent('webtransport:close-authentication-stream')) // We're done with this authentication stream