Files
LumaWeb/experiments/0002-xmpp-library/sha512-validation/sha512-mechanism.mjs
T
wt 07c9967d02 S00-019: Validate browser SCRAM-SHA-512 through public mechanism composition
Changes: Add an isolated pinned mechanism wrapper using Stanza's public constructor and factory APIs, preserve the SCRAM-SHA-512 wire name and fail-closed final guard, and document the proposed ADR, browser bundle evidence, independent Scramp vectors, notices and limits. Leave parent selection, dependency experiments, specs and shared contracts unchanged.
Validation: Fresh-cache npm ci and Vite browser build pass; 87 focused tests pass, including RFC HMAC vectors, original defect reproduction, independent full SHA-512 exchanges and rejected invalid finals/order/reset paths. Hashed Scramp oracle fixture comparison passes. Dependency check verifies 49 locked entries, 25 installed pins/licenses and 340 unmodified Stanza files. make check passes 72 tooling tests. Native browsers, WSS/live server interoperability and production readiness are untested; independent security review remains pending.

Task: S00-019
Agent: auto-crypto-c68801170fa4
Role: crypto
Action: claim
Status: review

Task title: Validate browser-compatible SCRAM-SHA-512 through a public mechanism API
2026-10-15 02:48:39 +07:00

29 lines
1.1 KiB
JavaScript

import sasl from 'stanza/lib/sasl/index.js';
// Public constructor selects the existing browser backend's supported hash alias.
// The delegate name never goes on the wire. No private field is read or changed.
export class Sha512Mechanism {
name = 'SCRAM-SHA-512';
providesMutualAuthentication = true;
#delegate;
constructor(name) {
if (name !== this.name) throw new Error('Unsupported mechanism');
this.#delegate = new sasl.SCRAM('SCRAM-SHA512');
}
getExpectedCredentials() { return this.#delegate.getExpectedCredentials(); }
// Keep derived credentials attempt-local; no cache leaves this boundary.
getCacheableCredentials() { return null; }
createResponse(credentials) {
if (credentials.tlsUnique) throw new Error('Channel binding unavailable');
return this.#delegate.createResponse(credentials);
}
processChallenge(value) { this.#delegate.processChallenge(value); }
processSuccess(value) { this.#delegate.processSuccess(value); }
finalize() { return this.#delegate.finalize(); }
}
export function registerSha512(client) {
client.sasl.disable('SCRAM-SHA-512');
client.sasl.register('SCRAM-SHA-512', Sha512Mechanism, 1000);
}