2019-11-11 15:39:09 +01:00
|
|
|
import { x25519 } from 'bcrypto';
|
2019-11-11 21:58:04 +01:00
|
|
|
import { Buffer } from "buffer";
|
2019-11-11 15:39:09 +01:00
|
|
|
|
2019-11-08 14:03:34 +01:00
|
|
|
import { bytes } from "./types/basic";
|
2019-11-11 21:58:04 +01:00
|
|
|
import { InsecureConnection, NoiseConnection, PeerId, SecureConnection, KeyPair } from "./types/libp2p";
|
2019-11-08 14:03:34 +01:00
|
|
|
|
2019-11-11 21:58:04 +01:00
|
|
|
import { Handshake } from "./handshake";
|
|
|
|
import { generateKeypair, signPayload } from "./utils";
|
|
|
|
|
|
|
|
export class Noise implements NoiseConnection {
|
2019-11-11 15:39:09 +01:00
|
|
|
private readonly privateKey: bytes;
|
|
|
|
private staticKeys?: KeyPair;
|
|
|
|
private earlyData?: bytes;
|
|
|
|
|
2019-11-08 14:03:34 +01:00
|
|
|
constructor(privateKey: bytes, staticNoiseKey?: bytes, earlyData?: bytes) {
|
2019-11-11 15:39:09 +01:00
|
|
|
this.privateKey = privateKey;
|
|
|
|
this.earlyData = earlyData;
|
2019-11-08 14:03:34 +01:00
|
|
|
|
2019-11-11 15:39:09 +01:00
|
|
|
if (staticNoiseKey) {
|
|
|
|
const publicKey = x25519.publicKeyCreate(staticNoiseKey);
|
|
|
|
this.staticKeys = {
|
|
|
|
privateKey: staticNoiseKey,
|
|
|
|
publicKey,
|
|
|
|
}
|
|
|
|
}
|
2019-11-08 14:03:34 +01:00
|
|
|
}
|
|
|
|
|
2019-11-11 21:58:04 +01:00
|
|
|
public protocol() {
|
2019-11-08 14:03:34 +01:00
|
|
|
return '/noise';
|
|
|
|
}
|
|
|
|
|
2019-11-11 21:58:04 +01:00
|
|
|
// encrypt outgoing data to the remote party (handshake as initiator)
|
|
|
|
public async secureOutbound(connection: InsecureConnection, remotePeer: PeerId) : Promise<SecureConnection> {
|
|
|
|
try {
|
|
|
|
const remotePublicKey = Buffer.from(remotePeer.pubKey);
|
|
|
|
const session = await this.createSecureConnection(connection, remotePublicKey, true);
|
|
|
|
} catch (e) {
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// decrypt incoming data (handshake as responder)
|
|
|
|
public async secureInbound(connection: InsecureConnection) : Promise<SecureConnection> {
|
|
|
|
}
|
|
|
|
|
|
|
|
private async read(ciphertext: bytes) {
|
2019-11-11 15:39:09 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2019-11-11 21:58:04 +01:00
|
|
|
private async write(plaintext: bytes) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
private async createSecureConnection(
|
|
|
|
connection: InsecureConnection,
|
|
|
|
remotePublicKey: bytes,
|
|
|
|
isInitiator: boolean,
|
|
|
|
) : Promise<SecureConnection> {
|
2019-11-11 15:39:09 +01:00
|
|
|
if (!this.staticKeys) {
|
2019-11-11 21:58:04 +01:00
|
|
|
this.staticKeys = await generateKeypair();
|
2019-11-11 15:39:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
let signedPayload;
|
|
|
|
if (this.earlyData) {
|
|
|
|
const payload = Buffer.concat([this.earlyData, this.staticKeys.publicKey])
|
|
|
|
signedPayload = await signPayload(this.privateKey, payload);
|
|
|
|
}
|
2019-11-08 14:03:34 +01:00
|
|
|
|
2019-11-11 21:58:04 +01:00
|
|
|
const prologue = Buffer.from(this.protocol());
|
|
|
|
const session = await Handshake.runXX(isInitiator, remotePublicKey, prologue, signedPayload, this.staticKeys);
|
|
|
|
|
|
|
|
return {
|
|
|
|
insecure: connection,
|
|
|
|
initiator: isInitiator,
|
|
|
|
prologue,
|
|
|
|
// localKey: get public key,
|
|
|
|
localPeer: connection.localPeer,
|
|
|
|
remotePeer: connection.remotePeer,
|
|
|
|
local: {
|
|
|
|
noiseKey: this.staticKeys.publicKey,
|
|
|
|
// libp2pKey:
|
|
|
|
},
|
|
|
|
xxNoiseSession: session,
|
|
|
|
xxComplete: true,
|
|
|
|
noiseKeypair: this.staticKeys,
|
|
|
|
}
|
2019-11-08 14:03:34 +01:00
|
|
|
}
|
|
|
|
|
2019-11-11 21:58:04 +01:00
|
|
|
|
2019-11-08 14:03:34 +01:00
|
|
|
}
|