1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
//! M66 — id_token nonce binding (OIDC Core 1.0 §3.1.3.7 step 11).
//!
//! The RP mints a per-session nonce, sends it in the Authentication
//! Request, stores a copy bound to its session state. On id_token
//! receipt, the engine compares the payload's `nonce` claim against
//! the RP-stored copy. Mismatch / missing → reject — the canonical
//! replay-defense gate for OIDC.
//!
//! ── Why a separate engine submodule ─────────────────────────────────────
//!
//! Nonce binding is structurally similar to the access_token's M35
//! replay-defense (both check "is this token uniquely bound to this
//! session?") but the substrate is RP-managed, not server-cached. The
//! engine provides the comparison primitive; storage of the expected
//! value is `id_token::VerifyConfig::expected_nonce` (set at auth-
//! request boundary, threaded through to verify call).
//!
//! ── Reusability across profiles ─────────────────────────────────────────
//!
//! Currently only id_token consumes `check_nonce`. Future DPoP work
//! (RFC 9449) carries a server-issued nonce on the access path; this
//! function stays `pub(crate)` and profile-agnostic so it can be reused
//! without splitting between modules. Per `feedback_audit_grilled_decisions`:
//! make it reusable by default (no profile-specific assumption in the
//! signature), but don't pre-wire DPoP until that row lands.
use crate;
/// Compare the token's payload `nonce` against the RP-stored expected
/// value. Plain `==` — nonce is a public correlator with no secrecy
/// contract (see `id_token::nonce` doc-comment).
pub