webauthn_rp

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

bin.rs (4901B)


      1 use super::{
      2     super::bin::{
      3         Decode, DecodeBuffer, EncDecErr, Encode, EncodeBuffer, EncodeBufferFallible as _,
      4     },
      5     AuthTransports, AuthenticatorAttachment, Backup, CredentialId, CredentialIdErr,
      6 };
      7 use core::{
      8     convert::Infallible,
      9     error::Error,
     10     fmt::{self, Display, Formatter},
     11 };
     12 /// [`Backup::NotEligible`] tag.
     13 const BACKUP_NOT_ELIGIBLE: u8 = 0;
     14 /// [`Backup::Eligible`] tag.
     15 const BACKUP_ELIGIBLE: u8 = 1;
     16 /// [`Backup::Exists`] tag.
     17 const BACKUP_EXISTS: u8 = 2;
     18 impl EncodeBuffer for Backup {
     19     fn encode_into_buffer(&self, buffer: &mut Vec<u8>) {
     20         match *self {
     21             Self::NotEligible => BACKUP_NOT_ELIGIBLE,
     22             Self::Eligible => BACKUP_ELIGIBLE,
     23             Self::Exists => BACKUP_EXISTS,
     24         }
     25         .encode_into_buffer(buffer);
     26     }
     27 }
     28 impl<'a> DecodeBuffer<'a> for Backup {
     29     type Err = EncDecErr;
     30     fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> {
     31         u8::decode_from_buffer(data).and_then(|val| match val {
     32             BACKUP_NOT_ELIGIBLE => Ok(Self::NotEligible),
     33             BACKUP_ELIGIBLE => Ok(Self::Eligible),
     34             BACKUP_EXISTS => Ok(Self::Exists),
     35             _ => Err(EncDecErr),
     36         })
     37     }
     38 }
     39 /// Error returned from [`AuthTransports::decode`].
     40 #[derive(Clone, Copy, Debug)]
     41 pub struct DecodeAuthTransportsErr;
     42 impl Display for DecodeAuthTransportsErr {
     43     #[inline]
     44     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
     45         f.write_str("AuthTransports could not be decoded")
     46     }
     47 }
     48 impl Error for DecodeAuthTransportsErr {}
     49 impl Encode for AuthTransports {
     50     type Output<'a>
     51         = u8
     52     where
     53         Self: 'a;
     54     type Err = Infallible;
     55     #[inline]
     56     fn encode(&self) -> Result<Self::Output<'_>, Self::Err> {
     57         Ok(self.0)
     58     }
     59 }
     60 impl Decode for AuthTransports {
     61     type Input<'a> = u8;
     62     type Err = DecodeAuthTransportsErr;
     63     #[inline]
     64     fn decode(input: Self::Input<'_>) -> Result<Self, Self::Err> {
     65         if input <= Self::all().0 {
     66             Ok(Self(input))
     67         } else {
     68             Err(DecodeAuthTransportsErr)
     69         }
     70     }
     71 }
     72 impl EncodeBuffer for AuthTransports {
     73     fn encode_into_buffer(&self, buffer: &mut Vec<u8>) {
     74         self.0.encode_into_buffer(buffer);
     75     }
     76 }
     77 impl<'a> DecodeBuffer<'a> for AuthTransports {
     78     type Err = EncDecErr;
     79     fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> {
     80         u8::decode_from_buffer(data).and_then(|val| Self::decode(val).map_err(|_e| EncDecErr))
     81     }
     82 }
     83 impl<T: AsRef<[u8]>> Encode for CredentialId<T> {
     84     type Output<'a>
     85         = &'a [u8]
     86     where
     87         Self: 'a;
     88     type Err = Infallible;
     89     #[inline]
     90     fn encode(&self) -> Result<Self::Output<'_>, Self::Err> {
     91         Ok(self.0.as_ref())
     92     }
     93 }
     94 impl Decode for CredentialId<Vec<u8>> {
     95     type Input<'a> = Vec<u8>;
     96     type Err = CredentialIdErr;
     97     #[inline]
     98     fn decode(input: Self::Input<'_>) -> Result<Self, Self::Err> {
     99         match CredentialId::<&[u8]>::from_slice(input.as_slice()) {
    100             Ok(_) => Ok(Self(input)),
    101             Err(e) => Err(e),
    102         }
    103     }
    104 }
    105 impl EncodeBuffer for CredentialId<&[u8]> {
    106     #[expect(clippy::unreachable, reason = "when there is a bug, we want to crash")]
    107     fn encode_into_buffer(&self, buffer: &mut Vec<u8>) {
    108         // Max length is 1023, so this won't error.
    109         self.0
    110             .encode_into_buffer(buffer)
    111             .unwrap_or_else(|_e| unreachable!("there is a bug in [u8]::encode_into_buffer"));
    112     }
    113 }
    114 impl<'a> DecodeBuffer<'a> for CredentialId<Vec<u8>> {
    115     type Err = EncDecErr;
    116     fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> {
    117         <&[u8]>::decode_from_buffer(data).and_then(|val| {
    118             CredentialId::<&[u8]>::from_slice(val)
    119                 .map_err(|_e| EncDecErr)
    120                 .map(|_| Self(val.to_owned()))
    121         })
    122     }
    123 }
    124 /// [`AuthenticatorAttachment::None`] tag.
    125 const AUTH_ATTACH_NONE: u8 = 0;
    126 /// [`AuthenticatorAttachment::Platform`] tag.
    127 const AUTH_ATTACH_PLATFORM: u8 = 1;
    128 /// [`AuthenticatorAttachment::CrossPlatform`] tag.
    129 const AUTH_ATTACH_CROSS_PLATFORM: u8 = 2;
    130 impl EncodeBuffer for AuthenticatorAttachment {
    131     fn encode_into_buffer(&self, buffer: &mut Vec<u8>) {
    132         match *self {
    133             Self::None => AUTH_ATTACH_NONE,
    134             Self::Platform => AUTH_ATTACH_PLATFORM,
    135             Self::CrossPlatform => AUTH_ATTACH_CROSS_PLATFORM,
    136         }
    137         .encode_into_buffer(buffer);
    138     }
    139 }
    140 impl<'a> DecodeBuffer<'a> for AuthenticatorAttachment {
    141     type Err = EncDecErr;
    142     fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> {
    143         u8::decode_from_buffer(data).and_then(|val| match val {
    144             AUTH_ATTACH_NONE => Ok(Self::None),
    145             AUTH_ATTACH_PLATFORM => Ok(Self::Platform),
    146             AUTH_ATTACH_CROSS_PLATFORM => Ok(Self::CrossPlatform),
    147             _ => Err(EncDecErr),
    148         })
    149     }
    150 }