11import { publicKeyFromProtobuf } from '@libp2p/crypto/keys'
22import { InvalidCryptoExchangeError , serviceCapabilities } from '@libp2p/interface'
33import { peerIdFromPublicKey } from '@libp2p/peer-id'
4- import { decode } from 'it-length-prefixed'
5- import { lpStream } from 'it-length-prefixed-stream'
6- import { duplexPair } from 'it-pair/duplex'
7- import { pipe } from 'it-pipe'
4+ import { lpStream } from '@libp2p/utils'
85import { alloc as uint8ArrayAlloc } from 'uint8arrays/alloc'
96import { NOISE_MSG_MAX_LENGTH_BYTES } from './constants.js'
107import { defaultCrypto } from './crypto/index.js'
118import { wrapCrypto } from './crypto.js'
129import { uint16BEDecode , uint16BEEncode } from './encoder.js'
1310import { registerMetrics } from './metrics.js'
1411import { performHandshakeInitiator , performHandshakeResponder } from './performHandshake.js'
15- import { decryptStream , encryptStream } from './streaming.js '
12+ import { toMessageStream } from './utils.ts '
1613import type { ICryptoInterface } from './crypto.js'
1714import type { NoiseComponents } from './index.js'
1815import type { MetricsRegistry } from './metrics.js'
19- import type { HandshakeResult , ICrypto , INoiseConnection , KeyPair } from './types.js'
20- import type { MultiaddrConnection , SecuredConnection , PrivateKey , PublicKey , StreamMuxerFactory , SecureConnectionOptions } from '@libp2p/interface'
21- import type { LengthPrefixedStream } from 'it-length-prefixed-stream'
22- import type { Duplex } from 'it-stream-types'
23- import type { Uint8ArrayList } from 'uint8arraylist'
16+ import type { HandshakeResult , ICrypto , INoiseConnection , INoiseExtensions , KeyPair } from './types.js'
17+ import type { SecuredConnection , PrivateKey , PublicKey , StreamMuxerFactory , SecureConnectionOptions , Logger , MessageStream } from '@libp2p/interface'
18+ import type { LengthPrefixedStream } from '@libp2p/utils'
2419
2520export interface NoiseExtensions {
2621 webtransportCerthashes : Uint8Array [ ]
@@ -45,12 +40,14 @@ export class Noise implements INoiseConnection {
4540 private readonly extensions ?: NoiseExtensions
4641 private readonly metrics ?: MetricsRegistry
4742 private readonly components : NoiseComponents
43+ private readonly log : Logger
4844
4945 constructor ( components : NoiseComponents , init : NoiseInit = { } ) {
5046 const { staticNoiseKey, extensions, crypto, prologueBytes } = init
5147 const { metrics } = components
5248
5349 this . components = components
50+ this . log = components . logger . forComponent ( 'libp2p:noise' )
5451 const _crypto = crypto ?? defaultCrypto
5552 this . crypto = wrapCrypto ( _crypto )
5653 this . extensions = {
@@ -83,31 +80,25 @@ export class Noise implements INoiseConnection {
8380 * @param options.remotePeer - PeerId of the remote peer. Used to validate the integrity of the remote peer
8481 * @param options.signal - Used to abort the operation
8582 */
86- public async secureOutbound < Stream extends Duplex < AsyncGenerator < Uint8Array | Uint8ArrayList > > = MultiaddrConnection > ( connection : Stream , options ?: SecureConnectionOptions ) : Promise < SecuredConnection < Stream , NoiseExtensions > > {
87- const wrappedConnection = lpStream (
88- connection ,
89- {
90- lengthEncoder : uint16BEEncode ,
91- lengthDecoder : uint16BEDecode ,
92- maxDataLength : NOISE_MSG_MAX_LENGTH_BYTES
93- }
94- )
83+ async secureOutbound ( connection : MessageStream , options ?: SecureConnectionOptions ) : Promise < SecuredConnection < INoiseExtensions > > {
84+ const log = connection . log ?. newScope ( 'noise' ) ?? this . log
85+ const wrappedConnection = lpStream ( connection , {
86+ lengthEncoder : uint16BEEncode ,
87+ lengthDecoder : uint16BEDecode ,
88+ maxDataLength : NOISE_MSG_MAX_LENGTH_BYTES
89+ } )
9590
9691 const handshake = await this . performHandshakeInitiator (
9792 wrappedConnection ,
9893 this . components . privateKey ,
94+ log ,
9995 options ?. remotePeer ?. publicKey ,
10096 options
10197 )
102- const conn = await this . createSecureConnection ( wrappedConnection , handshake )
103-
104- connection . source = conn . source
105- connection . sink = conn . sink
106-
10798 const publicKey = publicKeyFromProtobuf ( handshake . payload . identityKey )
10899
109100 return {
110- conn : connection ,
101+ connection : toMessageStream ( wrappedConnection . unwrap ( ) , handshake , this . metrics ) ,
111102 remoteExtensions : handshake . payload . extensions ,
112103 remotePeer : peerIdFromPublicKey ( publicKey ) ,
113104 streamMuxer : options ?. skipStreamMuxerNegotiation === true ? undefined : this . getStreamMuxer ( handshake . payload . extensions ?. streamMuxers )
@@ -144,31 +135,25 @@ export class Noise implements INoiseConnection {
144135 * @param options.remotePeer - PeerId of the remote peer. Used to validate the integrity of the remote peer
145136 * @param options.signal - Used to abort the operation
146137 */
147- public async secureInbound < Stream extends Duplex < AsyncGenerator < Uint8Array | Uint8ArrayList > > = MultiaddrConnection > ( connection : Stream , options ?: SecureConnectionOptions ) : Promise < SecuredConnection < Stream , NoiseExtensions > > {
148- const wrappedConnection = lpStream (
149- connection ,
150- {
151- lengthEncoder : uint16BEEncode ,
152- lengthDecoder : uint16BEDecode ,
153- maxDataLength : NOISE_MSG_MAX_LENGTH_BYTES
154- }
155- )
138+ async secureInbound ( connection : MessageStream , options ?: SecureConnectionOptions ) : Promise < SecuredConnection < INoiseExtensions > > {
139+ const log = connection . log ?. newScope ( 'noise' ) ?? this . log
140+ const wrappedConnection = lpStream ( connection , {
141+ lengthEncoder : uint16BEEncode ,
142+ lengthDecoder : uint16BEDecode ,
143+ maxDataLength : NOISE_MSG_MAX_LENGTH_BYTES
144+ } )
156145
157146 const handshake = await this . performHandshakeResponder (
158147 wrappedConnection ,
159148 this . components . privateKey ,
149+ log ,
160150 options ?. remotePeer ?. publicKey ,
161151 options
162152 )
163- const conn = await this . createSecureConnection ( wrappedConnection , handshake )
164-
165- connection . source = conn . source
166- connection . sink = conn . sink
167-
168153 const publicKey = publicKeyFromProtobuf ( handshake . payload . identityKey )
169154
170155 return {
171- conn : connection ,
156+ connection : toMessageStream ( wrappedConnection . unwrap ( ) , handshake , this . metrics ) ,
172157 remoteExtensions : handshake . payload . extensions ,
173158 remotePeer : peerIdFromPublicKey ( publicKey ) ,
174159 streamMuxer : options ?. skipStreamMuxerNegotiation === true ? undefined : this . getStreamMuxer ( handshake . payload . extensions ?. streamMuxers )
@@ -182,6 +167,7 @@ export class Noise implements INoiseConnection {
182167 connection : LengthPrefixedStream ,
183168 // TODO: pass private key in noise constructor via Components
184169 privateKey : PrivateKey ,
170+ log : Logger ,
185171 remoteIdentityKey ?: PublicKey ,
186172 options ?: SecureConnectionOptions
187173 ) : Promise < HandshakeResult > {
@@ -193,7 +179,7 @@ export class Noise implements INoiseConnection {
193179 connection,
194180 privateKey,
195181 remoteIdentityKey,
196- log : this . components . logger . forComponent ( 'libp2p:noise: xxhandshake') ,
182+ log : log . newScope ( ' xxhandshake') ,
197183 crypto : this . crypto ,
198184 prologue : this . prologue ,
199185 s : this . staticKey ,
@@ -218,6 +204,7 @@ export class Noise implements INoiseConnection {
218204 private async performHandshakeResponder (
219205 connection : LengthPrefixedStream ,
220206 privateKey : PrivateKey ,
207+ log : Logger ,
221208 remoteIdentityKey ?: PublicKey ,
222209 options ?: SecureConnectionOptions
223210 ) : Promise < HandshakeResult > {
@@ -229,7 +216,7 @@ export class Noise implements INoiseConnection {
229216 connection,
230217 privateKey,
231218 remoteIdentityKey,
232- log : this . components . logger . forComponent ( 'libp2p:noise: xxhandshake') ,
219+ log : log . newScope ( ' xxhandshake') ,
233220 crypto : this . crypto ,
234221 prologue : this . prologue ,
235222 s : this . staticKey ,
@@ -247,24 +234,4 @@ export class Noise implements INoiseConnection {
247234
248235 return result
249236 }
250-
251- private async createSecureConnection (
252- connection : LengthPrefixedStream < Duplex < AsyncGenerator < Uint8Array | Uint8ArrayList > > > ,
253- handshake : HandshakeResult
254- ) : Promise < Duplex < AsyncGenerator < Uint8Array | Uint8ArrayList > > > {
255- // Create encryption box/unbox wrapper
256- const [ secure , user ] = duplexPair < Uint8Array | Uint8ArrayList > ( )
257- const network = connection . unwrap ( )
258-
259- await pipe (
260- secure , // write to wrapper
261- encryptStream ( handshake , this . metrics ) , // encrypt data + prefix with message length
262- network , // send to the remote peer
263- ( source ) => decode ( source , { lengthDecoder : uint16BEDecode } ) , // read message length prefix
264- decryptStream ( handshake , this . metrics ) , // decrypt the incoming data
265- secure // pipe to the wrapper
266- )
267-
268- return user
269- }
270237}
0 commit comments