Files
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

40 lines
1.7 KiB
Python

"""Independent existing SCRAM client/server; synthetic public fixture data only."""
import base64
import json
import sys
from importlib.metadata import version
from pathlib import Path
from scramp import ScramClient, ScramMechanism
assert version("scramp") == "1.4.6"
assert version("asn1crypto") == "1.5.1"
path = Path(__file__).parent / "test" / "scramp-vectors.json"
nonce = "rOprNGfwEbeRWgbNEkqO"
server_nonce = "%hvYDpWUa2RaTCAfuxFIlj)hNlF$k0"
salt = base64.b64decode("W22ZaJ0SNY7soEsUEjb6gQ==")
results = []
for password in ["pencil", "A" * 131, "p\u00e9ncil"]:
mechanism = ScramMechanism("SCRAM-SHA-512")
auth = mechanism.make_auth_info(password, iteration_count=4096, salt=salt)
def auth_fn(username):
assert username == "user"
return auth
server = mechanism.make_server(auth_fn, s_nonce=server_nonce)
client = ScramClient(["SCRAM-SHA-512"], "user", password, c_nonce=nonce)
initial = client.get_client_first()
server.set_client_first(initial)
first = server.get_server_first()
client.set_server_first(first)
proof = client.get_client_final()
server.set_client_final(proof) # Independent server verifies proof.
final = server.get_server_final()
client.set_server_final(final) # Independent client verifies server.
results.append(dict(mechanism="SCRAM-SHA-512", username="user", password=password,
nonce=nonce, initial=initial, first=first, proof=proof, final=final))
if sys.argv[1:] == ["--write"]:
path.write_text(json.dumps(results, indent=2) + "\n")
else:
assert not sys.argv[1:]
assert json.loads(path.read_text()) == results
print("scramp 1.4.6: three fixed SHA-512 client/server exchanges verified")