ser_server_state.rs (9319B)
1 #![expect( 2 clippy::question_mark_used, 3 clippy::unseparated_literal_suffix, 4 reason = "noisy, opinionated, and likely doesn't prevent bugs or improve APIs" 5 )] 6 use super::{ 7 super::super::bin::{ 8 Decode, DecodeBuffer, EncDecErr, Encode, EncodeBuffer, EncodeBufferFallible, 9 }, 10 AuthenticationServerState, CredInfo, CredentialId, ExtensionReq, SentChallenge, 11 ServerCredSpecificExtensionInfo, ServerExtensionInfo, ServerPrfInfo, 12 SignatureCounterEnforcement, UserVerificationRequirement, 13 }; 14 #[cfg(doc)] 15 use super::{AllowedCredential, PublicKeyCredentialRequestOptions}; 16 use core::{ 17 error::Error, 18 fmt::{self, Display, Formatter}, 19 }; 20 #[cfg(doc)] 21 use std::time::UNIX_EPOCH; 22 use std::time::{SystemTime, SystemTimeError}; 23 impl EncodeBuffer for ServerPrfInfo { 24 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) { 25 match *self { 26 Self::One(req) => { 27 0u8.encode_into_buffer(buffer); 28 req 29 } 30 Self::Two(req) => { 31 1u8.encode_into_buffer(buffer); 32 req 33 } 34 } 35 .encode_into_buffer(buffer); 36 } 37 } 38 impl<'a> DecodeBuffer<'a> for ServerPrfInfo { 39 type Err = EncDecErr; 40 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 41 u8::decode_from_buffer(data).and_then(|val| match val { 42 0 => ExtensionReq::decode_from_buffer(data).map(Self::One), 43 1 => ExtensionReq::decode_from_buffer(data).map(Self::Two), 44 _ => Err(EncDecErr), 45 }) 46 } 47 } 48 impl EncodeBuffer for ServerCredSpecificExtensionInfo { 49 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) { 50 self.prf.encode_into_buffer(buffer); 51 } 52 } 53 impl<'a> DecodeBuffer<'a> for ServerCredSpecificExtensionInfo { 54 type Err = EncDecErr; 55 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 56 Option::decode_from_buffer(data).map(|prf| Self { prf }) 57 } 58 } 59 impl EncodeBuffer for CredInfo { 60 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) { 61 CredentialId::<&[u8]>::from(&self.id).encode_into_buffer(buffer); 62 self.ext.encode_into_buffer(buffer); 63 } 64 } 65 impl<'a> DecodeBuffer<'a> for CredInfo { 66 type Err = EncDecErr; 67 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 68 CredentialId::<Vec<u8>>::decode_from_buffer(data).and_then(|id| { 69 ServerCredSpecificExtensionInfo::decode_from_buffer(data).map(|ext| Self { id, ext }) 70 }) 71 } 72 } 73 impl EncodeBuffer for ServerExtensionInfo { 74 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) { 75 self.prf.encode_into_buffer(buffer); 76 } 77 } 78 impl<'a> DecodeBuffer<'a> for ServerExtensionInfo { 79 type Err = EncDecErr; 80 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 81 Option::decode_from_buffer(data).map(|prf| Self { prf }) 82 } 83 } 84 impl EncodeBuffer for SignatureCounterEnforcement { 85 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) { 86 match *self { 87 Self::Fail => 0u8, 88 Self::Update => 1, 89 Self::Ignore => 2, 90 } 91 .encode_into_buffer(buffer); 92 } 93 } 94 impl<'a> DecodeBuffer<'a> for SignatureCounterEnforcement { 95 type Err = EncDecErr; 96 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 97 u8::decode_from_buffer(data).and_then(|val| match val { 98 0 => Ok(Self::Fail), 99 1 => Ok(Self::Update), 100 2 => Ok(Self::Ignore), 101 _ => Err(EncDecErr), 102 }) 103 } 104 } 105 impl EncodeBufferFallible for &[CredInfo] { 106 type Err = EncDecErr; 107 /// # Errors 108 /// 109 /// Errors iff `self.len() > usize::from(u16::MAX)`. 110 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) -> Result<(), EncDecErr> { 111 u16::try_from(self.len()) 112 .map_err(|_e| EncDecErr) 113 .map(|len| { 114 len.encode_into_buffer(buffer); 115 self.iter().fold((), |(), val| { 116 val.encode_into_buffer(buffer); 117 }); 118 }) 119 } 120 } 121 impl<'a> DecodeBuffer<'a> for Vec<CredInfo> { 122 type Err = EncDecErr; 123 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 124 u16::decode_from_buffer(data).and_then(|len| { 125 let l = usize::from(len); 126 let mut creds = Self::with_capacity(l); 127 while creds.len() < l { 128 creds.push(CredInfo::decode_from_buffer(data)?); 129 } 130 Ok(creds) 131 }) 132 } 133 } 134 /// Error returned from [`AuthenticationServerState::encode`]. 135 #[derive(Debug)] 136 pub enum EncodeAuthenticationServerStateErr { 137 /// Variant returned when 138 /// [`AuthenticationServerState::expiration`](../struct.AuthenticationServerState.html#method.expiration-1) 139 /// is before [`UNIX_EPOCH`]. 140 SystemTime(SystemTimeError), 141 /// Variant returned when the corresponding [`PublicKeyCredentialRequestOptions::allow_credentials`] has more 142 /// than [`u16::MAX`] [`AllowedCredential`]s. 143 AllowedCredentialsCount, 144 } 145 impl Display for EncodeAuthenticationServerStateErr { 146 #[inline] 147 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 148 match *self { 149 Self::SystemTime(ref err) => err.fmt(f), 150 Self::AllowedCredentialsCount => { 151 f.write_str("there were more than 65,535 AllowedCredentials") 152 } 153 } 154 } 155 } 156 impl Error for EncodeAuthenticationServerStateErr {} 157 impl Encode for AuthenticationServerState { 158 type Output<'a> = Vec<u8> where Self: 'a; 159 type Err = EncodeAuthenticationServerStateErr; 160 #[inline] 161 fn encode(&self) -> Result<Self::Output<'_>, Self::Err> { 162 // Length of the anticipated most common output: 163 // * 16 for `SentChallenge` 164 // * 2 + large range for `[CredInfo]` where we assume [`CredInfo`] being 165 // empty is the most common 166 // * 1 for `UserVerificationRequirement` 167 // * 1 or 3 for `ServerExtensionInfo` where we assume 1 is the most common 168 // * 12 for `SystemTime` 169 let mut buffer = Vec::with_capacity(16 + 2 + 1 + 1 + 12); 170 self.challenge.encode_into_buffer(&mut buffer); 171 self.allow_credentials 172 .as_slice() 173 .encode_into_buffer(&mut buffer) 174 .map_err(|_e| EncodeAuthenticationServerStateErr::AllowedCredentialsCount) 175 .and_then(|()| { 176 self.user_verification.encode_into_buffer(&mut buffer); 177 self.extensions.encode_into_buffer(&mut buffer); 178 self.expiration 179 .encode_into_buffer(&mut buffer) 180 .map_err(EncodeAuthenticationServerStateErr::SystemTime) 181 .map(|()| buffer) 182 }) 183 } 184 } 185 /// Error returned from [`AuthenticationServerState::decode`]. 186 #[derive(Clone, Copy, Debug)] 187 pub enum DecodeAuthenticationServerStateErr { 188 /// Variant returned when there was trailing data after decoding an [`AuthenticationServerState`]. 189 TrailingData, 190 /// Variant returned for all other errors. 191 Other, 192 } 193 impl Display for DecodeAuthenticationServerStateErr { 194 #[inline] 195 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 196 f.write_str(match *self { 197 Self::TrailingData => "trailing data after decoding AuthenticationServerState", 198 Self::Other => "AuthenticationServerState could not be decoded", 199 }) 200 } 201 } 202 impl Error for DecodeAuthenticationServerStateErr {} 203 impl Decode for AuthenticationServerState { 204 type Input<'a> = &'a [u8]; 205 type Err = DecodeAuthenticationServerStateErr; 206 #[inline] 207 fn decode(mut input: Self::Input<'_>) -> Result<Self, Self::Err> { 208 SentChallenge::decode_from_buffer(&mut input).map_err(|_e| DecodeAuthenticationServerStateErr::Other).and_then(|challenge| { 209 Vec::decode_from_buffer(&mut input).map_err(|_e| DecodeAuthenticationServerStateErr::Other).and_then(|allow_credentials| { 210 UserVerificationRequirement::decode_from_buffer(&mut input).map_err(|_e| DecodeAuthenticationServerStateErr::Other).and_then(|user_verification| { 211 ServerExtensionInfo::decode_from_buffer(&mut input).map_err(|_e| DecodeAuthenticationServerStateErr::Other).and_then(|extensions| { 212 super::validate_options_helper(extensions, user_verification, &allow_credentials).map_err(|_e| DecodeAuthenticationServerStateErr::Other).and_then(|()| { 213 SystemTime::decode_from_buffer(&mut input).map_err(|_e| DecodeAuthenticationServerStateErr::Other).and_then(|expiration| { 214 if input.is_empty() { 215 Ok(Self { 216 challenge, 217 allow_credentials, 218 user_verification, 219 extensions, 220 expiration, 221 }) 222 } else { 223 Err(DecodeAuthenticationServerStateErr::TrailingData) 224 } 225 }) 226 }) 227 }) 228 }) 229 }) 230 }) 231 } 232 }