webauthn_rp

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

ser_server_state.rs (11922B)


      1 use super::{
      2     super::super::bin::{
      3         Decode, DecodeBuffer, EncDecErr, Encode, EncodeBuffer, EncodeBufferFallible,
      4     },
      5     AuthenticationServerState, CredInfo, CredentialId, DiscoverableAuthenticationServerState,
      6     ExtensionReq, NonDiscoverableAuthenticationServerState, SentChallenge,
      7     ServerCredSpecificExtensionInfo, ServerExtensionInfo, ServerPrfInfo,
      8     SignatureCounterEnforcement, UserVerificationRequirement,
      9 };
     10 #[cfg(doc)]
     11 use super::{AllowedCredential, NonDiscoverableCredentialRequestOptions};
     12 use core::{
     13     error::Error,
     14     fmt::{self, Display, Formatter},
     15 };
     16 #[cfg(doc)]
     17 use std::time::UNIX_EPOCH;
     18 use std::time::{SystemTime, SystemTimeError};
     19 impl EncodeBuffer for ServerPrfInfo {
     20     fn encode_into_buffer(&self, buffer: &mut Vec<u8>) {
     21         match *self {
     22             Self::None => 0u8.encode_into_buffer(buffer),
     23             Self::One(req) => {
     24                 1u8.encode_into_buffer(buffer);
     25                 req.encode_into_buffer(buffer);
     26             }
     27             Self::Two(req) => {
     28                 2u8.encode_into_buffer(buffer);
     29                 req.encode_into_buffer(buffer);
     30             }
     31         }
     32     }
     33 }
     34 impl<'a> DecodeBuffer<'a> for ServerPrfInfo {
     35     type Err = EncDecErr;
     36     fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> {
     37         u8::decode_from_buffer(data).and_then(|val| match val {
     38             0 => Ok(Self::None),
     39             1 => ExtensionReq::decode_from_buffer(data).map(Self::One),
     40             2 => ExtensionReq::decode_from_buffer(data).map(Self::Two),
     41             _ => Err(EncDecErr),
     42         })
     43     }
     44 }
     45 impl EncodeBuffer for ServerCredSpecificExtensionInfo {
     46     fn encode_into_buffer(&self, buffer: &mut Vec<u8>) {
     47         self.prf.encode_into_buffer(buffer);
     48     }
     49 }
     50 impl<'a> DecodeBuffer<'a> for ServerCredSpecificExtensionInfo {
     51     type Err = EncDecErr;
     52     fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> {
     53         ServerPrfInfo::decode_from_buffer(data).map(|prf| Self { prf })
     54     }
     55 }
     56 impl EncodeBuffer for CredInfo {
     57     fn encode_into_buffer(&self, buffer: &mut Vec<u8>) {
     58         CredentialId::<&[u8]>::from(&self.id).encode_into_buffer(buffer);
     59         self.ext.encode_into_buffer(buffer);
     60     }
     61 }
     62 impl<'a> DecodeBuffer<'a> for CredInfo {
     63     type Err = EncDecErr;
     64     fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> {
     65         CredentialId::<Vec<u8>>::decode_from_buffer(data).and_then(|id| {
     66             ServerCredSpecificExtensionInfo::decode_from_buffer(data).map(|ext| Self { id, ext })
     67         })
     68     }
     69 }
     70 impl EncodeBuffer for ServerExtensionInfo {
     71     fn encode_into_buffer(&self, buffer: &mut Vec<u8>) {
     72         self.prf.encode_into_buffer(buffer);
     73     }
     74 }
     75 impl<'a> DecodeBuffer<'a> for ServerExtensionInfo {
     76     type Err = EncDecErr;
     77     fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> {
     78         ServerPrfInfo::decode_from_buffer(data).map(|prf| Self { prf })
     79     }
     80 }
     81 impl EncodeBuffer for SignatureCounterEnforcement {
     82     fn encode_into_buffer(&self, buffer: &mut Vec<u8>) {
     83         match *self {
     84             Self::Fail => 0u8,
     85             Self::Update => 1,
     86             Self::Ignore => 2,
     87         }
     88         .encode_into_buffer(buffer);
     89     }
     90 }
     91 impl<'a> DecodeBuffer<'a> for SignatureCounterEnforcement {
     92     type Err = EncDecErr;
     93     fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> {
     94         u8::decode_from_buffer(data).and_then(|val| match val {
     95             0 => Ok(Self::Fail),
     96             1 => Ok(Self::Update),
     97             2 => Ok(Self::Ignore),
     98             _ => Err(EncDecErr),
     99         })
    100     }
    101 }
    102 impl EncodeBufferFallible for &[CredInfo] {
    103     type Err = EncDecErr;
    104     /// # Errors
    105     ///
    106     /// Errors iff `self.len() > usize::from(u16::MAX)`.
    107     fn encode_into_buffer(&self, buffer: &mut Vec<u8>) -> Result<(), EncDecErr> {
    108         u16::try_from(self.len())
    109             .map_err(|_e| EncDecErr)
    110             .map(|len| {
    111                 len.encode_into_buffer(buffer);
    112                 self.iter().fold((), |(), val| {
    113                     val.encode_into_buffer(buffer);
    114                 });
    115             })
    116     }
    117 }
    118 impl<'a> DecodeBuffer<'a> for Vec<CredInfo> {
    119     type Err = EncDecErr;
    120     fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> {
    121         u16::decode_from_buffer(data).and_then(|len| {
    122             let l = usize::from(len);
    123             let mut creds = Self::with_capacity(l);
    124             while creds.len() < l {
    125                 creds.push(CredInfo::decode_from_buffer(data)?);
    126             }
    127             Ok(creds)
    128         })
    129     }
    130 }
    131 impl EncodeBufferFallible for AuthenticationServerState {
    132     type Err = SystemTimeError;
    133     fn encode_into_buffer(&self, buffer: &mut Vec<u8>) -> Result<(), Self::Err> {
    134         self.challenge.encode_into_buffer(buffer);
    135         self.user_verification.encode_into_buffer(buffer);
    136         self.extensions.encode_into_buffer(buffer);
    137         self.expiration.encode_into_buffer(buffer)
    138     }
    139 }
    140 impl Encode for DiscoverableAuthenticationServerState {
    141     type Output<'a>
    142         = Vec<u8>
    143     where
    144         Self: 'a;
    145     type Err = SystemTimeError;
    146     #[inline]
    147     fn encode(&self) -> Result<Self::Output<'_>, Self::Err> {
    148         // Length of the anticipated most common output:
    149         // * 16 for `SentChallenge`
    150         // * 1 for `UserVerificationRequirement`
    151         // * 1 or 3 for `ServerExtensionInfo` where we assume 1 is the most common
    152         // * 12 for `SystemTime`
    153         let mut buffer = Vec::with_capacity(16 + 1 + 1 + 12);
    154         self.0.encode_into_buffer(&mut buffer).map(|()| buffer)
    155     }
    156 }
    157 /// Error returned from [`NonDiscoverableAuthenticationServerState::encode`].
    158 #[derive(Debug)]
    159 pub enum EncodeNonDiscoverableAuthenticationServerStateErr {
    160     /// Variant returned when
    161     /// [`NonDiscoverableAuthenticationServerState::expiration`](../struct.AuthenticationServerState.html#method.expiration-1)
    162     /// is before [`UNIX_EPOCH`].
    163     SystemTime(SystemTimeError),
    164     /// Variant returned when the corresponding [`NonDiscoverableCredentialRequestOptions::allow_credentials`] has more
    165     /// than [`u16::MAX`] [`AllowedCredential`]s.
    166     AllowedCredentialsCount,
    167 }
    168 impl Display for EncodeNonDiscoverableAuthenticationServerStateErr {
    169     #[inline]
    170     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
    171         match *self {
    172             Self::SystemTime(ref err) => err.fmt(f),
    173             Self::AllowedCredentialsCount => {
    174                 f.write_str("there were more than 65,535 AllowedCredentials")
    175             }
    176         }
    177     }
    178 }
    179 impl Error for EncodeNonDiscoverableAuthenticationServerStateErr {}
    180 impl Encode for NonDiscoverableAuthenticationServerState {
    181     type Output<'a>
    182         = Vec<u8>
    183     where
    184         Self: 'a;
    185     type Err = EncodeNonDiscoverableAuthenticationServerStateErr;
    186     #[inline]
    187     fn encode(&self) -> Result<Self::Output<'_>, Self::Err> {
    188         // Length of the anticipated most common output:
    189         // * 16 for `SentChallenge`
    190         // * 2 + large range for `[CredInfo]` where we assume [`CredInfo`] being
    191         //   empty is the most common
    192         // * 1 for `UserVerificationRequirement`
    193         // * 1 or 3 for `ServerExtensionInfo` where we assume 1 is the most common
    194         // * 12 for `SystemTime`
    195         let mut buffer = Vec::with_capacity(16 + 2 + 1 + 1 + 12);
    196         self.state
    197             .encode_into_buffer(&mut buffer)
    198             .map_err(EncodeNonDiscoverableAuthenticationServerStateErr::SystemTime)
    199             .and_then(|()| {
    200                 self.allow_credentials
    201                     .as_slice()
    202                     .encode_into_buffer(&mut buffer)
    203                     .map_err(|_e| {
    204                         EncodeNonDiscoverableAuthenticationServerStateErr::AllowedCredentialsCount
    205                     })
    206                     .map(|()| buffer)
    207             })
    208     }
    209 }
    210 impl<'a> DecodeBuffer<'a> for AuthenticationServerState {
    211     type Err = EncDecErr;
    212     fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> {
    213         SentChallenge::decode_from_buffer(data).and_then(|challenge| {
    214             UserVerificationRequirement::decode_from_buffer(data).and_then(|user_verification| {
    215                 ServerExtensionInfo::decode_from_buffer(data).and_then(|extensions| {
    216                     SystemTime::decode_from_buffer(data).map(|expiration| Self {
    217                         challenge,
    218                         user_verification,
    219                         extensions,
    220                         expiration,
    221                     })
    222                 })
    223             })
    224         })
    225     }
    226 }
    227 /// Error returned from [`DiscoverableAuthenticationServerState::decode`].
    228 #[derive(Clone, Copy, Debug)]
    229 pub enum DecodeDiscoverableAuthenticationServerStateErr {
    230     /// Variant returned when there was trailing data after decoding a [`DiscoverableAuthenticationServerState`].
    231     TrailingData,
    232     /// Variant returned for all other errors.
    233     Other,
    234 }
    235 impl Display for DecodeDiscoverableAuthenticationServerStateErr {
    236     #[inline]
    237     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
    238         f.write_str(match *self {
    239             Self::TrailingData => {
    240                 "trailing data after decoding DiscoverableAuthenticationServerState"
    241             }
    242             Self::Other => "DiscoverableAuthenticationServerState could not be decoded",
    243         })
    244     }
    245 }
    246 impl Error for DecodeDiscoverableAuthenticationServerStateErr {}
    247 impl Decode for DiscoverableAuthenticationServerState {
    248     type Input<'a> = &'a [u8];
    249     type Err = DecodeDiscoverableAuthenticationServerStateErr;
    250     #[inline]
    251     fn decode(mut input: Self::Input<'_>) -> Result<Self, Self::Err> {
    252         AuthenticationServerState::decode_from_buffer(&mut input)
    253             .map_err(|_e| DecodeDiscoverableAuthenticationServerStateErr::Other)
    254             .and_then(|state| {
    255                 if input.is_empty() {
    256                     Ok(Self(state))
    257                 } else {
    258                     Err(DecodeDiscoverableAuthenticationServerStateErr::TrailingData)
    259                 }
    260             })
    261     }
    262 }
    263 /// Error returned from [`NonDiscoverableAuthenticationServerState::decode`].
    264 #[derive(Clone, Copy, Debug)]
    265 pub enum DecodeNonDiscoverableAuthenticationServerStateErr {
    266     /// Variant returned when there was trailing data after decoding a [`NonDiscoverableAuthenticationServerState`].
    267     TrailingData,
    268     /// Variant returned for all other errors.
    269     Other,
    270 }
    271 impl Display for DecodeNonDiscoverableAuthenticationServerStateErr {
    272     #[inline]
    273     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
    274         f.write_str(match *self {
    275             Self::TrailingData => {
    276                 "trailing data after decoding NonDiscoverableAuthenticationServerState"
    277             }
    278             Self::Other => "NonDiscoverableAuthenticationServerState could not be decoded",
    279         })
    280     }
    281 }
    282 impl Error for DecodeNonDiscoverableAuthenticationServerStateErr {}
    283 impl Decode for NonDiscoverableAuthenticationServerState {
    284     type Input<'a> = &'a [u8];
    285     type Err = DecodeNonDiscoverableAuthenticationServerStateErr;
    286     #[inline]
    287     fn decode(mut input: Self::Input<'_>) -> Result<Self, Self::Err> {
    288         AuthenticationServerState::decode_from_buffer(&mut input)
    289             .map_err(|_e| DecodeNonDiscoverableAuthenticationServerStateErr::Other)
    290             .and_then(|state| {
    291                 Vec::decode_from_buffer(&mut input)
    292                     .map_err(|_e| DecodeNonDiscoverableAuthenticationServerStateErr::Other)
    293                     .and_then(|allow_credentials| {
    294                         if input.is_empty() {
    295                             Ok(Self {
    296                                 state,
    297                                 allow_credentials,
    298                             })
    299                         } else {
    300                             Err(DecodeNonDiscoverableAuthenticationServerStateErr::TrailingData)
    301                         }
    302                     })
    303             })
    304     }
    305 }