2.5 KiB
ocra/mutual-auth
Purpose
RFC 6287 §7.1 mutual authentication helpers. Both sides compute OCRA over
the concatenation of the client and server challenges, with the order
flipped between the two directions (Qc || Qs for the server's proof,
Qs || Qc for the client's). The module exposes pure functions plus
stateful OcraMutualAuthClient / OcraMutualAuthServer wrappers so
consumers don't reinvent the concatenation order.
Features
serverProof/verifyServerProof— the server's response and the client-side check.clientProof/verifyClientProof— the client's response and the server-side check.OcraMutualAuthClient/OcraMutualAuthServer— stateful wrappers that hold the suites + key + own challenge and expose narrow methods.- Optional
extraparameter for suites that includeC(counter),T(timestamp),Snnn(session info), orPSHA{...}(password hash).
Usage: Basic Example
import { OcraMutualAuthClient, OcraMutualAuthServer } from "@suaveplan/otp/ocra";
const server = new OcraMutualAuthServer(suites, key, "Qs");
const client = new OcraMutualAuthClient(suites, key, "Qc");
const Rs = server.respond("Qc");
const Rc = client.respond("Qs", Rs);
const ok = server.verify("Qc", Rc);
Usage: Advanced Example
import { clientProof, serverProof } from "@suaveplan/otp/ocra";
// Counter-bound mutual auth for a session that needs replay protection.
const Rs = serverProof({
suites,
key,
clientChallenge: "Qc",
serverChallenge: "Qs",
extra: { counter: 7n },
});
API Reference
serverProof(input): stringverifyServerProof(input): booleanclientProof(input): string— verifies server proof first; throwsOtpError(OTP.VERIFY_FAILED)on mismatch.verifyClientProof(input): booleanOcraMutualAuthClient/OcraMutualAuthServerclasses.
Implementation Notes
The challenge concatenation order is the most error-prone part of RFC 6287
§7.1 — Rs MUST be over Qc || Qs and Rc MUST be over Qs || Qc.
Encoding the order in named functions and class methods keeps callers from
having to reread the RFC every time they wire a new flow.
The class wrappers add a small amount of state (own challenge, own suite,
own key) so consumers can keep the per-session context outside the call
graph. The extra parameter lets the same flow work with counter-bound,
timestamp-bound, password-hash-bound, or session-info-bound suites — the
mutual-auth shape is the same, only the underlying OCRA inputs differ.