error.rs (31467B)
1 #[cfg(feature = "serde_relaxed")] 2 use super::super::SerdeJsonErr; 3 #[cfg(doc)] 4 use super::{ 5 super::super::{ 6 RegisteredCredential, 7 request::{ 8 BackupReq, CredentialMediationRequirement, UserVerificationRequirement, 9 register::{ 10 AuthenticatorAttachmentReq, AuthenticatorSelectionCriteria, 11 CredentialCreationOptions, Extension, PublicKeyCredentialCreationOptions, 12 RegistrationServerState, RegistrationVerificationOptions, 13 }, 14 }, 15 }, 16 Aaguid, Attestation, AttestationObject, AttestedCredentialData, AuthenticatorAttachment, 17 AuthenticatorAttestation, AuthenticatorData, AuthenticatorExtensionOutput, Backup, 18 ClientExtensionsOutputs, CollectedClientData, CompressedP256PubKey, CompressedP384PubKey, 19 Ed25519PubKey, Ed25519Signature, Flag, MAX_RSA_N_BITS, MIN_RSA_E, MIN_RSA_N_BITS, Metadata, 20 PackedAttestation, RsaPubKey, UncompressedP256PubKey, UncompressedP384PubKey, 21 UncompressedPubKey, 22 }; 23 use super::{ 24 super::{ 25 super::{CredentialErr, request::register::CredProtect}, 26 AuthRespErr, AuthenticatorDataErr as AuthDataErr, CeremonyErr, 27 error::{CollectedClientDataErr, CredentialIdErr}, 28 }, 29 CredentialProtectionPolicy, FourToSixtyThree, 30 }; 31 use core::{ 32 convert::Infallible, 33 error::Error, 34 fmt::{self, Display, Formatter}, 35 }; 36 /// Error returned from [`Ed25519PubKey::try_from`] when the `slice` is not 32-bytes in length. 37 #[derive(Clone, Copy, Debug, Eq, PartialEq)] 38 pub struct Ed25519PubKeyErr; 39 impl Display for Ed25519PubKeyErr { 40 #[inline] 41 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 42 f.write_str("the Ed25519 public key is not 32-bytes in length") 43 } 44 } 45 impl Error for Ed25519PubKeyErr {} 46 /// Error returned from [`UncompressedP256PubKey::try_from`]. 47 #[derive(Clone, Copy, Debug, Eq, PartialEq)] 48 pub enum UncompressedP256PubKeyErr { 49 /// Variant returned when the x-coordinate is not 32-bytes in length. 50 X, 51 /// Variant returned when the y-coordinate is not 32-bytes in length. 52 Y, 53 } 54 impl Display for UncompressedP256PubKeyErr { 55 #[inline] 56 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 57 f.write_str(match *self { 58 Self::X => "the P-256 public key x-coordinate is not 32-bytes in length", 59 Self::Y => "the P-256 public key y-coordinate is not 32-bytes in length", 60 }) 61 } 62 } 63 impl Error for UncompressedP256PubKeyErr {} 64 /// Error returned from [`CompressedP256PubKey::try_from`] when the x-coordinate 65 /// is not exactly 32 bytes in length. 66 #[derive(Clone, Copy, Debug, Eq, PartialEq)] 67 pub struct CompressedP256PubKeyErr; 68 impl Display for CompressedP256PubKeyErr { 69 #[inline] 70 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 71 f.write_str("the compressed P-256 public key x-coordinate is not 32-bytes in length") 72 } 73 } 74 impl Error for CompressedP256PubKeyErr {} 75 /// Error returned from [`UncompressedP384PubKey::try_from`]. 76 #[derive(Clone, Copy, Debug, Eq, PartialEq)] 77 pub enum UncompressedP384PubKeyErr { 78 /// Variant returned when the x-coordinate is not 48-bytes in length. 79 X, 80 /// Variant returned when the y-coordinate is not 48-bytes in length. 81 Y, 82 } 83 impl Display for UncompressedP384PubKeyErr { 84 #[inline] 85 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 86 f.write_str(match *self { 87 Self::X => "the P-384 public key x-coordinate is not 48-bytes in length", 88 Self::Y => "the P-384 public key y-coordinate is not 48-bytes in length", 89 }) 90 } 91 } 92 impl Error for UncompressedP384PubKeyErr {} 93 /// Error returned from [`CompressedP384PubKey::try_from`] when the x-coordinate 94 /// is not exactly 48 bytes in length. 95 #[derive(Clone, Copy, Debug, Eq, PartialEq)] 96 pub struct CompressedP384PubKeyErr; 97 impl Display for CompressedP384PubKeyErr { 98 #[inline] 99 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 100 f.write_str("the compressed P-384 public key x-coordinate is not 48-bytes in length") 101 } 102 } 103 impl Error for CompressedP384PubKeyErr {} 104 /// Error returned from [`RsaPubKey::try_from`]. 105 #[derive(Clone, Copy, Debug, Eq, PartialEq)] 106 pub enum RsaPubKeyErr { 107 /// Variant returned when the modulus has a leading 0. 108 NLeading0, 109 /// Variant returned when the modulus has fewer than [`MIN_RSA_N_BITS`] or more than 110 /// [`MAX_RSA_N_BITS`]. 111 NSize, 112 /// Variant returned when the modulus is even. 113 NEven, 114 /// Variant returned when the exponent is less than [`MIN_RSA_E`]. 115 ESize, 116 /// Variant returned when the exponent is even. 117 EEven, 118 } 119 impl Display for RsaPubKeyErr { 120 #[inline] 121 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 122 f.write_str(match *self { 123 Self::NLeading0 => "the RSA public key modulus had a leading 0", 124 Self::NSize => { 125 "the RSA public key modulus was less than 2048 bits or greater than 16384" 126 } 127 Self::NEven => "the RSA public key modulus was even", 128 Self::ESize => "the RSA public key exponent was less than 3", 129 Self::EEven => "the RSA public key exponent was even", 130 }) 131 } 132 } 133 impl Error for RsaPubKeyErr {} 134 /// Error returned when an alleged public key is not valid. 135 #[derive(Clone, Copy, Debug, Eq, PartialEq)] 136 pub enum PubKeyErr { 137 /// Error when [`Ed25519PubKey`] is not valid. 138 /// 139 /// Note this means the underlying point is either not on the curve or is an element 140 /// of the small-order subgroup. 141 Ed25519, 142 /// Error when [`UncompressedP256PubKey`] or [`CompressedP256PubKey`] is not valid. 143 P256, 144 /// Error when [`UncompressedP384PubKey`] or [`CompressedP384PubKey`] is not valid. 145 P384, 146 } 147 impl Display for PubKeyErr { 148 #[inline] 149 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 150 f.write_str(match *self { 151 Self::Ed25519 => "Ed25519 public key is invalid", 152 Self::P256 => "P-256 public key is invalid", 153 Self::P384 => "P-384 public key is invalid", 154 }) 155 } 156 } 157 impl Error for PubKeyErr {} 158 /// Error returned from [`Ed25519Signature::try_from`]. 159 #[derive(Clone, Copy, Debug, Eq, PartialEq)] 160 pub struct Ed25519SignatureErr; 161 impl Display for Ed25519SignatureErr { 162 #[inline] 163 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 164 f.write_str("the Ed25519 signature is not 64-bytes in length") 165 } 166 } 167 impl Error for Ed25519SignatureErr {} 168 /// Error returned from [`Aaguid::try_from`] when the slice is not exactly 169 /// 16-bytes in length. 170 #[derive(Clone, Copy, Debug, Eq, PartialEq)] 171 pub struct AaguidErr; 172 impl Display for AaguidErr { 173 #[inline] 174 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 175 f.write_str("the AAGUID is not 16-bytes in length") 176 } 177 } 178 impl Error for AaguidErr {} 179 /// Error returned in [`AuthenticatorDataErr::AuthenticatorExtension`]. 180 #[derive(Clone, Copy, Debug, Eq, PartialEq)] 181 pub enum AuthenticatorExtensionOutputErr { 182 /// The `slice` had an invalid length. 183 Len, 184 /// The first byte did not represent a map of one, two, or three key pairs. 185 CborHeader, 186 /// `credProtect` had an invalid value. 187 CredProtectValue, 188 /// `hmac-secret` had an invalid value. 189 HmacSecretValue, 190 /// `minPinLength` had an invalid value. 191 MinPinLengthValue, 192 /// `hmac-secret-mc` was not a byte string with additional info 24. 193 HmacSecretMcType, 194 /// `hmac-secret-mc` was not a byte string of length 48 or 80. 195 HmacSecretMcValue, 196 /// Fewer extensions existed than expected. 197 Missing, 198 } 199 impl Display for AuthenticatorExtensionOutputErr { 200 #[inline] 201 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 202 f.write_str(match *self { 203 Self::Len => "CBOR authenticator extensions had an invalid length", 204 Self::CborHeader => "CBOR authenticator extensions did not represent a map of one, two, or three key pairs", 205 Self::CredProtectValue => "CBOR authenticator extension 'credProtect' had an invalid value", 206 Self::HmacSecretValue => "CBOR authenticator extension 'hmac-secret' had an invalid value", 207 Self::MinPinLengthValue => "CBOR authenticator extension 'minPinLength' had an invalid value", 208 Self::HmacSecretMcType => "CBOR authenticator extension 'hmac-secret-mc' was not a byte string with additional info 24", 209 Self::HmacSecretMcValue => "CBOR authenticator extension 'hmac-secret-mc' was not a byte string of length 48 or 80", 210 Self::Missing => "CBOR authenticator extensions had fewer extensions than expected", 211 }) 212 } 213 } 214 impl Error for AuthenticatorExtensionOutputErr {} 215 /// Error returned in [`AttestedCredentialDataErr::CoseKey`]. 216 #[derive(Clone, Copy, Debug, Eq, PartialEq)] 217 pub enum CoseKeyErr { 218 /// The `slice` had an invalid length. 219 Len, 220 /// The COSE Key type was not `OKP`, `EC2`, or `RSA`. 221 CoseKeyType, 222 /// The `slice` was malformed and did not conform to an Ed25519 public key encoded as a COSE Key per 223 /// [RFC 9052](https://www.rfc-editor.org/rfc/rfc9052) and [RFC 9053](https://www.rfc-editor.org/rfc/rfc9053). 224 Ed25519CoseEncoding, 225 /// The `slice` was malformed and did not conform to an ECDSA public key based on curve P-256 and SHA-256 226 /// encoded as a COSE Key per [RFC 9052](https://www.rfc-editor.org/rfc/rfc9052) and 227 /// [RFC 9053](https://www.rfc-editor.org/rfc/rfc9053). 228 P256CoseEncoding, 229 /// The `slice` was malformed and did not conform to an ECDSA public key based on curve P-384 and SHA-384 230 /// encoded as a COSE Key per [RFC 9052](https://www.rfc-editor.org/rfc/rfc9052) and 231 /// [RFC 9053](https://www.rfc-editor.org/rfc/rfc9053). 232 P384CoseEncoding, 233 /// The `slice` was malformed and did not conform to an RSASSA-PKCS1-v1.5 public key using SHA-256 encoded as a 234 /// COSE Key per [RFC 8230](https://www.rfc-editor.org/rfc/rfc8230.html). 235 RsaCoseEncoding, 236 /// The RSA public key exponent is too large. 237 RsaExponentTooLarge, 238 /// The RSA public key was invalid. 239 RsaPubKey(RsaPubKeyErr), 240 } 241 impl Display for CoseKeyErr { 242 #[inline] 243 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 244 match *self { 245 Self::Len => f.write_str("COSE key data had an invalid length"), 246 Self::CoseKeyType => f.write_str("COSE key type was not 'OKP', 'EC2', or 'RSA'"), 247 Self::Ed25519CoseEncoding => f.write_str("Ed25519 COSE key was not encoded correctly"), 248 Self::P256CoseEncoding => { 249 f.write_str("ECDSA with P-256 and SHA-256 COSE key was not encoded correctly") 250 } 251 Self::P384CoseEncoding => { 252 f.write_str("ECDSA with P-384 and SHA-384 COSE key was not encoded correctly") 253 } 254 Self::RsaCoseEncoding => { 255 f.write_str("RSASSA-PKCS1-v1.5 using SHA-256 COSE key was not encoded correctly") 256 } 257 Self::RsaExponentTooLarge => f.write_str("RSA public key exponent is too large"), 258 Self::RsaPubKey(err) => err.fmt(f), 259 } 260 } 261 } 262 impl Error for CoseKeyErr {} 263 /// Error returned in [`AuthenticatorDataErr::AttestedCredential`]. 264 #[derive(Clone, Copy, Debug, Eq, PartialEq)] 265 pub enum AttestedCredentialDataErr { 266 /// The `slice` had an invalid length. 267 Len, 268 /// Error when the claimed credential ID length is not valid. 269 CredentialId(CredentialIdErr), 270 /// Error related to the credential public key. 271 CoseKey(CoseKeyErr), 272 } 273 impl Display for AttestedCredentialDataErr { 274 #[inline] 275 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 276 match *self { 277 Self::Len => f.write_str("attested credential data had an invalid length"), 278 Self::CredentialId(err) => err.fmt(f), 279 Self::CoseKey(err) => err.fmt(f), 280 } 281 } 282 } 283 impl Error for AttestedCredentialDataErr {} 284 /// Error returned from [`AuthenticatorData::try_from`]. 285 #[derive(Clone, Copy, Debug, Eq, PartialEq)] 286 pub enum AuthenticatorDataErr { 287 /// The `slice` had an invalid length. 288 Len, 289 /// Bit 1 in [`flags`](https://www.w3.org/TR/webauthn-3/#authdata-flags) is not 0. 290 FlagsBit1Not0, 291 /// Bit 5 in [`flags`](https://www.w3.org/TR/webauthn-3/#authdata-flags) is not 0. 292 FlagsBit5Not0, 293 /// [AT](https://www.w3.org/TR/webauthn-3/#authdata-flags-at) bit was 0. 294 AttestedCredentialDataNotIncluded, 295 /// [BE](https://www.w3.org/TR/webauthn-3/#authdata-flags-be) and 296 /// [BS](https://www.w3.org/TR/webauthn-3/#authdata-flags-bs) bits were 0 and 1 respectively. 297 BackupWithoutEligibility, 298 /// Error returned when [`AttestedCredentialData`] is malformed. 299 AttestedCredential(AttestedCredentialDataErr), 300 /// Error returned when [`AuthenticatorExtensionOutput`] is malformed. 301 AuthenticatorExtension(AuthenticatorExtensionOutputErr), 302 /// [ED](https://www.w3.org/TR/webauthn-3/#authdata-flags-ed) bit was 0, but 303 /// [`extensions`](https://www.w3.org/TR/webauthn-3/#authdata-extensions) existed. 304 NoExtensionBitWithData, 305 /// [ED](https://www.w3.org/TR/webauthn-3/#authdata-flags-ed) bit was 1, but 306 /// [`extensions`](https://www.w3.org/TR/webauthn-3/#authdata-extensions) did not exist. 307 ExtensionBitWithoutData, 308 /// There was data remaining that could not be deserialized. 309 TrailingData, 310 } 311 impl Display for AuthenticatorDataErr { 312 #[inline] 313 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 314 match *self { 315 Self::Len => AuthDataErr::< 316 Infallible, 317 AttestedCredentialDataErr, 318 AuthenticatorExtensionOutputErr, 319 >::Len 320 .fmt(f), 321 Self::FlagsBit1Not0 => AuthDataErr::< 322 Infallible, 323 AttestedCredentialDataErr, 324 AuthenticatorExtensionOutputErr, 325 >::FlagsBit1Not0 326 .fmt(f), 327 Self::FlagsBit5Not0 => AuthDataErr::< 328 Infallible, 329 AttestedCredentialDataErr, 330 AuthenticatorExtensionOutputErr, 331 >::FlagsBit5Not0 332 .fmt(f), 333 Self::AttestedCredentialDataNotIncluded => { 334 f.write_str("attested credential data was not included") 335 } 336 Self::BackupWithoutEligibility => AuthDataErr::< 337 Infallible, 338 AttestedCredentialDataErr, 339 AuthenticatorExtensionOutputErr, 340 >::BackupWithoutEligibility 341 .fmt(f), 342 Self::AttestedCredential(err) => err.fmt(f), 343 Self::AuthenticatorExtension(err) => err.fmt(f), 344 Self::NoExtensionBitWithData => AuthDataErr::< 345 Infallible, 346 AttestedCredentialDataErr, 347 AuthenticatorExtensionOutputErr, 348 >::NoExtensionBitWithData 349 .fmt(f), 350 Self::ExtensionBitWithoutData => AuthDataErr::< 351 Infallible, 352 AttestedCredentialDataErr, 353 AuthenticatorExtensionOutputErr, 354 >::ExtensionBitWithoutData 355 .fmt(f), 356 Self::TrailingData => AuthDataErr::< 357 Infallible, 358 AttestedCredentialDataErr, 359 AuthenticatorExtensionOutputErr, 360 >::TrailingData 361 .fmt(f), 362 } 363 } 364 } 365 impl Error for AuthenticatorDataErr {} 366 /// Error returned in [`AttestationObjectErr::Attestation`]. 367 #[derive(Clone, Copy, Debug, Eq, PartialEq)] 368 pub enum AttestationErr { 369 /// The `slice` had an invalid length. 370 Len, 371 /// The attestation format does not exist. 372 MissingFormat, 373 /// The attestation format is not supported. 374 UnsupportedFormat, 375 /// The attestation statement does not exist. 376 MissingStatement, 377 /// [None](https://www.w3.org/TR/webauthn-3/#sctn-none-attestation) has the wrong format. 378 NoneFormat, 379 /// [Packed](https://www.w3.org/TR/webauthn-3/#sctn-packed-attestation) was not a map of two or three key-value pairs. 380 PackedFormat, 381 /// [Packed](https://www.w3.org/TR/webauthn-3/#sctn-packed-attestation) did not have an algorithm. 382 PackedFormatMissingAlg, 383 /// [Packed](https://www.w3.org/TR/webauthn-3/#sctn-packed-attestation) had an unsupported algorithm. 384 PackedFormatUnsupportedAlg, 385 /// [Packed](https://www.w3.org/TR/webauthn-3/#sctn-packed-attestation) did not have a signature. 386 PackedFormatMissingSig, 387 /// [Packed](https://www.w3.org/TR/webauthn-3/#sctn-packed-attestation) Ed25519 signature CBOR was invalid. 388 PackedFormatCborEd25519Signature, 389 /// [Packed](https://www.w3.org/TR/webauthn-3/#sctn-packed-attestation) P-256 signature CBOR was invalid. 390 PackedFormatCborP256Signature, 391 /// [Packed](https://www.w3.org/TR/webauthn-3/#sctn-packed-attestation) P-256 signature was invalid. 392 PackedFormatP256, 393 /// [Packed](https://www.w3.org/TR/webauthn-3/#sctn-packed-attestation) P-384 signature CBOR was invalid. 394 PackedFormatCborP384Signature, 395 /// [Packed](https://www.w3.org/TR/webauthn-3/#sctn-packed-attestation) P-384 signature was invalid. 396 PackedFormatP384, 397 /// [Packed](https://www.w3.org/TR/webauthn-3/#sctn-packed-attestation) RS256 signature CBOR was invalid. 398 PackedFormatCborRs256Signature, 399 /// [Packed](https://www.w3.org/TR/webauthn-3/#sctn-packed-attestation) RS256 signature was invalid. 400 PackedFormatRs256, 401 } 402 impl Display for AttestationErr { 403 #[inline] 404 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 405 f.write_str(match *self { 406 Self::Len => "CBOR attestation had an invalid length", 407 Self::MissingFormat => "CBOR attestation did not have an attestation format", 408 Self::UnsupportedFormat => "CBOR attestation format is not supported", 409 Self::MissingStatement => "CBOR attestation did not have an attestation statement", 410 Self::NoneFormat => "CBOR attestation had the wrong format for the none attestation", 411 Self::PackedFormat => "CBOR attestation had the wrong number of key-value pairs for the packed attestation", 412 Self::PackedFormatMissingAlg => "CBOR attestation did not have an algorithm for the packed attestation", 413 Self::PackedFormatUnsupportedAlg => "CBOR attestation had an unsupported algorithm for the packed attestation", 414 Self::PackedFormatMissingSig => "CBOR attestation did not have a signature for the packed attestation", 415 Self::PackedFormatCborEd25519Signature => "CBOR attestation Ed25519 signature had the wrong CBOR format for the packed attestation", 416 Self::PackedFormatCborP256Signature => "CBOR attestation P-256 signature had the wrong CBOR format for the packed attestation", 417 Self::PackedFormatP256 => "CBOR attestation P-256 signature was invalid for the packed attestation", 418 Self::PackedFormatCborP384Signature => "CBOR attestation P-384 signature had the wrong CBOR format for the packed attestation", 419 Self::PackedFormatP384 => "CBOR attestation P-384 signature was invalid for the packed attestation", 420 Self::PackedFormatCborRs256Signature => "CBOR attestation RS256 signature had the wrong CBOR format for the packed attestation", 421 Self::PackedFormatRs256 => "CBOR attestation RS256 signature was invalid for the packed attestation", 422 }) 423 } 424 } 425 impl Error for AttestationErr {} 426 /// Error returned by [`AttestationObject::try_from`]. 427 #[derive(Clone, Copy, Debug, Eq, PartialEq)] 428 pub enum AttestationObjectErr { 429 /// The `slice` had an invalid length. 430 Len, 431 /// The `slice` was not a CBOR map with three key-value pairs. 432 NotAMapOf3, 433 /// Error when [`PackedAttestation::signature`] does not match the type of 434 /// [`AttestedCredentialData::credential_public_key`] when self attestation 435 /// is used. 436 SelfAttestationAlgorithmMismatch, 437 /// The third key was not "authData". 438 MissingAuthData, 439 /// `authData` did not have a byte string data type. 440 AuthDataType, 441 /// `authData` length with additional info 24 or 25 did not have a conforming length. 442 AuthDataLenInfo, 443 /// Error related to the encoding of [`Attestation`]. 444 Attestation(AttestationErr), 445 /// [`AuthenticatorData`] length did not match the length encoded in the CBOR data. 446 CborAuthDataLenMismatch, 447 /// Error from [`AuthenticatorData::try_from`]. 448 AuthData(AuthenticatorDataErr), 449 } 450 impl Display for AttestationObjectErr { 451 #[inline] 452 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 453 match *self { 454 Self::Len => f.write_str("CBOR attestation object had an invalid length"), 455 Self::NotAMapOf3 => { 456 f.write_str("CBOR attestation object was not a map of three key-value pairs") 457 } 458 Self::MissingAuthData => { 459 f.write_str("CBOR attestation object did not have 'authData' as its third key") 460 } 461 Self::AuthDataType => { 462 f.write_str("CBOR attestation object authenticator data invalid type") 463 } 464 Self::AuthDataLenInfo => f.write_str( 465 "CBOR attestation object authenticator data had an invalid encoded length", 466 ), 467 Self::Attestation(err) => err.fmt(f), 468 Self::CborAuthDataLenMismatch => f.write_str( 469 "CBOR attestation object authenticator data length did not match the CBOR value", 470 ), 471 Self::AuthData(err) => err.fmt(f), 472 Self::SelfAttestationAlgorithmMismatch => f.write_str("CBOR attestation object packed attestation contained a self attestation whose format did not match the type of the public key"), 473 } 474 } 475 } 476 impl Error for AttestationObjectErr {} 477 /// Error in [`RegCeremonyErr::Extension`]. 478 #[derive(Clone, Copy, Debug, Eq, PartialEq)] 479 pub enum ExtensionErr { 480 /// [`ClientExtensionsOutputs::cred_props`] was sent from the client but was not supposed to be. 481 ForbiddenCredProps, 482 /// [`ClientExtensionsOutputs::prf`] was sent from the client but was not supposed to be. 483 ForbiddenPrf, 484 /// [`AuthenticatorExtensionOutput::cred_protect`] was sent from the client but was not supposed to be. 485 ForbiddenCredProtect, 486 /// [`AuthenticatorExtensionOutput::hmac_secret`] was sent from the client but was not supposed to be. 487 ForbiddenHmacSecret, 488 /// [`AuthenticatorExtensionOutput::min_pin_length`] was sent from the client but was not supposed to be. 489 ForbiddenMinPinLength, 490 /// [`Extension::cred_props`] was requested, but the required response was not sent back. 491 MissingCredProps, 492 /// [`Extension::prf`] was requested, but the required response was not sent back. 493 MissingPrf, 494 /// [`Extension::cred_protect`] was requested, but the required response was not sent back. 495 MissingCredProtect, 496 /// [`Extension::min_pin_length`] was requested, but the required response was not sent back. 497 MissingMinPinLength, 498 /// [`Extension::cred_protect`] was requested with the first policy, but the second policy was sent back. 499 InvalidCredProtectValue(CredProtect, CredentialProtectionPolicy), 500 /// [`Extension::prf`] was requested, but 501 /// [`enabled`](https://www.w3.org/TR/webauthn-3/#dom-authenticationextensionsprfoutputs-enabled) was `false`. 502 InvalidPrfValue, 503 /// [`Extension::prf`] was requested, but 504 /// [`hmac-secret`](https://fidoalliance.org/specs/fido-v2.2-rd-20230321/fido-client-to-authenticator-protocol-v2.2-rd-20230321.html#sctn-hmac-secret-extension) 505 /// was `false`. 506 InvalidHmacSecretValue, 507 /// [`Extension::min_pin_length`] was requested, but 508 /// [`minPinLength`](https://fidoalliance.org/specs/fido-v2.2-rd-20230321/fido-client-to-authenticator-protocol-v2.2-rd-20230321.html#sctn-minpinlength-extension) 509 /// was sent set to the second value which is strictly less than the required first value. 510 InvalidMinPinLength(FourToSixtyThree, FourToSixtyThree), 511 } 512 impl Display for ExtensionErr { 513 #[inline] 514 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 515 match *self { 516 Self::ForbiddenCredProps => { 517 f.write_str("credProps was sent from the client, but it is not allowed") 518 } 519 Self::ForbiddenPrf => { 520 f.write_str("prf info was sent from the client, but it is not allowed") 521 } 522 Self::ForbiddenCredProtect => { 523 f.write_str("credProtect was sent from the client, but it is not allowed") 524 } 525 Self::ForbiddenHmacSecret => { 526 f.write_str("hmac-secret info was sent from the client, but it is not allowed") 527 } 528 Self::ForbiddenMinPinLength => { 529 f.write_str("minPinLength info was sent from the client, but it is not allowed") 530 } 531 Self::MissingCredProps => f.write_str("credProps was not sent from the client"), 532 Self::MissingPrf => f.write_str("prf was not sent from the client"), 533 Self::MissingCredProtect => f.write_str("credProtect was not sent from the client"), 534 Self::MissingMinPinLength => f.write_str("minPinLength was not sent from the client"), 535 Self::InvalidCredProtectValue(sent, rec) => write!( 536 f, 537 "credProtect was sent with {sent}, but {rec} was received", 538 ), 539 Self::InvalidPrfValue => f.write_str("prf was false"), 540 Self::InvalidHmacSecretValue => f.write_str("hmac-secret was false"), 541 Self::InvalidMinPinLength(sent, rec) => write!( 542 f, 543 "minPinLength was sent, but {rec} is strictly smaller than the required {sent}" 544 ), 545 } 546 } 547 } 548 impl Error for ExtensionErr {} 549 /// Error returned by [`RegistrationServerState::verify`]. 550 #[derive(Debug)] 551 pub enum RegCeremonyErr { 552 /// [`PublicKeyCredentialCreationOptions::timeout`] was exceeded. 553 Timeout, 554 /// [`AuthenticatorAttestation::client_data_json`] could not be parsed by 555 /// [`CollectedClientData::from_client_data_json`]. 556 CollectedClientData(CollectedClientDataErr), 557 /// [`AuthenticatorAttestation::client_data_json`] could not be parsed by 558 /// [`CollectedClientData::from_client_data_json_relaxed`]. 559 #[cfg_attr(docsrs, doc(cfg(feature = "serde_relaxed")))] 560 #[cfg(feature = "serde_relaxed")] 561 CollectedClientDataRelaxed(SerdeJsonErr), 562 /// [`AuthenticatorAttestation::attestation_object`] could not be parsed into 563 /// [`AttestationObject`]. 564 AttestationObject(AttestationObjectErr), 565 /// [`UncompressedPubKey`] was not valid. 566 PubKey(PubKeyErr), 567 /// [`PackedAttestation::signature`] was not valid. 568 AttestationSignature, 569 /// [`CollectedClientData::origin`] does not match one of the values in 570 /// [`RegistrationVerificationOptions::allowed_origins`]. 571 OriginMismatch, 572 /// [`CollectedClientData::cross_origin`] was `true`, but 573 /// [`RegistrationVerificationOptions::allowed_top_origins`] was `None`. 574 CrossOrigin, 575 /// [`CollectedClientData::top_origin`] does not match one of the values in 576 /// [`RegistrationVerificationOptions::allowed_top_origins`]. 577 TopOriginMismatch, 578 /// [`PublicKeyCredentialCreationOptions::challenge`] and [`CollectedClientData::challenge`] don't match. 579 ChallengeMismatch, 580 /// The SHA-256 hash of [`PublicKeyCredentialCreationOptions::rp_id`] does not match [`AuthenticatorData::rp_id_hash`]. 581 RpIdHashMismatch, 582 /// [`Flag::user_present`] was `false` despite [`CredentialCreationOptions::mediation`] 583 /// being something other than [`CredentialMediationRequirement::Conditional`]. 584 UserNotPresent, 585 /// [`AuthenticatorSelectionCriteria::user_verification`] was set to [`UserVerificationRequirement::Required`], 586 /// but [`Flag::user_verified`] was `false`. 587 UserNotVerified, 588 /// [`Backup::NotEligible`] was not sent back despite [`BackupReq::NotEligible`]. 589 BackupEligible, 590 /// [`Backup::NotEligible`] was sent back despite [`BackupReq::Eligible`]. 591 BackupNotEligible, 592 /// [`Backup::Eligible`] was not sent back despite [`BackupReq::EligibleNotExists`]. 593 BackupExists, 594 /// [`Backup::Exists`] was not sent back despite [`BackupReq::Exists`]. 595 BackupDoesNotExist, 596 /// [`AuthenticatorAttachment`] was not sent back despite being required. 597 MissingAuthenticatorAttachment, 598 /// [`AuthenticatorAttachmentReq::Platform`] or [`AuthenticatorAttachmentReq::CrossPlatform`] was sent 599 /// but [`AuthenticatorAttachment`] was not the same. 600 AuthenticatorAttachmentMismatch, 601 /// Variant returned when there is an issue with [`Extension`]s. 602 Extension(ExtensionErr), 603 /// [`PublicKeyCredentialCreationOptions::pub_key_cred_params`] does not contain an algorithm associated with 604 /// [`AttestedCredentialData::credential_public_key`]. 605 PublicKeyAlgorithmMismatch, 606 /// Variant returned when [`RegisteredCredential`] cannot be created due to invalid state. 607 Credential(CredentialErr), 608 } 609 impl Display for RegCeremonyErr { 610 #[inline] 611 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 612 match *self { 613 Self::Timeout => CeremonyErr::<AttestationObjectErr>::Timeout.fmt(f), 614 Self::CollectedClientData(ref err) => write!(f, "clientDataJSON could not be parsed: {err}"), 615 #[cfg(feature = "serde_relaxed")] 616 Self::CollectedClientDataRelaxed(ref err) => write!(f, "clientDataJSON could not be parsed: {err}"), 617 Self::AttestationObject(err) => err.fmt(f), 618 Self::PubKey(err) => err.fmt(f), 619 Self::AttestationSignature => AuthRespErr::<AttestationObjectErr>::Signature.fmt(f), 620 Self::OriginMismatch => CeremonyErr::<AttestationObjectErr>::OriginMismatch.fmt(f), 621 Self::CrossOrigin => CeremonyErr::<AttestationObjectErr>::CrossOrigin.fmt(f), 622 Self::TopOriginMismatch => CeremonyErr::<AttestationObjectErr>::TopOriginMismatch.fmt(f), 623 Self::BackupEligible => CeremonyErr::<AttestationObjectErr>::BackupEligible.fmt(f), 624 Self::BackupNotEligible => CeremonyErr::<AttestationObjectErr>::BackupNotEligible.fmt(f), 625 Self::BackupExists => CeremonyErr::<AttestationObjectErr>::BackupExists.fmt(f), 626 Self::BackupDoesNotExist => CeremonyErr::<AttestationObjectErr>::BackupDoesNotExist.fmt(f), 627 Self::ChallengeMismatch => CeremonyErr::<AttestationObjectErr>::ChallengeMismatch.fmt(f), 628 Self::RpIdHashMismatch => CeremonyErr::<AttestationObjectErr>::RpIdHashMismatch.fmt(f), 629 Self::UserNotPresent => f.write_str("user was not present despite mediation not being conditional"), 630 Self::UserNotVerified => CeremonyErr::<AttestationObjectErr>::UserNotVerified.fmt(f), 631 Self::MissingAuthenticatorAttachment => f.write_str("the authenticator attachment modality was not sent despite being required"), 632 Self::AuthenticatorAttachmentMismatch => f.write_str("the kind of authenticator requested (e.g., platform) was not used"), 633 Self::Extension(ext) => ext.fmt(f), 634 Self::PublicKeyAlgorithmMismatch => f.write_str( 635 "the allowed public key algorithms does not contain the algorithm sent from the client", 636 ), 637 Self::Credential(err) => err.fmt(f), 638 } 639 } 640 } 641 impl Error for RegCeremonyErr {}