Changes: Add an isolated Stanza 12.22.1 SASL feature replacement using existing SCRAM crypto, exact dependency lock and MIT notices, 44 integrated fixture checks, proposed ADR and review handoff. Leave production adapters and the original library experiment unchanged. Validation: Fresh-cache npm ci and npm test passed on Node 24.21.0/npm 11.19.0; 44 tests cover RFC SHA-1/SHA-256 proofs and verified finals, stock defect reproduction, invalid/premature finals and async cleanup. make check passed 72 tooling tests. Pins/licenses/notices, unchanged vendor source and whitespace verified. Browser/WSS/server interoperability and constant-time assurance remain unverified; independent security review is pending. Task: S00-017 Agent: auto-protocol-599343cd9e3f Role: protocol Action: claim Status: review Task title: Establish fail-closed SCRAM server-final validation
77 lines
4.4 KiB
Markdown
77 lines
4.4 KiB
Markdown
# SCRAM server-final validation experiment
|
|
|
|
S00-017 fixture-only remediation of S00-003. No network connection or production
|
|
adapter. Public RFC example credentials are used only in memory. Requires the
|
|
accepted Node 24.21.0 / npm 11.19.0 runtime; installs enforce exact engines and TLS.
|
|
|
|
From the project root, use the isolated runtime already verified by S00-002:
|
|
|
|
```sh
|
|
export PATH=/private/tmp/luma-stack-runtime/node-v24.21.0-darwin-arm64/bin:$PATH
|
|
node --version
|
|
npm --version
|
|
npm ci --prefix experiments/0002-xmpp-library/sasl-validation --ignore-scripts --no-audit --no-fund --cache /private/tmp/luma-sasl-review-cache --fetch-retries=0 --fetch-timeout=15000
|
|
npm test --prefix experiments/0002-xmpp-library/sasl-validation
|
|
```
|
|
|
|
On another host, obtain the official exact Node runtime with verified HTTPS and
|
|
checksum; do not change system configuration or disable certificates. Use a fresh
|
|
cache directory for an independent clean-install check. The original parent
|
|
experiment manifest remains incomplete and is not used by these commands.
|
|
|
|
The 44 tests use Stanza's actual Client, XML parse/registry, named SASL feature
|
|
handler, feature negotiation dispatcher and SCRAM implementation. Outgoing sends,
|
|
restart and disconnect are captured fixture effects, not server evidence. Tests
|
|
first reproduce stock 12.22.1 accepting missing/forged premature success, then
|
|
verify rejection with the replacement. RFC 5802 §5 / RFC 7677 §3 client-first,
|
|
client-proof and verified server-final are checked byte-for-byte for SHA-1/256.
|
|
No real credentials or key material are printed. A passing stock reproduction
|
|
means the defect was observed, not safe authentication.
|
|
|
|
`validated-sasl.mjs` installs through the public plugin and feature APIs:
|
|
|
|
```js
|
|
// Illustrative integration for a fresh Client, BEFORE any connect/features.
|
|
client.use(validatedSasl);
|
|
```
|
|
|
|
The plugin calls `registerFeature('sasl', 100, handler)`. Stanza's feature registry
|
|
uses one handler per name, so this replaces the stock callback. Registration also
|
|
adds another order entry; the real dispatcher exits on restart/disconnect, and
|
|
our integrated tests verify only one negotiation/completion, including after
|
|
reset. Do not install after authentication has started or alongside another SASL
|
|
replacement. The stock handler must never have an active event listener.
|
|
|
|
State is bounded to initial credentials/send, server-first, proof send,
|
|
server-final and closed. Success is allowed only after completed proof send,
|
|
strict final syntax, `processSuccess` and `finalize` reporting both authenticated
|
|
and mutuallyAuthenticated. Invalid input disconnects once, removes listeners
|
|
and never requests authenticated restart. Reset closes the old attempt before
|
|
awaited work resumes. Crypto remains entirely in the installed library, backed
|
|
by Node crypto in this run; no hash, HMAC, KDF or proof implementation is authored.
|
|
No credential cache/update is persisted by the replacement.
|
|
|
|
This is a deliberately limited non-PLUS SHA-256/SHA-1 experiment. It rejects
|
|
other mechanisms, supplied TLS binding bytes, extensions, extra challenges and
|
|
server-final delivered separately as a challenge. It accepts only server-final
|
|
additional-data on success. It checks nonce extension and bounds decoded data
|
|
at 4096 bytes and iterations at 100000; these are experiment limits, not shared
|
|
contracts/product policy. Racing success before a send promise resolves is
|
|
rejected conservatively. A final timeout/lifecycle policy belongs to the original
|
|
integration; this experiment does not claim one.
|
|
|
|
Exact dependency graph and preserved licenses: LICENSE_INVENTORY.md and
|
|
THIRD_PARTY_NOTICES.md. All eight locked packages are MIT; lock entries retain
|
|
HTTPS registry URLs and SHA512 integrity. Node/npm notices stay with their runtime.
|
|
|
|
Security review must inspect the state transitions and actual library calls,
|
|
repeat clean install/tests, check the diff, licenses and executor evidence, then
|
|
approve/reject through the task workflow. No browser build/execution, live WSS,
|
|
independent server, parser resource-limit certification, TLS channel binding,
|
|
constant-time verification audit, advisory/provenance audit, production SASL
|
|
policy or release readiness is claimed. Stanza's verifier uses ordinary string
|
|
equality; these tests prove rejection correctness, not a timing guarantee.
|
|
Browser Stanza uses its bundled synchronous hash/HMAC code and browser RNG/WS;
|
|
that backend is not exercised here. S00-003 retains its library selection,
|
|
browser/WSS/parser/extension experiment and stronger-mechanism policy work.
|