Skip to content

Commit de57508

Browse files
committed
chore: remote peer id arg
1 parent 0ba4883 commit de57508

File tree

102 files changed

+820
-1459
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

102 files changed

+820
-1459
lines changed

packages/connection-encrypter-plaintext/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
"uint8arrays": "^5.1.0"
6262
},
6363
"devDependencies": {
64+
"@libp2p/crypto": "^4.1.9",
6465
"@libp2p/interface-compliance-tests": "^5.4.11",
6566
"@libp2p/logger": "^4.0.19",
6667
"@libp2p/peer-id-factory": "^4.2.3",

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

+11-19
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,14 @@ import { UnexpectedPeerError, InvalidCryptoExchangeError, serviceCapabilities }
2424
import { peerIdFromBytes, peerIdFromKeys } from '@libp2p/peer-id'
2525
import { pbStream } from 'it-protobuf-stream'
2626
import { Exchange, KeyType } from './pb/proto.js'
27-
import type { ComponentLogger, Logger, MultiaddrConnection, ConnectionEncrypter, SecuredConnection, PeerId } from '@libp2p/interface'
27+
import type { ComponentLogger, Logger, MultiaddrConnection, ConnectionEncrypter, SecuredConnection, PeerId, PrivateKey } from '@libp2p/interface'
2828
import type { Duplex } from 'it-stream-types'
2929
import type { Uint8ArrayList } from 'uint8arraylist'
3030

3131
const PROTOCOL = '/plaintext/2.0.0'
3232

3333
export interface PlaintextComponents {
34-
peerId: PeerId
34+
privateKey: PrivateKey
3535
logger: ComponentLogger
3636
}
3737

@@ -45,12 +45,12 @@ export interface PlaintextInit {
4545

4646
class Plaintext implements ConnectionEncrypter {
4747
public protocol: string = PROTOCOL
48-
private readonly peerId: PeerId
48+
private readonly privateKey: PrivateKey
4949
private readonly log: Logger
5050
private readonly timeout: number
5151

5252
constructor (components: PlaintextComponents, init: PlaintextInit = {}) {
53-
this.peerId = components.peerId
53+
this.privateKey = components.privateKey
5454
this.log = components.logger.forComponent('libp2p:plaintext')
5555
this.timeout = init.timeout ?? 1000
5656
}
@@ -62,39 +62,31 @@ class Plaintext implements ConnectionEncrypter {
6262
]
6363

6464
async secureInbound <Stream extends Duplex<AsyncGenerator<Uint8Array | Uint8ArrayList>> = MultiaddrConnection> (conn: Stream, remoteId?: PeerId): Promise<SecuredConnection<Stream>> {
65-
return this._encrypt(this.peerId, conn, remoteId)
65+
return this._encrypt(this.privateKey, conn, remoteId)
6666
}
6767

6868
async secureOutbound <Stream extends Duplex<AsyncGenerator<Uint8Array | Uint8ArrayList>> = MultiaddrConnection> (conn: Stream, remoteId?: PeerId): Promise<SecuredConnection<Stream>> {
69-
return this._encrypt(this.peerId, conn, remoteId)
69+
return this._encrypt(this.privateKey, conn, remoteId)
7070
}
7171

7272
/**
7373
* Encrypt connection
7474
*/
75-
async _encrypt <Stream extends Duplex<AsyncGenerator<Uint8Array | Uint8ArrayList>> = MultiaddrConnection> (localId: PeerId, conn: Stream, remoteId?: PeerId): Promise<SecuredConnection<Stream>> {
75+
async _encrypt <Stream extends Duplex<AsyncGenerator<Uint8Array | Uint8ArrayList>> = MultiaddrConnection> (privateKey: PrivateKey, conn: Stream, remoteId?: PeerId): Promise<SecuredConnection<Stream>> {
7676
const signal = AbortSignal.timeout(this.timeout)
7777
const pb = pbStream(conn).pb(Exchange)
7878

79-
let type = KeyType.RSA
80-
81-
if (localId.type === 'Ed25519') {
82-
type = KeyType.Ed25519
83-
} else if (localId.type === 'secp256k1') {
84-
type = KeyType.Secp256k1
85-
}
86-
8779
this.log('write pubkey exchange to peer %p', remoteId)
8880

8981
const [
9082
, response
9183
] = await Promise.all([
9284
// Encode the public key and write it to the remote peer
9385
pb.write({
94-
id: localId.toBytes(),
86+
id: await privateKey.public.hash(),
9587
pubkey: {
96-
Type: type,
97-
Data: localId.publicKey ?? new Uint8Array(0)
88+
Type: KeyType[privateKey.type],
89+
Data: privateKey.public.marshal()
9890
}
9991
}, {
10092
signal
@@ -126,7 +118,7 @@ class Plaintext implements ConnectionEncrypter {
126118
}
127119
} catch (err: any) {
128120
this.log.error(err)
129-
throw new InvalidCryptoExchangeError('Remote did not provide its public key')
121+
throw new InvalidCryptoExchangeError('Invalid public key - ' + err.message)
130122
}
131123

132124
if (remoteId != null && !peerId.equals(remoteId)) {

packages/connection-encrypter-plaintext/src/pb/proto.proto

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ message Exchange {
88
enum KeyType {
99
RSA = 0;
1010
Ed25519 = 1;
11-
Secp256k1 = 2;
11+
secp256k1 = 2;
1212
ECDSA = 3;
1313
}
1414

packages/connection-encrypter-plaintext/src/pb/proto.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,14 @@ export namespace Exchange {
8181
export enum KeyType {
8282
RSA = 'RSA',
8383
Ed25519 = 'Ed25519',
84-
Secp256k1 = 'Secp256k1',
84+
secp256k1 = 'secp256k1',
8585
ECDSA = 'ECDSA'
8686
}
8787

8888
enum __KeyTypeValues {
8989
RSA = 0,
9090
Ed25519 = 1,
91-
Secp256k1 = 2,
91+
secp256k1 = 2,
9292
ECDSA = 3
9393
}
9494

packages/connection-encrypter-plaintext/test/compliance.spec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
/* eslint-env mocha */
22

3+
import { generateKeyPair } from '@libp2p/crypto/keys'
34
import suite from '@libp2p/interface-compliance-tests/connection-encryption'
45
import { defaultLogger } from '@libp2p/logger'
5-
import { createEd25519PeerId } from '@libp2p/peer-id-factory'
66
import { plaintext } from '../src/index.js'
77

88
describe('plaintext compliance', () => {
99
suite({
1010
async setup (opts) {
1111
return plaintext()({
12-
peerId: opts?.peerId ?? await createEd25519PeerId(),
12+
privateKey: opts?.privateKey ?? await generateKeyPair('Ed25519'),
1313
logger: defaultLogger()
1414
})
1515
},
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,33 @@
11
/* eslint-env mocha */
22

3+
import { generateKeyPair } from '@libp2p/crypto/keys'
34
import { mockMultiaddrConnPair } from '@libp2p/interface-compliance-tests/mocks'
45
import { defaultLogger } from '@libp2p/logger'
5-
import { peerIdFromBytes } from '@libp2p/peer-id'
6-
import { createEd25519PeerId, createRSAPeerId } from '@libp2p/peer-id-factory'
6+
import { createEd25519PeerId } from '@libp2p/peer-id-factory'
77
import { multiaddr } from '@multiformats/multiaddr'
88
import { expect } from 'aegir/chai'
99
import sinon from 'sinon'
1010
import { plaintext } from '../src/index.js'
1111
import type { ConnectionEncrypter, PeerId } from '@libp2p/interface'
1212

1313
describe('plaintext', () => {
14-
let localPeer: PeerId
1514
let remotePeer: PeerId
1615
let wrongPeer: PeerId
1716
let encrypter: ConnectionEncrypter
1817
let encrypterRemote: ConnectionEncrypter
1918

2019
beforeEach(async () => {
21-
[localPeer, remotePeer, wrongPeer] = await Promise.all([
22-
createEd25519PeerId(),
20+
[remotePeer, wrongPeer] = await Promise.all([
2321
createEd25519PeerId(),
2422
createEd25519PeerId()
2523
])
2624

2725
encrypter = plaintext()({
28-
peerId: localPeer,
26+
privateKey: await generateKeyPair('Ed25519'),
2927
logger: defaultLogger()
3028
})
3129
encrypterRemote = plaintext()({
32-
peerId: remotePeer,
30+
privateKey: await generateKeyPair('Ed25519'),
3331
logger: defaultLogger()
3432
})
3533
})
@@ -55,28 +53,4 @@ describe('plaintext', () => {
5553
expect(err).to.have.property('name', 'UnexpectedPeerError')
5654
})
5755
})
58-
59-
it('should fail if the peer does not provide its public key', async () => {
60-
const peer = await createRSAPeerId()
61-
remotePeer = peerIdFromBytes(peer.toBytes())
62-
63-
encrypter = plaintext()({
64-
peerId: remotePeer,
65-
logger: defaultLogger()
66-
})
67-
68-
const { inbound, outbound } = mockMultiaddrConnPair({
69-
remotePeer,
70-
addrs: [
71-
multiaddr('/ip4/127.0.0.1/tcp/1234'),
72-
multiaddr('/ip4/127.0.0.1/tcp/1235')
73-
]
74-
})
75-
76-
await expect(Promise.all([
77-
encrypter.secureInbound(inbound),
78-
encrypterRemote.secureOutbound(outbound, localPeer)
79-
]))
80-
.to.eventually.be.rejected.with.property('name', 'InvalidCryptoExchangeError')
81-
})
8256
})

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@
1919
*/
2020

2121
import { TLS } from './tls.js'
22-
import type { ComponentLogger, ConnectionEncrypter, PeerId } from '@libp2p/interface'
22+
import type { ComponentLogger, ConnectionEncrypter, PrivateKey } from '@libp2p/interface'
2323

2424
export const PROTOCOL = '/tls/1.0.0'
2525

2626
export interface TLSComponents {
27-
peerId: PeerId
27+
privateKey: PrivateKey
2828
logger: ComponentLogger
2929
}
3030

packages/connection-encrypter-tls/src/pb/index.proto

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ syntax = "proto3";
33
enum KeyType {
44
RSA = 0;
55
Ed25519 = 1;
6-
Secp256k1 = 2;
6+
secp256k1 = 2;
77
ECDSA = 3;
88
}
99

packages/connection-encrypter-tls/src/pb/index.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,14 @@ import type { Uint8ArrayList } from 'uint8arraylist'
1010
export enum KeyType {
1111
RSA = 'RSA',
1212
Ed25519 = 'Ed25519',
13-
Secp256k1 = 'Secp256k1',
13+
secp256k1 = 'secp256k1',
1414
ECDSA = 'ECDSA'
1515
}
1616

1717
enum __KeyTypeValues {
1818
RSA = 0,
1919
Ed25519 = 1,
20-
Secp256k1 = 2,
20+
secp256k1 = 2,
2121
ECDSA = 3
2222
}
2323

packages/connection-encrypter-tls/src/tls.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,19 @@ import { HandshakeTimeoutError } from './errors.js'
2424
import { generateCertificate, verifyPeerCertificate, itToStream, streamToIt } from './utils.js'
2525
import { PROTOCOL } from './index.js'
2626
import type { TLSComponents, TLSInit } from './index.js'
27-
import type { MultiaddrConnection, ConnectionEncrypter, SecuredConnection, PeerId, Logger } from '@libp2p/interface'
27+
import type { MultiaddrConnection, ConnectionEncrypter, SecuredConnection, PeerId, Logger, PrivateKey } from '@libp2p/interface'
2828
import type { Duplex } from 'it-stream-types'
2929
import type { Uint8ArrayList } from 'uint8arraylist'
3030

3131
export class TLS implements ConnectionEncrypter {
3232
public protocol: string = PROTOCOL
3333
private readonly log: Logger
34-
private readonly peerId: PeerId
34+
private readonly privateKey: PrivateKey
3535
private readonly timeout: number
3636

3737
constructor (components: TLSComponents, init: TLSInit = {}) {
3838
this.log = components.logger.forComponent('libp2p:tls')
39-
this.peerId = components.peerId
39+
this.privateKey = components.privateKey
4040
this.timeout = init.timeout ?? 1000
4141
}
4242

@@ -59,7 +59,7 @@ export class TLS implements ConnectionEncrypter {
5959
*/
6060
async _encrypt <Stream extends Duplex<AsyncGenerator<Uint8Array | Uint8ArrayList>> = MultiaddrConnection> (conn: Stream, isServer: boolean, remoteId?: PeerId): Promise<SecuredConnection<Stream>> {
6161
const opts: TLSSocketOptions = {
62-
...await generateCertificate(this.peerId),
62+
...await generateCertificate(this.privateKey),
6363
isServer,
6464
// require TLS 1.3 or later
6565
minVersion: 'TLSv1.3',

packages/connection-encrypter-tls/src/utils.ts

+7-36
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Duplex as DuplexStream } from 'node:stream'
2-
import { Ed25519PublicKey, Secp256k1PublicKey, marshalPublicKey, supportedKeys, unmarshalPrivateKey, unmarshalPublicKey } from '@libp2p/crypto/keys'
3-
import { InvalidCryptoExchangeError, InvalidParametersError, UnexpectedPeerError } from '@libp2p/interface'
2+
import { Ed25519PublicKey, Secp256k1PublicKey, marshalPublicKey, supportedKeys } from '@libp2p/crypto/keys'
3+
import { InvalidCryptoExchangeError, UnexpectedPeerError } from '@libp2p/interface'
44
import { peerIdFromKeys } from '@libp2p/peer-id'
55
import { AsnConvert } from '@peculiar/asn1-schema'
66
import * as asn1X509 from '@peculiar/asn1-x509'
@@ -13,7 +13,7 @@ import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
1313
import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
1414
import { InvalidCertificateError } from './errors.js'
1515
import { KeyType, PublicKey } from './pb/index.js'
16-
import type { PeerId, PublicKey as Libp2pPublicKey, Logger } from '@libp2p/interface'
16+
import type { PeerId, PublicKey as Libp2pPublicKey, Logger, PrivateKey } from '@libp2p/interface'
1717
import type { Duplex } from 'it-stream-types'
1818
import type { Uint8ArrayList } from 'uint8arraylist'
1919

@@ -74,7 +74,7 @@ export async function verifyPeerCertificate (rawCertificate: Uint8Array, expecte
7474

7575
if (remotePublicKey.type === KeyType.Ed25519) {
7676
remoteLibp2pPublicKey = new Ed25519PublicKey(remotePublicKeyData)
77-
} else if (remotePublicKey.type === KeyType.Secp256k1) {
77+
} else if (remotePublicKey.type === KeyType.secp256k1) {
7878
remoteLibp2pPublicKey = new Secp256k1PublicKey(remotePublicKeyData)
7979
} else if (remotePublicKey.type === KeyType.RSA) {
8080
remoteLibp2pPublicKey = supportedKeys.rsa.unmarshalRsaPublicKey(remotePublicKeyData)
@@ -104,35 +104,7 @@ export async function verifyPeerCertificate (rawCertificate: Uint8Array, expecte
104104
return remotePeerId
105105
}
106106

107-
export async function generateCertificate (peerId: PeerId): Promise<{ cert: string, key: string }> {
108-
if (peerId.privateKey == null) {
109-
throw new InvalidParametersError('Private key was missing from PeerId')
110-
}
111-
112-
if (peerId.publicKey == null) {
113-
throw new InvalidParametersError('Public key missing from PeerId')
114-
}
115-
116-
const publicKey = unmarshalPublicKey(peerId.publicKey)
117-
let keyType: KeyType
118-
let keyData: Uint8Array
119-
120-
if (peerId.type === 'Ed25519') {
121-
// Ed25519: Only the 32 bytes of the public key
122-
keyType = KeyType.Ed25519
123-
keyData = publicKey.marshal()
124-
} else if (peerId.type === 'secp256k1') {
125-
// Secp256k1: Only the compressed form of the public key. 33 bytes.
126-
keyType = KeyType.Secp256k1
127-
keyData = publicKey.marshal()
128-
} else if (peerId.type === 'RSA') {
129-
// The rest of the keys are encoded as a SubjectPublicKeyInfo structure in PKIX, ASN.1 DER form.
130-
keyType = KeyType.RSA
131-
keyData = publicKey.marshal()
132-
} else {
133-
throw new InvalidParametersError('PeerId had unknown or unsupported type')
134-
}
135-
107+
export async function generateCertificate (privateKey: PrivateKey): Promise<{ cert: string, key: string }> {
136108
const now = Date.now()
137109

138110
const alg = {
@@ -144,7 +116,6 @@ export async function generateCertificate (peerId: PeerId): Promise<{ cert: stri
144116
const keys = await crypto.subtle.generateKey(alg, true, ['sign'])
145117
const certPublicKeySpki = await crypto.subtle.exportKey('spki', keys.publicKey)
146118
const dataToSign = encodeSignatureData(certPublicKeySpki)
147-
const privateKey = await unmarshalPrivateKey(peerId.privateKey)
148119
const sig = await privateKey.sign(dataToSign)
149120
const notAfter = new Date(now + CERT_VALIDITY_PERIOD_TO)
150121
// workaround for https://github.com/PeculiarVentures/x509/issues/73
@@ -163,8 +134,8 @@ export async function generateCertificate (peerId: PeerId): Promise<{ cert: stri
163134
// publicKey
164135
new asn1js.OctetString({
165136
valueHex: PublicKey.encode({
166-
type: keyType,
167-
data: keyData
137+
type: KeyType[privateKey.type],
138+
data: privateKey.public.marshal()
168139
})
169140
}),
170141
// signature

packages/connection-encrypter-tls/test/compliance.spec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
/* eslint-env mocha */
22

3+
import { generateKeyPair } from '@libp2p/crypto/keys'
34
import suite from '@libp2p/interface-compliance-tests/connection-encryption'
45
import { defaultLogger } from '@libp2p/logger'
5-
import { createEd25519PeerId } from '@libp2p/peer-id-factory'
66
import { tls } from '../src/index.js'
77

88
describe('tls compliance', () => {
99
suite({
1010
async setup (opts) {
1111
return tls()({
12-
peerId: opts?.peerId ?? await createEd25519PeerId(),
12+
privateKey: opts?.privateKey ?? await generateKeyPair('Ed25519'),
1313
logger: defaultLogger()
1414
})
1515
},

0 commit comments

Comments
 (0)