summaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/src/meshbay_hub/static/crypto.js
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub/static/crypto.js')
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/crypto.js38
1 files changed, 37 insertions, 1 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/crypto.js b/packages/meshbay-hub/src/meshbay_hub/static/crypto.js
index 5ebf624..2346fa2 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/crypto.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/crypto.js
@@ -230,6 +230,42 @@ function b64encode(bytes) {
return btoa(String.fromCharCode(...bytes));
}
+// ── Admin operation transcript ───────────────────────────────────────────────
+// Mirrors meshbay_common/adminop.py::admin_transcript(). Both sides build these
+// bytes independently; they are never taken off the wire.
+//
+// Finding H5: the client used to sign 32 raw random bytes chosen by the node — a
+// blind signing oracle. It now reconstructs a domain-separated, length-prefixed
+// transcript naming the operation, subject, node and group, so the UI can show the
+// user what they are authorizing and a signature cannot be reused elsewhere.
+
+const ADMIN_TRANSCRIPT_PREFIX = new TextEncoder().encode('meshbay:admin:v1');
+
+function adminTranscript(op, nodePkB64, groupId, subject, nonceB64, ts) {
+ const enc = new TextEncoder();
+ const fields = [
+ enc.encode(op),
+ enc.encode(nodePkB64),
+ enc.encode(groupId),
+ enc.encode(subject),
+ b64decode(nonceB64),
+ enc.encode(String(ts)),
+ ];
+ let total = ADMIN_TRANSCRIPT_PREFIX.length;
+ for (const f of fields) total += 4 + f.length;
+
+ const out = new Uint8Array(total);
+ out.set(ADMIN_TRANSCRIPT_PREFIX, 0);
+ let off = ADMIN_TRANSCRIPT_PREFIX.length;
+ for (const f of fields) {
+ new DataView(out.buffer).setUint32(off, f.length, false);
+ off += 4;
+ out.set(f, off);
+ off += f.length;
+ }
+ return out;
+}
+
// ── GEK proof (HMAC-SHA256 for handshake challenge) ─────────────────────────
async function hmacGEK(gekRaw, nonceB64, offerFp, answerFp) {
@@ -249,5 +285,5 @@ async function hmacGEK(gekRaw, nonceB64, offerFp, answerFp) {
window.MeshBayCrypto = {
importGEK, deriveChunkKey, decryptChunk, decryptChunkBin, decryptFile,
generateGEK, wrapGEK, unwrapGEK, encryptChunk, b64encode, b64decode,
- hmacGEK,
+ hmacGEK, adminTranscript,
};