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