passkey_types/webauthn/
common.rs

1//! Common types used in both Attestation (registration) and Assertion (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},
10};
11
12#[cfg(doc)]
13use crate::webauthn::{
14    AuthenticatorAttestationResponse, PublicKeyCredential, PublicKeyCredentialCreationOptions,
15    PublicKeyCredentialRequestOptions,
16};
17
18/// This enumeration defines the valid credential types. It is an extension point; values can be
19/// added to it in the future, as more credential types are defined. The values of this enumeration
20/// are used for versioning the Authentication Assertion and attestation structures according to the
21/// type of the authenticator.
22///
23/// <https://w3c.github.io/webauthn/#enumdef-publickeycredentialtype>
24#[derive(Debug, Default, Serialize, Deserialize, Clone, Copy, PartialEq, Eq)]
25#[serde(rename_all = "kebab-case")]
26#[cfg_attr(feature = "typeshare", typeshare(serialized_as = "String"))]
27pub enum PublicKeyCredentialType {
28    /// Currently the only type defined is a `PublicKey` meaning the public conterpart of an
29    /// asymmetric key pair.
30    PublicKey,
31    /// This is the default as it will be ignored if the value is unknown during deserialization
32    #[default]
33    Unknown,
34}
35
36/// Identifies a specific public key credential. It is used in [`PublicKeyCredentialCreationOptions::exclude_credentials`]
37/// to prevent creating duplicate credentials on the same authenticator, and in [`PublicKeyCredentialRequestOptions::allow_credentials`]
38/// to determine if and how the credential can currently be reached by the client. It mirrors some
39/// fields of the [`PublicKeyCredential`] object returned by the `create()` and `get()` operations.
40///
41/// It is recommended to ignore any credential whose type is [`PublicKeyCredentialType::Unknown`]
42///
43/// <https://w3c.github.io/webauthn/#dictdef-publickeycredentialdescriptor>
44#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
45#[cfg_attr(feature = "typeshare", typeshare)]
46pub struct PublicKeyCredentialDescriptor {
47    /// This member contains the type of the public key credential the caller is referring to. The
48    /// value SHOULD be a member of [`PublicKeyCredentialType`] but client platforms MUST ignore any
49    /// [`PublicKeyCredentialDescriptor`] with an [`PublicKeyCredentialType::Unknown`] type.
50    ///
51    /// This mirrors the [`PublicKeyCredential::ty`] field.
52    #[serde(rename = "type", deserialize_with = "ignore_unknown")]
53    pub ty: PublicKeyCredentialType,
54
55    /// This member contains the credential ID of the public key credential the caller is referring to.
56    ///
57    /// This mirrors the [`PublicKeyCredential::raw_id`] field.
58    pub id: Bytes,
59
60    /// This OPTIONAL member contains a hint as to how the client might communicate with the managing
61    /// authenticator of the [`PublicKeyCredential`] the caller is referring to. The values SHOULD be
62    /// members of [`AuthenticatorTransport`] but client platforms MUST ignore unknown values.
63    ///
64    /// This mirrors the [`AuthenticatorAttestationResponse::transports`] field of a
65    /// [`PublicKeyCredential::response`] structure created by a `create()` operation. When registering
66    /// a new credential, the Relying Party SHOULD store the value returned from
67    /// [`AuthenticatorAttestationResponse::transports`]. When creating a [`PublicKeyCredentialDescriptor`]
68    /// for that credential, the Relying Party SHOULD retrieve that stored value and set it as the
69    /// value of the transports member.
70    #[serde(
71        default,
72        skip_serializing_if = "Option::is_none",
73        deserialize_with = "ignore_unknown_opt_vec"
74    )]
75    pub transports: Option<Vec<AuthenticatorTransport>>,
76}
77
78impl PublicKeyCredentialDescriptor {
79    /// Checks whether [`Self::ty`] is not of value [`PublicKeyCredentialType::Unknown`]. This should
80    /// be used for filtering a list of [`PublicKeyCredentialDescriptor`]s that are not of a known type.
81    pub fn is_known(&self) -> bool {
82        match self.ty {
83            PublicKeyCredentialType::PublicKey => true,
84            PublicKeyCredentialType::Unknown => false,
85        }
86    }
87}
88
89/// A Relying Party may require [user verification] for some of its operations but not for others,
90/// and may use this type to express its needs.
91///
92/// <https://w3c.github.io/webauthn/#enumdef-userverificationrequirement>
93///
94/// [user verification]: https://w3c.github.io/webauthn/#user-verification
95#[derive(Debug, Default, Deserialize, Serialize, Clone, Copy, PartialEq, Eq)]
96#[serde(rename_all = "lowercase")]
97#[cfg_attr(feature = "typeshare", typeshare(serialized_as = "String"))]
98pub enum UserVerificationRequirement {
99    /// The Relying Party requires user verification for the operation and will fail the overall
100    /// ceremony if the response does not have the UV flag set. The client MUST return an error if
101    /// user verification cannot be performed.
102    Required,
103
104    /// The Relying Party prefers user verification for the operation if possible, but will not fail
105    /// the operation if the response does not have the UV flag set.
106    #[default]
107    Preferred,
108
109    /// The Relying Party does not want user verification employed during the operation
110    /// (e.g., in the interest of minimizing disruption to the user interaction flow).
111    Discouraged,
112}
113
114/// Authenticators may implement various transports for communicating with clients. This enumeration
115/// defines hints as to how clients might communicate with a particular authenticator in order to
116/// obtain an assertion for a specific credential. Note that these hints represent the Relying Party's
117/// best belief as to how an authenticator may be reached. A Relying Party will typically learn of
118/// the supported transports for a [`PublicKeyCredential`] via [`AuthenticatorAttestationResponse::transports`].
119///
120/// <https://w3c.github.io/webauthn/#enum-transport>
121#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq)]
122#[serde(rename_all = "lowercase")]
123#[cfg_attr(feature = "typeshare", typeshare(serialized_as = "String"))]
124pub enum AuthenticatorTransport {
125    /// Indicates the respective authenticator can be contacted over removable USB.
126    Usb,
127
128    /// Indicates the respective authenticator can be contacted over Near Field Communication (NFC).
129    Nfc,
130
131    /// Indicates the respective authenticator can be contacted over Bluetooth Smart (Bluetooth Low Energy / BLE).
132    Ble,
133
134    /// Indicates the respective authenticator can be contacted using a combination of (often separate)
135    /// data-transport and proximity mechanisms. This supports, for example, authentication on a
136    /// desktop computer using a smartphone.
137    #[serde(alias = "cable")]
138    Hybrid,
139
140    /// Indicates the respective authenticator is contacted using a client device-specific transport,
141    /// i.e. it is a platform authenticator. These authenticators are not removable from the client
142    /// device.
143    Internal,
144}
145
146/// This enumeration’s values describe authenticators' attachment modalities. Relying Parties use
147/// this to express a preferred authenticator attachment modality when passing a
148/// [`PublicKeyCredentialCreationOptions`] to create a credential, and clients use this to report the
149/// authenticator attachment modality used to complete a registration or authentication ceremony.
150///
151/// <https://w3c.github.io/webauthn/#enumdef-authenticatorattachment>
152#[derive(Debug, Deserialize, Serialize, Clone, Copy, PartialEq, Eq)]
153#[serde(rename_all = "kebab-case")]
154#[cfg_attr(feature = "typeshare", typeshare(serialized_as = "String"))]
155pub enum AuthenticatorAttachment {
156    /// This value indicates platform attachment which is attached using a client device-specific
157    /// transport, called **platform attachment**, and is usually not removable from the client
158    /// device. A public key credential bound to a platform authenticator is called a
159    /// **platform credential**.
160    Platform,
161
162    /// This value indicates cross-platform attachment which is attached using cross-platform transports
163    /// called **cross-platform attachment**. Authenticators of this class are removable from, and can
164    /// "roam" between, client devices. A public key credential bound to a roaming authenticator is
165    /// called a **roaming credential**.
166    CrossPlatform,
167}
168
169/// WebAuthn Relying Parties may use this enumeration to communicate hints to the user-agent about
170/// how a request may be best completed. These hints are not requirements, and do not bind the
171/// user-agent, but may guide it in providing the best experience by using contextual information
172/// that the Relying Party has about the request. Hints are provided in order of decreasing preference
173/// so, if two hints are contradictory, the first one controls. Hints may also overlap: if a more-specific
174/// hint is defined a Relying Party may still wish to send less specific ones for user-agents that may
175/// not recognise the more specific one. In this case the most specific hint should be sent before
176/// the less-specific ones.
177///
178/// Hints MAY contradict information contained in [`AuthenticatorTransport`] and [`AuthenticatorAttachment`].
179/// When this occurs, the hints take precedence. (Note that transports values are not provided when
180/// using discoverable credentials, leaving hints as the only avenue for expressing some aspects of
181/// such a request.)
182///
183/// <https://w3c.github.io/webauthn/#enum-hints>
184#[derive(Debug, Deserialize, Serialize, Clone, Copy, PartialEq, Eq)]
185#[serde(rename_all = "kebab-case")]
186#[cfg_attr(feature = "typeshare", typeshare(serialized_as = "String"))]
187#[non_exhaustive]
188pub enum PublicKeyCredentialHints {
189    /// Indicates that the Relying Party believes that users will satisfy this request with a physical
190    /// security key. For example, an enterprise Relying Party may set this hint if they have issued
191    /// security keys to their employees and will only accept those authenticators for registration
192    /// and authentication.
193    ///
194    /// For compatibility with older user agents, when this hint is used in [`PublicKeyCredentialCreationOptions`],
195    /// the authenticatorAttachment SHOULD be set to [`AuthenticatorAttachment::CrossPlatform`].
196    SecurityKey,
197
198    /// Indicates that the Relying Party believes that users will satisfy this request with a platform
199    /// authenticator attached to the client device.
200    ///
201    /// For compatibility with older user agents, when this hint is used in [`PublicKeyCredentialCreationOptions`],
202    /// the authenticatorAttachment SHOULD be set to [`AuthenticatorAttachment::Platform`].
203    ClientDevice,
204
205    /// Indicates that the Relying Party believes that users will satisfy this request with
206    /// general-purpose authenticators such as smartphones. For example, a consumer Relying Party
207    /// may believe that only a small fraction of their customers possesses dedicated security keys.
208    /// This option also implies that the local platform authenticator should not be promoted in the UI.
209    ///
210    /// For compatibility with older user agents, when this hint is used in [`PublicKeyCredentialCreationOptions`],
211    /// the authenticatorAttachment SHOULD be set to [`AuthenticatorAttachment::CrossPlatform`].
212    Hybrid,
213}