feat: harden bridge origin/CSP, cache decryption, and overhaul the web client UI

This commit is contained in:
randogoth 2026-09-26 19:04:36 +03:00
parent f637d5be57
commit 80133da100
10 changed files with 975 additions and 352 deletions

View file

@ -2,7 +2,7 @@
// The initiator is anonymous; the responder's static key arrives encrypted in
// message two, which is what server pinning checks.
import { aeadDecrypt, aeadEncrypt, concat, hkdfSha256, randomBytes, sha256, timingSafeEqual, utf8Bytes, x25519, x25519Base } from "./crypto.js";
import { aeadDecrypt, aeadEncrypt, concat, hkdfSha256, randomBytes, sha256, utf8Bytes, x25519, x25519Base } from "./crypto.js";
const PROTOCOL = "Noise_NX_25519_ChaChaPoly_SHA256"; // exactly 32 bytes, so h = name
const PROLOGUE = utf8Bytes("smolmail/1");
@ -90,10 +90,3 @@ export class NxInitiator {
return plaintext;
}
}
// §4: a pinned key must match the one the handshake revealed, or everything stops.
export function checkPin(pinned, serverStatic, host) {
if (pinned && !timingSafeEqual(pinned, serverStatic))
throw new Error(`${host} presented a different key than the one pinned`);
return pinned !== null && pinned !== undefined;
}