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}