Handshake payload refactor

This commit is contained in:
morrigan
2019-11-20 21:38:14 +01:00
parent 3519df482d
commit af95dc2fcd
6 changed files with 64 additions and 42 deletions

View File

@ -1,6 +1,7 @@
import { bytes, bytes32 } from "./@types/basic";
import { NoiseSession, XXHandshake } from "./xx";
import { KeyPair, PeerId } from "./@types/libp2p";
import {Buffer} from "buffer";
type handshakeType = "XX";
@ -29,7 +30,10 @@ export class Handshake {
const xx = new XXHandshake();
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;
}

View File

@ -3,7 +3,7 @@ import { Buffer } from "buffer";
import Wrap from 'it-pb-rpc';
import { Handshake } from "./handshake";
import { generateKeypair, signPayload } from "./utils";
import { createHandshakePayload, generateKeypair, getHandshakePayload } from "./utils";
import { decryptStreams, encryptStreams } from "./crypto";
import { bytes } from "./@types/basic";
import { NoiseConnection, PeerId, KeyPair, SecureOutbound } from "./@types/libp2p";
@ -68,14 +68,11 @@ export class Noise implements NoiseConnection {
this.staticKeys = await generateKeypair();
}
let signedPayload;
if (this.earlyData) {
const payload = Buffer.concat([this.earlyData, this.staticKeys.publicKey])
signedPayload = await signPayload(this.privateKey, payload);
}
const payload = getHandshakePayload(this.staticKeys.publicKey);
const signedPayload = signHandshakePayload(this.staticKeys.privateKey, payload);
const handshakePayload = await createHandshakePayload(this.staticKeys, signedPayload);
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);
return await encryptStreams(connection, session);

View File

@ -1,8 +1,14 @@
import { x25519 } from 'bcrypto';
import * as crypto from 'libp2p-crypto';
import { x25519, ed25519 } from 'bcrypto';
import protobuf from "protobufjs";
import { KeyPair } from "./@types/libp2p";
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> {
const privateKey = x25519.privateKeyGenerate();
@ -14,8 +20,40 @@ export async function generateKeypair() : Promise<KeyPair> {
}
}
export async function signPayload(privateKey: bytes, payload: bytes) {
const Ed25519PrivateKey = crypto.keys.supportedKeys.ed25519.Ed25519PrivateKey;
// const ed25519 = Ed25519PrivateKey(privateKey, "need-to-get-public-key");
// return ed25519.sign(privateKey, payload);
export async function createHandshakePayload(
libp2pKeys: KeyPair,
signedPayload: bytes,
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,
}
}