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