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
This commit is contained in:
1 parent
e69372c6db
commit
07c9967d02
26 files changed
+6399
-8
No files matched your search
@@ -0,0 +1,129 @@
|
||||
# ADR 0002 SHA-512 remediation: public mechanism composition
|
||||
|
||||
- Status: proposed; independent security review required.
|
||||
- Task: S00-019, remediation of S00-003.
|
||||
- Date: 2026-10-15.
|
||||
- Owner: auto-crypto-c68801170fa4 (crypto).
|
||||
- Reviewer: pending, security role.
|
||||
- Requirements: ACC-004, NET-003, NET-004.
|
||||
|
||||
Input: original SHA-512 blocker, accepted scope/stack/SASL/parser decisions,
|
||||
exact pinned Stanza browser source/public declarations and primary vectors.
|
||||
Output is one isolated runnable experiment in
|
||||
experiments/0002-xmpp-library/sha512-validation. No production library selection,
|
||||
parent WSS work, shared contract, stack change or original spec change.
|
||||
|
||||
## Defect and options
|
||||
|
||||
The built Stanza 12.22.1 browser backend reproduces the RFC 4231 case 1 failure
|
||||
for createHmac('sha-512'). Source chooses 128-byte blocks only for sha512;
|
||||
SCRAM's normal wire name derives sha-512. The browser digest implementation
|
||||
already accepts both spellings; HMAC does not normalize the hyphen. Direct
|
||||
public SCRAM('SCRAM-SHA-512') produces the wrong full client proof as well.
|
||||
|
||||
1. Compose the existing exported SCRAM through its public constructor with the
|
||||
working algorithm alias, expose the correct independent wire name, and
|
||||
register the wrapper through public Factory APIs. Proposed for this exact
|
||||
version, with complete browser-backend vectors guarding the alias behavior.
|
||||
2. Replace crypto or the complete mechanism with another library. Not needed
|
||||
for this outcome: introduces new runtime crypto/dependency/API assumptions.
|
||||
Scramp is used only as an independent test oracle, not a browser candidate.
|
||||
3. Patch private algorithm/vendor HMAC, mutate vendor prototypes, rewrite imports
|
||||
to a replacement crypto backend, rename the wire mechanism or downgrade.
|
||||
Rejected; no such patch/workaround is used.
|
||||
|
||||
## Proposed integration
|
||||
|
||||
Sha512Mechanism implements the shipped public Mechanism interface and delegates
|
||||
all crypto to a new public SCRAM('SCRAM-SHA512'). Constructor typing accepts a
|
||||
string; exact shipped source derives sha512, supported by createHash/Hmac. The
|
||||
wrapper exposes SCRAM-SHA-512 on the wire and never accesses/changes a Stanza
|
||||
private field. The delegate retains its internal alias name throughout. This
|
||||
uses documented public constructor/method signatures and version-inspected alias
|
||||
behavior, not an upstream promise of a named SCRAM-SHA512 wire mechanism.
|
||||
Future upgrades must revalidate this composition; an incompatible API is a new
|
||||
blocker, not permission for a private patch.
|
||||
|
||||
Public Factory.disable/register replaces SHA-512 before negotiation; fresh
|
||||
Client.use installs the isolated S00-017 guard copy. Guard is narrowed to SHA-512
|
||||
and its 88-character verifier, while preserving strict validation, ordering,
|
||||
mutual authentication, cancellation and no-success-on-error behavior. Delegate
|
||||
processSuccess/finalize must confirm both flags before auth event/flags/restart.
|
||||
Library-derived keys remain attempt-local, getCacheableCredentials returns null;
|
||||
no storage/cache update path is added. Crypto primitives, SCRAM composition,
|
||||
SASLprep and verifier remain entirely existing library code.
|
||||
|
||||
Only non-PLUS SHA-512 is permitted by this fixture profile. PLUS-only/plaintext/
|
||||
unsupported offers fail; compatible mixed offers select SHA-512. tlsUnique input
|
||||
fails. GS2 n,, and c=biws reflect no channel binding. Full NET-003 fallback policy
|
||||
and real WSS ACC-004 stay with S00-003; this experiment makes no complete product
|
||||
requirement or library-selection claim.
|
||||
|
||||
## Pins, public API and sources
|
||||
|
||||
Inspected primary sources on 2026-10-15:
|
||||
|
||||
- [RFC 4231 sections 4.2–4.8](https://www.rfc-editor.org/rfc/rfc4231.html#section-4.2)
|
||||
supplies seven fixed HMAC-SHA-512 cases, including 131-byte keys and truncation.
|
||||
- [RFC 6234 test driver](https://www.rfc-editor.org/rfc/rfc6234.html#section-8.5)
|
||||
supplies SHA-512 abc digest. No primitive code is copied from the RFC.
|
||||
- [Stanza source](https://github.com/legastero/stanza/blob/master/src/lib/sasl/index.ts)
|
||||
supplies public API context; exact shipped 12.22.1 lib/sasl/index.d.ts/.js,
|
||||
Client.d.ts/.js, plugins/features.d.ts/.js and platform/browser/crypto files
|
||||
are authoritative version-specific evidence. Factory accepts a constructor;
|
||||
wrapper calls only declared public methods. Stanza license is MIT with bundled
|
||||
browser crypto ancestry notices preserved.
|
||||
- [events upstream](https://github.com/browserify/events) documents browser
|
||||
EventEmitter API, ES5 support, MIT license and limited maintainer resources.
|
||||
events 3.3.0 supplies the explicit polyfill required by Stanza's browser graph.
|
||||
- [Vite build](https://vite.dev/guide/build.html) supports library output/browser
|
||||
targets; accepted Vite 8.3.4 is reused, not a new stack selection.
|
||||
- [Scramp 1.4.6 API](https://pypi.org/project/scramp/1.4.6/) documents SHA-512
|
||||
and public client/server methods. Test oracle pins Scramp 1.4.6 (MIT-0) and
|
||||
asn1crypto 1.5.1 (MIT), exact wheel SHA256 hashes, Python >=3.8. Version selected
|
||||
for available Python 3.9 host compatibility; not a latest-version/audit claim.
|
||||
|
||||
Direct npm pins: stanza 12.22.1, events 3.3.0 (MIT), Vite 8.3.4 (MIT, build only).
|
||||
49 exact locked entries, 25 installed on this macOS ARM64 host. All lock entries
|
||||
have HTTPS registry URL, SHA512 integrity and license inventory; installed
|
||||
notices include Stanza NOTICE browser code lineage and build third-party texts.
|
||||
Native rolldown binding omits a license file; owning rolldown MIT/third-party
|
||||
licenses preserved. Optional platform entries are inventory-only. Build graph
|
||||
includes MIT/ISC/BSD/Apache/MPL packages; no modified covered vendor source.
|
||||
Neither pins nor these checks certify advisory/provenance/security clearance.
|
||||
|
||||
Runtime remains accepted Node 24.21.0/npm 11.19.0. Normal HTTPS, strict engines,
|
||||
disabled install scripts; no global configuration change. Browser bundle uses
|
||||
package browser mapping and explicit events alias, with no Node crypto/backend
|
||||
or external builtin. Build graph assertions and executed artifact supply backend
|
||||
evidence; Node crypto appears only as the separate primitive oracle in tests.
|
||||
|
||||
## Actual validation and limits
|
||||
|
||||
Fresh-cache npm ci, browser library build and 87 tests passed. All seven fixed
|
||||
RFC HMAC cases match sha512/SHA512; SHA digest aliases match abc, varied HMAC keys
|
||||
0..256 bytes match independent Node crypto. Stock hyphenated HMAC/full SCRAM
|
||||
failures reproduce. Three full fixed SHA-512 exchanges match independent Scramp
|
||||
client/server output (ordinary/131-byte/Unicode passwords). Scramp regeneration
|
||||
verifies client proof and server-final independently before comparing fixtures.
|
||||
|
||||
Actual browser-built Client, XML registry, feature dispatcher and mechanism run
|
||||
positive and missing/forged/premature/malformed/duplicate/racing-final checks.
|
||||
Fixture send/transport effects are captured explicitly; crypto is never stubbed.
|
||||
Fail never authenticates/restarts; reset/error/replay cannot revive it. Server
|
||||
silence after proof remains unauthenticated until external reset. All 340 Stanza
|
||||
files byte-match original pinned candidate. Detailed commands, checks and hashes
|
||||
are in README and executor evidence; independent review remains mandatory.
|
||||
|
||||
Bundle execution host is Node, using browser backend and host native web APIs.
|
||||
Actual Chrome/Firefox/Safari runtime, WSS/TLS, live independent server/client,
|
||||
parent parser integration, workers/performance and production readiness are not
|
||||
claimed. Targets Chrome/Edge 111, Firefox 114, Safari 16.4 are accepted build
|
||||
floors, not a certified product matrix; native crypto RNG/fetch/WebSocket needed.
|
||||
Synchronous SCRAM derivation can block UI; no constant-time verifier guarantee
|
||||
(Stanza compares strings), timeout or exhaustive SASLprep claim. Only success
|
||||
additional-data final, extension-free syntax, 4096 decoded bytes/100000 iteration
|
||||
fixture limits; separate final challenge conservatively rejects. Accepted
|
||||
S00-017/S00-018 source is untouched. Independent security reviewer must assess
|
||||
public alias composition and all limits, repeat commands and record acceptance
|
||||
before the coordinator resumes the parent in another fresh process.
|
||||
Reference in new issue
Block a user