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