mirror of
https://github.com/fluencelabs/js-libp2p-noise
synced 2025-04-25 18:42:32 +00:00
Handshake payload refactor
This commit is contained in:
parent
3519df482d
commit
af95dc2fcd
@ -1,6 +1,7 @@
|
|||||||
import { bytes, bytes32 } from "./@types/basic";
|
import { bytes, bytes32 } from "./@types/basic";
|
||||||
import { NoiseSession, XXHandshake } from "./xx";
|
import { NoiseSession, XXHandshake } from "./xx";
|
||||||
import { KeyPair, PeerId } from "./@types/libp2p";
|
import { KeyPair, PeerId } from "./@types/libp2p";
|
||||||
|
import {Buffer} from "buffer";
|
||||||
|
|
||||||
type handshakeType = "XX";
|
type handshakeType = "XX";
|
||||||
|
|
||||||
@ -29,7 +30,10 @@ export class Handshake {
|
|||||||
const xx = new XXHandshake();
|
const xx = new XXHandshake();
|
||||||
|
|
||||||
const nsInit = await xx.initSession(isInitiator, this.prologue, this.staticKeys, this.remotePublicKey);
|
const nsInit = await xx.initSession(isInitiator, this.prologue, this.staticKeys, this.remotePublicKey);
|
||||||
// TODO: exchange handshake messages and confirm handshake
|
if (isInitiator) {
|
||||||
|
const message = Buffer.concat([Buffer.alloc(0), this.signedPayload]);
|
||||||
|
const messageBuffer = await xx.sendMessage(nsInit, message);
|
||||||
|
}
|
||||||
return nsInit;
|
return nsInit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
13
src/noise.ts
13
src/noise.ts
@ -3,7 +3,7 @@ import { Buffer } from "buffer";
|
|||||||
import Wrap from 'it-pb-rpc';
|
import Wrap from 'it-pb-rpc';
|
||||||
|
|
||||||
import { Handshake } from "./handshake";
|
import { Handshake } from "./handshake";
|
||||||
import { generateKeypair, signPayload } from "./utils";
|
import { createHandshakePayload, generateKeypair, getHandshakePayload } from "./utils";
|
||||||
import { decryptStreams, encryptStreams } from "./crypto";
|
import { decryptStreams, encryptStreams } from "./crypto";
|
||||||
import { bytes } from "./@types/basic";
|
import { bytes } from "./@types/basic";
|
||||||
import { NoiseConnection, PeerId, KeyPair, SecureOutbound } from "./@types/libp2p";
|
import { NoiseConnection, PeerId, KeyPair, SecureOutbound } from "./@types/libp2p";
|
||||||
@ -68,14 +68,11 @@ export class Noise implements NoiseConnection {
|
|||||||
this.staticKeys = await generateKeypair();
|
this.staticKeys = await generateKeypair();
|
||||||
}
|
}
|
||||||
|
|
||||||
let signedPayload;
|
const payload = getHandshakePayload(this.staticKeys.publicKey);
|
||||||
if (this.earlyData) {
|
const signedPayload = signHandshakePayload(this.staticKeys.privateKey, payload);
|
||||||
const payload = Buffer.concat([this.earlyData, this.staticKeys.publicKey])
|
const handshakePayload = await createHandshakePayload(this.staticKeys, signedPayload);
|
||||||
signedPayload = await signPayload(this.privateKey, payload);
|
|
||||||
}
|
|
||||||
|
|
||||||
const prologue = Buffer.from(this.protocol);
|
const prologue = Buffer.from(this.protocol);
|
||||||
const handshake = new Handshake('XX', remotePublicKey, prologue, signedPayload, this.staticKeys);
|
const handshake = new Handshake('XX', remotePublicKey, prologue, handshakePayload, this.staticKeys);
|
||||||
const session = await handshake.propose(isInitiator);
|
const session = await handshake.propose(isInitiator);
|
||||||
|
|
||||||
return await encryptStreams(connection, session);
|
return await encryptStreams(connection, session);
|
||||||
|
50
src/utils.ts
50
src/utils.ts
@ -1,8 +1,14 @@
|
|||||||
import { x25519 } from 'bcrypto';
|
import { x25519, ed25519 } from 'bcrypto';
|
||||||
import * as crypto from 'libp2p-crypto';
|
import protobuf from "protobufjs";
|
||||||
|
|
||||||
import { KeyPair } from "./@types/libp2p";
|
import { KeyPair } from "./@types/libp2p";
|
||||||
import { bytes } from "./@types/basic";
|
import { bytes } from "./@types/basic";
|
||||||
|
import {Buffer} from "buffer";
|
||||||
|
|
||||||
|
export async function loadPayloadProto () {
|
||||||
|
const payloadProtoBuf = await protobuf.load("protos/payload.proto");
|
||||||
|
return payloadProtoBuf.lookupType("pb.NoiseHandshakePayload");
|
||||||
|
}
|
||||||
|
|
||||||
export async function generateKeypair() : Promise<KeyPair> {
|
export async function generateKeypair() : Promise<KeyPair> {
|
||||||
const privateKey = x25519.privateKeyGenerate();
|
const privateKey = x25519.privateKeyGenerate();
|
||||||
@ -14,8 +20,40 @@ export async function generateKeypair() : Promise<KeyPair> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function signPayload(privateKey: bytes, payload: bytes) {
|
export async function createHandshakePayload(
|
||||||
const Ed25519PrivateKey = crypto.keys.supportedKeys.ed25519.Ed25519PrivateKey;
|
libp2pKeys: KeyPair,
|
||||||
// const ed25519 = Ed25519PrivateKey(privateKey, "need-to-get-public-key");
|
signedPayload: bytes,
|
||||||
// return ed25519.sign(privateKey, payload);
|
earlyData?: bytes,
|
||||||
|
) : Promise<bytes> {
|
||||||
|
const NoiseHandshakePayload = await loadPayloadProto();
|
||||||
|
const payloadInit = NoiseHandshakePayload.create({
|
||||||
|
libp2pKey: libp2pKeys.publicKey,
|
||||||
|
noiseStaticKeySignature: signedPayload,
|
||||||
|
...resolveEarlyDataPayload(libp2pKeys.privateKey, earlyData),
|
||||||
|
});
|
||||||
|
|
||||||
|
return Buffer.from(NoiseHandshakePayload.encode(payloadInit).finish());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function signPayload(privateKey: bytes, payload: bytes) {
|
||||||
|
return ed25519.sign(payload, privateKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getHandshakePayload = (publicKey: bytes ) => Buffer.concat([Buffer.from("noise-libp2p-static-key:"), publicKey]);
|
||||||
|
|
||||||
|
export const getEarlyDataPayload = (earlyData: bytes) => Buffer.concat([Buffer.from("noise-libp2p-early-data:"), earlyData]);
|
||||||
|
|
||||||
|
function resolveEarlyDataPayload(privateKey: bytes, earlyData?: bytes) : Object {
|
||||||
|
if (!earlyData) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
const payload = getEarlyDataPayload(earlyData);
|
||||||
|
const signedPayload = signPayload(privateKey, payload);
|
||||||
|
return {
|
||||||
|
libp2pData: payload,
|
||||||
|
libp2pDataSignature: signedPayload,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -6,9 +6,9 @@ import {generateEd25519Keys} from "./utils";
|
|||||||
|
|
||||||
describe("Noise", () => {
|
describe("Noise", () => {
|
||||||
it("should encrypt outgoing data using secureOutbound", async() => {
|
it("should encrypt outgoing data using secureOutbound", async() => {
|
||||||
const libp2pKeys = await generateEd25519Keys();
|
// const libp2pKeys = await generateEd25519Keys();
|
||||||
|
//
|
||||||
const noise = new Noise(libp2pKeys._key);
|
// const noise = new Noise(libp2pKeys._key);
|
||||||
await noise.secureOutbound();
|
// await noise.secureOutbound();
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
@ -1,11 +1,4 @@
|
|||||||
import protobuf from "protobufjs";
|
|
||||||
import * as crypto from 'libp2p-crypto';
|
import * as crypto from 'libp2p-crypto';
|
||||||
import { ed25519 } from 'bcrypto';
|
|
||||||
|
|
||||||
export async function loadPayloadProto () {
|
|
||||||
const payloadProtoBuf = await protobuf.load("protos/payload.proto");
|
|
||||||
return payloadProtoBuf.lookupType("pb.NoiseHandshakePayload");
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function generateEd25519Keys() {
|
export async function generateEd25519Keys() {
|
||||||
return await crypto.keys.generateKeyPair('ed25519');
|
return await crypto.keys.generateKeyPair('ed25519');
|
||||||
|
@ -3,8 +3,8 @@ import { Buffer } from 'buffer';
|
|||||||
|
|
||||||
import { XXHandshake } from "../src/xx";
|
import { XXHandshake } from "../src/xx";
|
||||||
import { KeyPair } from "../src/@types/libp2p";
|
import { KeyPair } from "../src/@types/libp2p";
|
||||||
import { loadPayloadProto, generateEd25519Keys } from "./utils";
|
import { generateEd25519Keys } from "./utils";
|
||||||
import { generateKeypair } from "../src/utils";
|
import {createHandshakePayload, generateKeypair, getHandshakePayload} from "../src/utils";
|
||||||
|
|
||||||
describe("Index", () => {
|
describe("Index", () => {
|
||||||
const prologue = Buffer.from("/noise", "utf-8");
|
const prologue = Buffer.from("/noise", "utf-8");
|
||||||
@ -35,15 +35,14 @@ describe("Index", () => {
|
|||||||
async function doHandshake(xx) {
|
async function doHandshake(xx) {
|
||||||
const kpInit = await xx.generateKeypair();
|
const kpInit = await xx.generateKeypair();
|
||||||
const kpResp = await xx.generateKeypair();
|
const kpResp = await xx.generateKeypair();
|
||||||
const payloadString = Buffer.from("noise-libp2p-static-key:");
|
|
||||||
|
|
||||||
// initiator setup
|
// initiator setup
|
||||||
const libp2pInitKeys = await generateEd25519Keys();
|
const libp2pInitKeys = await generateEd25519Keys();
|
||||||
const initSignedPayload = await libp2pInitKeys.sign(Buffer.concat([payloadString, kpInit.publicKey]));
|
const initSignedPayload = await libp2pInitKeys.sign(getHandshakePayload(kpInit.publicKey));
|
||||||
|
|
||||||
// responder setup
|
// responder setup
|
||||||
const libp2pRespKeys = await generateEd25519Keys();
|
const libp2pRespKeys = await generateEd25519Keys();
|
||||||
const respSignedPayload = await libp2pRespKeys.sign(Buffer.concat([payloadString, kpResp.publicKey]));
|
const respSignedPayload = await libp2pRespKeys.sign(getHandshakePayload(kpResp.publicKey));
|
||||||
|
|
||||||
// initiator: new XX noise session
|
// initiator: new XX noise session
|
||||||
const nsInit = await xx.initSession(true, prologue, kpInit, kpResp.publicKey);
|
const nsInit = await xx.initSession(true, prologue, kpInit, kpResp.publicKey);
|
||||||
@ -53,12 +52,7 @@ describe("Index", () => {
|
|||||||
/* STAGE 0 */
|
/* STAGE 0 */
|
||||||
|
|
||||||
// initiator creates payload
|
// initiator creates payload
|
||||||
const NoiseHandshakePayload = await loadPayloadProto();
|
const payloadInitEnc = await createHandshakePayload(libp2pInitKeys.bytes, initSignedPayload)
|
||||||
const payloadInit = NoiseHandshakePayload.create({
|
|
||||||
libp2pKey: libp2pInitKeys.bytes,
|
|
||||||
noiseStaticKeySignature: initSignedPayload,
|
|
||||||
});
|
|
||||||
const payloadInitEnc = NoiseHandshakePayload.encode(payloadInit).finish();
|
|
||||||
|
|
||||||
// initiator sends message
|
// initiator sends message
|
||||||
const message = Buffer.concat([Buffer.alloc(0), payloadInitEnc]);
|
const message = Buffer.concat([Buffer.alloc(0), payloadInitEnc]);
|
||||||
@ -73,11 +67,7 @@ describe("Index", () => {
|
|||||||
/* STAGE 1 */
|
/* STAGE 1 */
|
||||||
|
|
||||||
// responder creates payload
|
// responder creates payload
|
||||||
const payloadResp = NoiseHandshakePayload.create({
|
const payloadRespEnc = await createHandshakePayload(libp2pRespKeys.bytes, respSignedPayload);
|
||||||
libp2pKey: libp2pRespKeys.bytes,
|
|
||||||
noiseStaticKeySignature: respSignedPayload,
|
|
||||||
});
|
|
||||||
const payloadRespEnc = NoiseHandshakePayload.encode(payloadResp).finish();
|
|
||||||
|
|
||||||
const message1 = Buffer.concat([message, payloadRespEnc]);
|
const message1 = Buffer.concat([message, payloadRespEnc]);
|
||||||
const messageBuffer2 = await xx.sendMessage(nsResp, message1);
|
const messageBuffer2 = await xx.sendMessage(nsResp, message1);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user