passkey_types/webauthn/extensions/mod.rs
1use serde::{Deserialize, Serialize};
2use typeshare::typeshare;
3
4mod credential_properties;
5mod pseudo_random_function;
6
7pub use credential_properties::*;
8pub use pseudo_random_function::*;
9
10#[cfg(doc)]
11use crate::webauthn::PublicKeyCredential;
12
13/// This is a dictionary containing the client extension input values for zero or more
14/// [WebAuthn Extensions]. There are currently none supported.
15///
16/// <https://w3c.github.io/webauthn/#dictdef-authenticationextensionsclientinputs>
17///
18/// [WebAuthn Extensions]: https://w3c.github.io/webauthn/#webauthn-extensions
19#[derive(Debug, Default, Deserialize, Serialize)]
20#[serde(rename_all = "camelCase")]
21#[typeshare]
22pub struct AuthenticationExtensionsClientInputs {
23 /// Boolean to indicate that this extension is requested by the relying party.
24 ///
25 /// See [`CredentialPropertiesOutput`] for more information.
26 #[serde(default, skip_serializing_if = "Option::is_none")]
27 pub cred_props: Option<bool>,
28
29 /// Inputs for the pseudo-random function extensions.
30 ///
31 /// See [`AuthenticationExtensionsPrfInputs`] for more information.
32 #[serde(default, skip_serializing_if = "Option::is_none")]
33 pub prf: Option<AuthenticationExtensionsPrfInputs>,
34
35 /// Inputs for the pseudo-random function extension where the inputs are already hashed
36 /// by another client following the `sha256("WebAuthn PRF" || salt)` format.
37 ///
38 /// This is not an official extension, rather a field that occurs in some cases on Android
39 /// as well as the field that MUST be used when mapping from Apple's Authentication Services
40 /// [`ASAuthorizationPublicKeyCredentialPRFAssertionInput`].
41 ///
42 /// This field SHOULD NOT be present alongside the [`Self::prf`] field as that field will take precedence.
43 ///
44 /// [`ASAuthorizationPublicKeyCredentialPRFAssertionInput`]: https://developer.apple.com/documentation/authenticationservices/asauthorizationpublickeycredentialprfassertioninput-swift.struct
45 #[serde(default, skip_serializing_if = "Option::is_none")]
46 pub prf_already_hashed: Option<AuthenticationExtensionsPrfInputs>,
47}
48
49impl AuthenticationExtensionsClientInputs {
50 /// Validates that there is at least one extension field that is `Some`
51 /// and that they are in turn not empty. If all fields are `None`
52 /// then this returns `None` as well.
53 pub fn zip_contents(self) -> Option<Self> {
54 let Self {
55 cred_props,
56 prf,
57 prf_already_hashed,
58 } = &self;
59 let has_cred_props = cred_props.is_some();
60
61 let has_prf = prf.is_some();
62 let has_prf_already_hashed = prf_already_hashed.is_some();
63
64 (has_cred_props || has_prf || has_prf_already_hashed).then_some(self)
65 }
66}
67
68/// This is a dictionary containing the client extension output values for zero or more
69/// [WebAuthn Extensions].
70///
71/// <https://w3c.github.io/webauthn/#dictdef-authenticationextensionsclientoutputs>
72///
73/// [WebAuthn Extensions]: https://w3c.github.io/webauthn/#webauthn-extensions
74#[derive(Debug, Default, Deserialize, Serialize)]
75#[serde(rename_all = "camelCase")]
76#[typeshare(swift = "Equatable")]
77pub struct AuthenticationExtensionsClientOutputs {
78 /// Contains properties of the given [`PublicKeyCredential`] when it is included.
79 ///
80 /// See [`CredentialPropertiesOutput`] for more information
81 #[serde(default, skip_serializing_if = "Option::is_none")]
82 pub cred_props: Option<CredentialPropertiesOutput>,
83
84 /// Contains the results of evaluating the PRF.
85 ///
86 /// See [`AuthenticationExtensionsPrfOutputs`] for more information.
87 #[serde(default, skip_serializing_if = "Option::is_none")]
88 pub prf: Option<AuthenticationExtensionsPrfOutputs>,
89}