passkey_types/webauthn/
assertion.rs

1//! Types used for public key authentication
2
3use serde::{Deserialize, Serialize};
4#[cfg(feature = "typeshare")]
5use typeshare::typeshare;
6
7use crate::{
8    Bytes,
9    utils::serde::{ignore_unknown, ignore_unknown_opt_vec, maybe_stringified_num},
10    webauthn::{
11        AttestationConveyancePreference, AttestationStatementFormatIdentifiers,
12        AuthenticationExtensionsClientInputs, PublicKeyCredential, PublicKeyCredentialDescriptor,
13        PublicKeyCredentialHints, UserVerificationRequirement,
14    },
15};
16
17#[cfg(doc)]
18use crate::{
19    ctap2::{AttestedCredentialData, AuthenticatorData},
20    webauthn::{
21        AuthenticatorAttestationResponse, CollectedClientData, PublicKeyCredentialUserEntity,
22    },
23};
24
25/// The response to the successful authentication of a [`PublicKeyCredential`]
26#[cfg_attr(feature = "typeshare", typeshare(swift = "Equatable, Hashable"))]
27pub type AuthenticatedPublicKeyCredential = PublicKeyCredential<AuthenticatorAssertionResponse>;
28
29/// This type supplies `get()` requests with the data it needs to generate an assertion.
30/// Its `challenge` member MUST be present, while its other members are OPTIONAL.
31///
32/// <https://w3c.github.io/webauthn/#dictdef-publickeycredentialrequestoptions>
33#[derive(Debug, Serialize, Deserialize)]
34#[serde(rename_all = "camelCase")]
35#[cfg_attr(feature = "typeshare", typeshare)]
36pub struct PublicKeyCredentialRequestOptions {
37    /// This member specifies a challenge that the authenticator signs, along with other data, when
38    /// producing an authentication assertion. See the [Cryptographic Challenges] security consideration.
39    ///
40    /// [Cryptographic Challenges]: https://w3c.github.io/webauthn/#sctn-cryptographic-challenges
41    pub challenge: Bytes,
42
43    /// This OPTIONAL member specifies a time, in milliseconds, that the Relying Party is willing to
44    /// wait for the call to complete. The value is treated as a hint, and MAY be overridden by the
45    /// client.
46    #[serde(
47        default,
48        skip_serializing_if = "Option::is_none",
49        deserialize_with = "maybe_stringified_num"
50    )]
51    pub timeout: Option<u32>,
52
53    /// This OPTIONAL member specifies the [RP ID] claimed by the [Relying Party]. The client MUST
54    /// verify that the Relying Party's origin matches the scope of this RP ID. The authenticator
55    /// MUST verify that this RP ID exactly equals the rpId of the credential to be used for the
56    /// authentication ceremony.
57    ///
58    /// If omitted, its value will be the requesting origin's [effective domain].
59    ///
60    /// [RP ID]: https://w3c.github.io/webauthn/#rp-id
61    /// [Relying Party]: https://w3c.github.io/webauthn/#relying-party
62    /// [effective domain]: https://html.spec.whatwg.org/multipage/browsers.html#concept-origin-effective-domain
63    #[serde(default, skip_serializing_if = "Option::is_none")]
64    pub rp_id: Option<String>,
65
66    /// This OPTIONAL member is used by the client to find authenticators eligible for this
67    /// authentication ceremony. It can be used in two ways:
68    ///
69    /// * If the user account to authenticate is already identified (e.g. if the user has entered a
70    ///   username), then the Relying Party SHOULD use this member to list credential descriptors for
71    ///   credential records in the user account. This SHOULD usually include all credential records
72    ///   in the user account.
73    ///
74    ///   The items SHOULD specify [`PublicKeyCredentialDescriptor::transports`] whenever possible.
75    ///   This helps the client optimize the user experience for any given situation. Also note that
76    ///   the Relying Party does not need to filter the list when requesting user verification — the
77    ///   client will automatically ignore non-eligible credentials if [`Self::user_verification`]
78    ///   is set to required.
79    ///
80    ///   See also the [Privacy leak via credential IDs][privacy] privacy consideration.
81    ///
82    /// * If the user account to authenticate is not already identified, then the Relying Party MAY
83    ///   leave this member empty or unspecified. In this case, only discoverable credentials will be
84    ///   utilized in this authentication ceremony, and the user account MAY be identified by the
85    ///   of the resulting [`AuthenticatorAssertionResponse::user_handle`]. If the available
86    ///   authenticators contain more than one discoverable credential scoped to the Relying Party,
87    ///   the credentials are displayed by the client platform or authenticator for the user to select
88    ///   from.
89    ///
90    /// If not empty, the client MUST return an error if none of the listed credentials can be used.
91    ///
92    /// The list is ordered in descending order of preference: the first item in the list is the
93    /// most preferred credential, and the last is the least preferred.
94    ///
95    /// [privacy]: https://w3c.github.io/webauthn/#sctn-credential-id-privacy-leak
96    #[serde(
97        default,
98        skip_serializing_if = "Option::is_none",
99        deserialize_with = "ignore_unknown_opt_vec",
100        // On older versions of google play services, hybrid requests were not being transcribed
101        // correctly from the CTAP format to the webauthn format as is required by the credential
102        // manager API. This alias is present to mitigate the issue on devices that may not have
103        // received the update. It will be removed at a later date so do not rely on it.
104        alias = "allowList"
105    )]
106    pub allow_credentials: Option<Vec<PublicKeyCredentialDescriptor>>,
107
108    /// This OPTIONAL member specifies the Relying Party's requirements regarding user verification
109    /// for the `get()` operation. The value SHOULD be a member of [`UserVerificationRequirement`]
110    /// but client platforms MUST ignore unknown values, treating an unknown value as if the member
111    /// does not exist and using its default value. Eligible authenticators are filtered to only
112    /// those capable of satisfying this requirement.
113    ///
114    /// See [`UserVerificationRequirement`] for the description of this field's values and semantics.
115    #[serde(default, deserialize_with = "ignore_unknown")]
116    pub user_verification: UserVerificationRequirement,
117
118    /// This OPTIONAL member contains zero or more elements from [`PublicKeyCredentialHints`]` to
119    /// guide the user agent in interacting with the user.
120    ///
121    /// This field ignores unknown hint values at deserialization.
122    #[serde(
123        default,
124        skip_serializing_if = "Option::is_none",
125        deserialize_with = "ignore_unknown_opt_vec"
126    )]
127    pub hints: Option<Vec<PublicKeyCredentialHints>>,
128
129    /// The Relying Party MAY use this OPTIONAL member to specify a preference regarding attestation
130    /// conveyance. Its value SHOULD be a member of [`AttestationConveyancePreference`]. Client platforms
131    /// MUST ignore unknown values, treating an unknown value as if the member does not exist,
132    /// therefore acting as the default value.
133    ///
134    /// The default value is [`AttestationConveyancePreference::None`]
135    #[serde(default, deserialize_with = "ignore_unknown")]
136    pub attestation: AttestationConveyancePreference,
137
138    /// The Relying Party MAY use this OPTIONAL member to specify a preference regarding the attestation
139    /// statement format used by the authenticator. Values SHOULD be taken from the IANA "WebAuthn
140    /// Attestation Statement Format Identifiers" registry [IANA-WebAuthn-Registries] established by
141    /// [RFC8809]. Values are ordered from most preferable to least preferable. This parameter is
142    /// advisory and the authenticator MAY use an attestation statement not enumerated in this parameter.
143    ///
144    /// The default value is the empty list, which indicates no preference.
145    ///
146    /// [IANA-WebAuthn-Registries]: https://www.iana.org/assignments/webauthn/webauthn.xhtml#webauthn-attestation-statement-format-ids
147    /// [RFC8809]: https://www.rfc-editor.org/rfc/rfc8809
148    #[serde(
149        default,
150        skip_serializing_if = "Option::is_none",
151        deserialize_with = "ignore_unknown_opt_vec"
152    )]
153    pub attestation_formats: Option<Vec<AttestationStatementFormatIdentifiers>>,
154
155    /// The Relying Party MAY use this OPTIONAL member to provide client extension inputs requesting
156    /// additional processing by the client and authenticator.
157    ///
158    /// See [`AuthenticationExtensionsClientInputs`] for the list of currenly supported [WebAuthn Extensions].
159    ///
160    /// [WebAuthn Extensions]: https://w3c.github.io/webauthn/#webauthn-extensions
161    #[serde(
162        default,
163        skip_serializing_if = "Option::is_none",
164        deserialize_with = "ignore_unknown"
165    )]
166    pub extensions: Option<AuthenticationExtensionsClientInputs>,
167}
168
169/// This is the expected input to [`navigator.credentials.get`] when wanting to authenticate using a
170/// webauthn credential.
171///
172/// <https://w3c.github.io/webauthn/#sctn-credentialrequestoptions-extension>
173///
174/// [`navigator.credentials.get`]: https://developer.mozilla.org/en-US/docs/Web/API/CredentialsContainer/get
175#[derive(Debug, Serialize, Deserialize)]
176#[serde(rename_all = "camelCase")]
177#[cfg_attr(feature = "typeshare", typeshare)]
178pub struct CredentialRequestOptions {
179    /// The key defining that this is a request for a webauthn credential.
180    pub public_key: PublicKeyCredentialRequestOptions,
181}
182
183/// This type represents an authenticator's response to a client’s request for generation of a new
184/// authentication assertion given the Relying Party's [challenge](PublicKeyCredentialRequestOptions)
185/// and OPTIONAL list of credentials it is aware of. This response contains a cryptographic signature
186/// proving possession of the credential private key, and optionally evidence of user consent to a
187/// specific transaction.
188///
189/// <https://w3c.github.io/webauthn/#iface-authenticatorassertionresponse>
190#[derive(Debug, Deserialize, Serialize)]
191#[serde(rename_all = "camelCase")]
192#[cfg_attr(feature = "typeshare", typeshare(swift = "Equatable, Hashable"))]
193pub struct AuthenticatorAssertionResponse {
194    /// This attribute contains the JSON serialization of [`CollectedClientData`] passed to the
195    /// authenticator by the client in order to generate this credential. The exact JSON serialization
196    /// MUST be preserved, as the hash of the serialized client data has been computed over it.
197    #[serde(rename = "clientDataJSON")]
198    pub client_data_json: Bytes,
199
200    /// This attribute contains the authenticator data returned by the authenticator. See [`AuthenticatorData`].
201    pub authenticator_data: Bytes,
202
203    /// This attribute contains the raw signature returned from the authenticator.
204    pub signature: Bytes,
205
206    /// This attribute contains the user handle returned from the authenticator, or null if the
207    /// authenticator did not return a user handle.
208    ///
209    /// This mirrors the [`PublicKeyCredentialUserEntity::id`] field.
210    #[serde(default, skip_serializing_if = "Option::is_none")]
211    pub user_handle: Option<Bytes>,
212
213    /// This OPTIONAL attribute contains an attestation object, if the authenticator supports attestation
214    /// in assertions. The attestation object, if present, includes an attestation statement. Unlike
215    /// the [`AuthenticatorAttestationResponse::attestation_object`], it does not contain an `authData`
216    /// key because the authenticator data is provided directly above in
217    /// [`AuthenticatorAssertionResponse::authenticator_data`] structure. For more details on attestation,
218    /// see [Attestation in assertions][1].
219    ///
220    /// [1]: https://w3c.github.io/webauthn/#sctn-attestation-in-assertions
221    #[serde(default, skip_serializing_if = "Option::is_none")]
222    pub attestation_object: Option<Bytes>,
223}