This commit is contained in:
2026-08-17 06:33:21 +02:00
parent 1c62f1de1c
commit 2a8e3f41d7
2 changed files with 52 additions and 50 deletions
+2 -48
View File
@@ -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
View File
@@ -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) => {