mirror of
https://github.com/fluencelabs/js-libp2p-noise
synced 2025-06-11 01:41:33 +00:00
Create handshake interface to support performing different handshakes
This commit is contained in:
8
src/@types/handshake-interface.ts
Normal file
8
src/@types/handshake-interface.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import {bytes} from "./basic";
|
||||
import {NoiseSession} from "./handshake";
|
||||
|
||||
export interface HandshakeInterface {
|
||||
session: NoiseSession;
|
||||
encrypt(plaintext: bytes, session: NoiseSession): bytes;
|
||||
decrypt(ciphertext: bytes, session: NoiseSession): bytes;
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import { Buffer } from "buffer";
|
||||
import { Handshake } from "./handshake-xx";
|
||||
import {HandshakeInterface} from "./@types/handshake-interface";
|
||||
|
||||
interface ReturnEncryptionWrapper {
|
||||
(source: Iterable<Uint8Array>): AsyncIterableIterator<Uint8Array>;
|
||||
@ -8,7 +8,7 @@ interface ReturnEncryptionWrapper {
|
||||
const maxPlaintextLength = 65519;
|
||||
|
||||
// Returns generator that encrypts payload from the user
|
||||
export function encryptStream(handshake: Handshake): ReturnEncryptionWrapper {
|
||||
export function encryptStream(handshake: HandshakeInterface): ReturnEncryptionWrapper {
|
||||
return async function * (source) {
|
||||
for await (const chunk of source) {
|
||||
const chunkBuffer = Buffer.from(chunk.buffer, chunk.byteOffset, chunk.length);
|
||||
@ -28,7 +28,7 @@ export function encryptStream(handshake: Handshake): ReturnEncryptionWrapper {
|
||||
|
||||
|
||||
// Decrypt received payload to the user
|
||||
export function decryptStream(handshake: Handshake): ReturnEncryptionWrapper {
|
||||
export function decryptStream(handshake: HandshakeInterface): ReturnEncryptionWrapper {
|
||||
return async function * (source) {
|
||||
for await (const chunk of source) {
|
||||
const chunkBuffer = Buffer.from(chunk.buffer, chunk.byteOffset, chunk.length);
|
||||
|
@ -4,7 +4,7 @@ import {KeyPair, PeerId} from "./@types/libp2p";
|
||||
import {WrappedConnection} from "./noise";
|
||||
import {IKHandshake} from "./handshakes/ik";
|
||||
|
||||
export class Handshake {
|
||||
export class Handshake { // implements HandshakeHandler
|
||||
public isInitiator: boolean;
|
||||
public session: NoiseSession;
|
||||
|
||||
|
@ -4,6 +4,7 @@ import { XXHandshake } from "./handshakes/xx";
|
||||
import { KeyPair, PeerId } from "./@types/libp2p";
|
||||
import { bytes, bytes32 } from "./@types/basic";
|
||||
import { NoiseSession } from "./@types/handshake";
|
||||
import {HandshakeInterface} from "./@types/handshake-interface";
|
||||
import {
|
||||
createHandshakePayload,
|
||||
getHandshakePayload,
|
||||
@ -15,7 +16,7 @@ import { logger } from "./logger";
|
||||
import { decodeMessageBuffer, encodeMessageBuffer } from "./encoder";
|
||||
import { WrappedConnection } from "./noise";
|
||||
|
||||
export class Handshake {
|
||||
export class Handshake implements HandshakeInterface {
|
||||
public isInitiator: boolean;
|
||||
public session: NoiseSession;
|
||||
|
||||
@ -50,7 +51,7 @@ export class Handshake {
|
||||
}
|
||||
|
||||
// stage 0
|
||||
async propose(): Promise<void> {
|
||||
public async propose(): Promise<void> {
|
||||
if (this.isInitiator) {
|
||||
logger("Stage 0 - Initiator starting to send first message.");
|
||||
const messageBuffer = this.xx.sendMessage(this.session, Buffer.alloc(0));
|
||||
@ -65,7 +66,7 @@ export class Handshake {
|
||||
}
|
||||
|
||||
// stage 1
|
||||
async exchange(): Promise<void> {
|
||||
public async exchange(): Promise<void> {
|
||||
if (this.isInitiator) {
|
||||
logger('Stage 1 - Initiator waiting to receive first message from responder...');
|
||||
const receivedMessageBuffer = decodeMessageBuffer((await this.connection.readLP()).slice());
|
||||
@ -97,7 +98,7 @@ export class Handshake {
|
||||
}
|
||||
|
||||
// stage 2
|
||||
async finish(earlyData?: bytes): Promise<void> {
|
||||
public async finish(earlyData?: bytes): Promise<void> {
|
||||
if (this.isInitiator) {
|
||||
logger('Stage 2 - Initiator sending third handshake message.');
|
||||
const signedPayload = signPayload(this.libp2pPrivateKey, getHandshakePayload(this.staticKeys.publicKey));
|
||||
|
26
src/noise.ts
26
src/noise.ts
@ -6,13 +6,15 @@ import ensureBuffer from 'it-buffer';
|
||||
import pipe from 'it-pipe';
|
||||
import lp from 'it-length-prefixed';
|
||||
|
||||
import { Handshake } from "./handshake-xx";
|
||||
import { Handshake as XX } from "./handshake-xx";
|
||||
import { generateKeypair } from "./utils";
|
||||
import { uint16BEDecode, uint16BEEncode } from "./encoder";
|
||||
import { decryptStream, encryptStream } from "./crypto";
|
||||
import { bytes } from "./@types/basic";
|
||||
import { NoiseConnection, PeerId, KeyPair, SecureOutbound } from "./@types/libp2p";
|
||||
import { Duplex } from "./@types/it-pair";
|
||||
import {XXHandshake} from "./handshakes/xx";
|
||||
import {HandshakeInterface} from "./@types/handshake-interface";
|
||||
|
||||
export type WrappedConnection = ReturnType<typeof Wrap>;
|
||||
|
||||
@ -89,24 +91,22 @@ export class Noise implements NoiseConnection {
|
||||
isInitiator: boolean,
|
||||
libp2pPublicKey: bytes,
|
||||
remotePeer: PeerId,
|
||||
): Promise<Handshake> {
|
||||
): Promise<HandshakeInterface> {
|
||||
// TODO: Implement noise pipes
|
||||
|
||||
if (false) {
|
||||
// TODO: Implement noise pipes
|
||||
|
||||
} else {
|
||||
return await this.performXXHandshake(connection, isInitiator, libp2pPublicKey, remotePeer)
|
||||
const prologue = Buffer.from(this.protocol);
|
||||
const handshake = new XX(isInitiator, this.privateKey, libp2pPublicKey, prologue, this.staticKeys, connection, remotePeer);
|
||||
|
||||
return await this.performXXHandshake(handshake);
|
||||
}
|
||||
}
|
||||
|
||||
private async performXXHandshake(
|
||||
connection: WrappedConnection,
|
||||
isInitiator: boolean,
|
||||
libp2pPublicKey: bytes,
|
||||
remotePeer: PeerId,
|
||||
): Promise<Handshake> {
|
||||
const prologue = Buffer.from(this.protocol);
|
||||
const handshake = new Handshake(isInitiator, this.privateKey, libp2pPublicKey, prologue, this.staticKeys, connection, remotePeer);
|
||||
|
||||
handshake: XX
|
||||
): Promise<HandshakeInterface> {
|
||||
try {
|
||||
await handshake.propose();
|
||||
await handshake.exchange();
|
||||
@ -120,7 +120,7 @@ export class Noise implements NoiseConnection {
|
||||
|
||||
private async createSecureConnection(
|
||||
connection: WrappedConnection,
|
||||
handshake: Handshake,
|
||||
handshake: HandshakeInterface,
|
||||
): Promise<Duplex> {
|
||||
// Create encryption box/unbox wrapper
|
||||
const [secure, user] = DuplexPair();
|
||||
|
Reference in New Issue
Block a user