Init
This commit is contained in:
+2
-48
@@ -4,7 +4,6 @@ import { invoke } from "@tauri-apps/api/core";
|
|||||||
import "./App.css";
|
import "./App.css";
|
||||||
import { EnclaveWebSocket } from "./protocol/ws";
|
import { EnclaveWebSocket } from "./protocol/ws";
|
||||||
import * as ed from "@noble/ed25519";
|
import * as ed from "@noble/ed25519";
|
||||||
import { base58 } from "@scure/base";
|
|
||||||
import { sha512 } from "@noble/hashes/sha2.js";
|
import { sha512 } from "@noble/hashes/sha2.js";
|
||||||
|
|
||||||
ed.hashes.sha512 = sha512;
|
ed.hashes.sha512 = sha512;
|
||||||
@@ -20,55 +19,10 @@ function App() {
|
|||||||
initialized.current = true;
|
initialized.current = true;
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
const ws = new EnclaveWebSocket("ws://localhost:3415");
|
const ws = new EnclaveWebSocket("localhost:3415");
|
||||||
|
|
||||||
const timestamp = Date.now();
|
|
||||||
const hostname = "localhost:3415";
|
|
||||||
|
|
||||||
const msg = new TextEncoder().encode(`${timestamp}@${hostname}`);
|
|
||||||
|
|
||||||
ws.clientSecretKey = ed.utils.randomSecretKey();
|
ws.clientSecretKey = ed.utils.randomSecretKey();
|
||||||
|
|
||||||
ws.clientPublicKey = ed.getPublicKey(ws.clientSecretKey);
|
ws.clientPublicKey = ed.getPublicKey(ws.clientSecretKey);
|
||||||
|
ws.init();
|
||||||
const publicKeyString = base58.encode(ws.clientPublicKey);
|
|
||||||
|
|
||||||
ws.send({
|
|
||||||
method: "Initialize",
|
|
||||||
public_key: publicKeyString,
|
|
||||||
signature: base58.encode(ed.sign(msg, ws.clientSecretKey)),
|
|
||||||
|
|
||||||
timestamp,
|
|
||||||
hostname,
|
|
||||||
});
|
|
||||||
|
|
||||||
const initialized = await ws.read();
|
|
||||||
|
|
||||||
if (initialized.method !== "Initialized") {
|
|
||||||
console.error("Invalid method from server, closing. ", initialized);
|
|
||||||
ws.websocket.close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (initialized.hostname !== hostname) {
|
|
||||||
console.error("Server is trying to be a middle man", initialized);
|
|
||||||
ws.websocket.close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const sigMsg = new TextEncoder().encode(
|
|
||||||
`${initialized.timestamp}@${hostname}@${publicKeyString}`,
|
|
||||||
);
|
|
||||||
|
|
||||||
ws.serverPublicKey = base58.decode(initialized.public_key);
|
|
||||||
const signature = base58.decode(initialized.signature);
|
|
||||||
|
|
||||||
if (!ed.verify(signature, sigMsg, ws.serverPublicKey)) {
|
|
||||||
console.error("Invalid signature", initialized);
|
|
||||||
ws.websocket.close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("OK");
|
console.log("OK");
|
||||||
})();
|
})();
|
||||||
}, []);
|
}, []);
|
||||||
|
|||||||
+50
-2
@@ -1,7 +1,13 @@
|
|||||||
import { ClientMethod, ServerMethod } from "./protocol";
|
import { ClientMethod, ServerMethod } from "./protocol";
|
||||||
|
import { base58 } from "@scure/base";
|
||||||
|
import * as ed from "@noble/ed25519";
|
||||||
|
import { sha512 } from "@noble/hashes/sha2.js";
|
||||||
|
|
||||||
|
ed.hashes.sha512 = sha512;
|
||||||
|
|
||||||
export class EnclaveWebSocket {
|
export class EnclaveWebSocket {
|
||||||
public websocket: WebSocket;
|
public websocket: WebSocket;
|
||||||
|
public hostname: string;
|
||||||
onOpenQueue: Array<() => void>;
|
onOpenQueue: Array<() => void>;
|
||||||
|
|
||||||
public clientPublicKey: Uint8Array;
|
public clientPublicKey: Uint8Array;
|
||||||
@@ -9,17 +15,59 @@ export class EnclaveWebSocket {
|
|||||||
|
|
||||||
public serverPublicKey?: Uint8Array;
|
public serverPublicKey?: Uint8Array;
|
||||||
|
|
||||||
public constructor(url: string | URL) {
|
public constructor(hostname: string) {
|
||||||
this.clientPublicKey = new Uint8Array();
|
this.clientPublicKey = new Uint8Array();
|
||||||
this.clientSecretKey = new Uint8Array();
|
this.clientSecretKey = new Uint8Array();
|
||||||
this.onOpenQueue = new Array();
|
this.onOpenQueue = new Array();
|
||||||
|
|
||||||
this.websocket = new WebSocket(url);
|
this.hostname = hostname;
|
||||||
|
this.websocket = new WebSocket("ws://" + hostname);
|
||||||
this.websocket.onopen = () => {
|
this.websocket.onopen = () => {
|
||||||
this.onOpenQueue.forEach((fun) => fun());
|
this.onOpenQueue.forEach((fun) => fun());
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async init() {
|
||||||
|
const publicKeyString = base58.encode(this.clientPublicKey);
|
||||||
|
|
||||||
|
const timestamp = Date.now();
|
||||||
|
|
||||||
|
const msg = new TextEncoder().encode(`${timestamp}@${this.hostname}`);
|
||||||
|
|
||||||
|
this.send({
|
||||||
|
method: "Initialize",
|
||||||
|
public_key: publicKeyString,
|
||||||
|
signature: base58.encode(ed.sign(msg, this.clientSecretKey)),
|
||||||
|
|
||||||
|
timestamp,
|
||||||
|
hostname: this.hostname,
|
||||||
|
});
|
||||||
|
|
||||||
|
const initialized = await this.read();
|
||||||
|
|
||||||
|
if (initialized.method !== "Initialized") {
|
||||||
|
this.websocket.close();
|
||||||
|
throw Error("Invalid method from server, closing. ");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (initialized.hostname !== this.hostname) {
|
||||||
|
this.websocket.close();
|
||||||
|
throw Error("Server is trying to be a middle man");
|
||||||
|
}
|
||||||
|
|
||||||
|
const sigMsg = new TextEncoder().encode(
|
||||||
|
`${initialized.timestamp}@${this.hostname}@${publicKeyString}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
this.serverPublicKey = base58.decode(initialized.public_key);
|
||||||
|
const signature = base58.decode(initialized.signature);
|
||||||
|
|
||||||
|
if (!ed.verify(signature, sigMsg, this.serverPublicKey)) {
|
||||||
|
this.websocket.close();
|
||||||
|
throw Error("Invalid signature");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async send(method: ServerMethod) {
|
public async send(method: ServerMethod) {
|
||||||
if (this.websocket.readyState !== WebSocket.OPEN) {
|
if (this.websocket.readyState !== WebSocket.OPEN) {
|
||||||
return new Promise<void>((ok) => {
|
return new Promise<void>((ok) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user