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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
//! Authenticator interface — the Authorizer-side tamper-resistant module
//! and its custodian-side verifier.
//!
//! ## What this trait models, and what it does NOT
//!
//! Models each Authorizer-side credential `c` as a module `Aut_c` with
//! non-extractable internal keys producing
//! - one signature `σ ← Sig_{sk_c}(μ)` per user-verified invocation,
//! - and one or more PRF outputs `y_i ← PRF_c(η_i)`.
//!
//! Two of those three artefacts are produced **inside `Aut_c`** at the Authorizer's
//! device:
//!
//! - `sk_c` and the PRF key never leave the module.
//! - `y_c` and the derived wrapping key `W_c` exist transiently in the Authorizer's
//! trusted client and reach `T` only as the wrapping-key field of a grant.
//!
//! The custodian `T` — which is what `sudp` mostly implements — therefore only
//! needs to do **one** thing in cryptographic terms: verify `σ` over `β` under
//! the credential's public key, plus the structural checks the WebAuthn (or
//! analogous) profile demands. That is exactly what this trait exposes.
//!
//! ### Where does PRF / wrapping-key derivation live, then?
//!
//! It lives at `A` (the Authorizer's client). The client does the PRF evaluation
//! inside the authenticator, derives `W_c` via HKDF in JavaScript / native
//! code, and sends `W_c` to `T` over the confidential leg as part of the
//! [`Grant`](crate::Grant). The crate provides helpers for the symmetric KDF
//! shape (so a Rust client embedding `sudp` can derive `W_c` identically) but
//! it never assumes the custodian holds raw PRF output — the PRF stays
//! authenticator-bound by design.
//!
//! ### Enrollment vs. assertion
//!
//! WebAuthn distinguishes `webauthn.create` (enrollment, releases
//! `(cid_c, pk_c)`) from `webauthn.get` (assertion, releases `σ` and the PRF
//! output). The protocol Phase I.1 is enrollment; Phases II.2 / II.3 are
//! assertion. This trait covers both:
//!
//! - [`Authenticator::verify_enrollment`] consumes an enrollment artefact and
//! returns the canonical credential record `(cid, pk)` to be stored in `T`'s
//! registry.
//! - [`Authenticator::verify_assertion`] verifies a Phase II.2 assertion
//! against the credential's stored `pk_c` and the channel binding `β`.
//!
//! Custom authenticators (HSM-backed, OS-credential-mediator, mock) implement
//! both. The WebAuthn realisation lives in [`crate::passkey::webauthn`].
use ;
use crateResult;
/// `Aut_c`: Authorizer-side tamper-resistant module + its custodian-side verifier.
///
/// All types are associated so that an authenticator backend chooses its own
/// wire formats. Wire-format choices that vary between deployments
/// (e.g. base64 vs. CBOR) belong in the backend, not in the protocol core.
/// Result of [`Authenticator::verify_enrollment`].
/// Convenience marker for `Authenticator::Context`. Wraps the typical WebAuthn
/// triple `(rp_id, origin, require_uv)` so deployments using a custom backend
/// have a ready type if they need it.