webauthn_rp

WebAuthn Level 3 RP library.
git clone https://git.philomathiclife.com/repos/webauthn_rp
Log | Files | Refs | README

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 {}