ser_server_state.rs (14098B)
1 use super::{ 2 super::super::bin::{ 3 Decode, DecodeBuffer, EncDecErr, Encode, EncodeBuffer, EncodeBufferFallible as _, 4 }, 5 AuthenticatorAttachmentReq, AuthenticatorSelectionCriteria, CoseAlgorithmIdentifiers, 6 CredProtect, CredentialMediationRequirement, CrossPlatformHint, ExtensionInfo, Hint, 7 PlatformHint, RegistrationServerState, ResidentKeyRequirement, SentChallenge, 8 ServerExtensionInfo, ServerPrfInfo, UserHandle, UserVerificationRequirement, 9 }; 10 use core::{ 11 error::Error, 12 fmt::{self, Display, Formatter}, 13 }; 14 use std::time::{SystemTime, SystemTimeError}; 15 impl EncodeBuffer for CoseAlgorithmIdentifiers { 16 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) { 17 self.0.encode_into_buffer(buffer); 18 } 19 } 20 impl<'a> DecodeBuffer<'a> for CoseAlgorithmIdentifiers { 21 type Err = EncDecErr; 22 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 23 u8::decode_from_buffer(data).and_then(|val| { 24 if val | Self::ALL.0 == Self::ALL.0 { 25 Ok(Self(val)) 26 } else { 27 Err(EncDecErr) 28 } 29 }) 30 } 31 } 32 impl EncodeBuffer for PlatformHint { 33 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) { 34 match *self { 35 Self::None => 0u8, 36 Self::ClientDevice => 1, 37 } 38 .encode_into_buffer(buffer); 39 } 40 } 41 impl<'a> DecodeBuffer<'a> for PlatformHint { 42 type Err = EncDecErr; 43 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 44 u8::decode_from_buffer(data).and_then(|val| match val { 45 0 => Ok(Self::None), 46 1 => Ok(Self::ClientDevice), 47 _ => Err(EncDecErr), 48 }) 49 } 50 } 51 impl EncodeBuffer for CrossPlatformHint { 52 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) { 53 match *self { 54 Self::None => 0u8, 55 Self::SecurityKey => 1, 56 Self::Hybrid => 2, 57 Self::SecurityKeyHybrid => 3, 58 Self::HybridSecurityKey => 4, 59 } 60 .encode_into_buffer(buffer); 61 } 62 } 63 impl<'a> DecodeBuffer<'a> for CrossPlatformHint { 64 type Err = EncDecErr; 65 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 66 u8::decode_from_buffer(data).and_then(|val| match val { 67 0 => Ok(Self::None), 68 1 => Ok(Self::SecurityKey), 69 2 => Ok(Self::Hybrid), 70 3 => Ok(Self::SecurityKeyHybrid), 71 4 => Ok(Self::HybridSecurityKey), 72 _ => Err(EncDecErr), 73 }) 74 } 75 } 76 impl EncodeBuffer for AuthenticatorAttachmentReq { 77 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) { 78 match *self { 79 Self::None(hint) => { 80 0u8.encode_into_buffer(buffer); 81 hint.encode_into_buffer(buffer); 82 } 83 Self::Platform(hint) => { 84 1u8.encode_into_buffer(buffer); 85 hint.encode_into_buffer(buffer); 86 } 87 Self::CrossPlatform(hint) => { 88 2u8.encode_into_buffer(buffer); 89 hint.encode_into_buffer(buffer); 90 } 91 } 92 } 93 } 94 impl<'a> DecodeBuffer<'a> for AuthenticatorAttachmentReq { 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 => Hint::decode_from_buffer(data).map(Self::None), 99 1 => PlatformHint::decode_from_buffer(data).map(Self::Platform), 100 2 => CrossPlatformHint::decode_from_buffer(data).map(Self::CrossPlatform), 101 _ => Err(EncDecErr), 102 }) 103 } 104 } 105 impl EncodeBuffer for AuthenticatorSelectionCriteria { 106 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) { 107 self.authenticator_attachment.encode_into_buffer(buffer); 108 self.resident_key.encode_into_buffer(buffer); 109 self.user_verification.encode_into_buffer(buffer); 110 } 111 } 112 impl<'a> DecodeBuffer<'a> for AuthenticatorSelectionCriteria { 113 type Err = EncDecErr; 114 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 115 AuthenticatorAttachmentReq::decode_from_buffer(data).and_then(|authenticator_attachment| { 116 ResidentKeyRequirement::decode_from_buffer(data).and_then(|resident_key| { 117 UserVerificationRequirement::decode_from_buffer(data).map(|user_verification| { 118 Self { 119 authenticator_attachment, 120 resident_key, 121 user_verification, 122 } 123 }) 124 }) 125 }) 126 } 127 } 128 impl EncodeBuffer for CredProtect { 129 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) { 130 match *self { 131 Self::None => 0u8.encode_into_buffer(buffer), 132 Self::UserVerificationOptional(enforce, info) => { 133 1u8.encode_into_buffer(buffer); 134 enforce.encode_into_buffer(buffer); 135 info.encode_into_buffer(buffer); 136 } 137 Self::UserVerificationOptionalWithCredentialIdList(enforce, info) => { 138 2u8.encode_into_buffer(buffer); 139 enforce.encode_into_buffer(buffer); 140 info.encode_into_buffer(buffer); 141 } 142 Self::UserVerificationRequired(enforce, info) => { 143 3u8.encode_into_buffer(buffer); 144 enforce.encode_into_buffer(buffer); 145 info.encode_into_buffer(buffer); 146 } 147 } 148 } 149 } 150 impl<'a> DecodeBuffer<'a> for CredProtect { 151 type Err = EncDecErr; 152 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 153 u8::decode_from_buffer(data).and_then(|val| match val { 154 0 => Ok(Self::None), 155 1 => bool::decode_from_buffer(data).and_then(|enforce| { 156 ExtensionInfo::decode_from_buffer(data) 157 .map(|info| Self::UserVerificationOptional(enforce, info)) 158 }), 159 2 => bool::decode_from_buffer(data).and_then(|enforce| { 160 ExtensionInfo::decode_from_buffer(data) 161 .map(|info| Self::UserVerificationOptionalWithCredentialIdList(enforce, info)) 162 }), 163 3 => bool::decode_from_buffer(data).and_then(|enforce| { 164 ExtensionInfo::decode_from_buffer(data) 165 .map(|info| Self::UserVerificationRequired(enforce, info)) 166 }), 167 _ => Err(EncDecErr), 168 }) 169 } 170 } 171 impl EncodeBuffer for ServerPrfInfo { 172 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) { 173 match *self { 174 Self::None => 0u8.encode_into_buffer(buffer), 175 Self::One(info) => { 176 1u8.encode_into_buffer(buffer); 177 info.encode_into_buffer(buffer); 178 } 179 Self::Two(info) => { 180 2u8.encode_into_buffer(buffer); 181 info.encode_into_buffer(buffer); 182 } 183 } 184 } 185 } 186 impl<'a> DecodeBuffer<'a> for ServerPrfInfo { 187 type Err = EncDecErr; 188 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 189 u8::decode_from_buffer(data).and_then(|val| match val { 190 0 => Ok(Self::None), 191 1 => ExtensionInfo::decode_from_buffer(data).map(Self::One), 192 2 => ExtensionInfo::decode_from_buffer(data).map(Self::Two), 193 _ => Err(EncDecErr), 194 }) 195 } 196 } 197 impl EncodeBuffer for ServerExtensionInfo { 198 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) { 199 self.cred_props.encode_into_buffer(buffer); 200 self.cred_protect.encode_into_buffer(buffer); 201 self.min_pin_length.encode_into_buffer(buffer); 202 self.prf.encode_into_buffer(buffer); 203 } 204 } 205 impl<'a> DecodeBuffer<'a> for ServerExtensionInfo { 206 type Err = EncDecErr; 207 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 208 Option::decode_from_buffer(data).and_then(|cred_props| { 209 CredProtect::decode_from_buffer(data).and_then(|cred_protect| { 210 Option::decode_from_buffer(data).and_then(|min_pin_length| { 211 ServerPrfInfo::decode_from_buffer(data).map(|prf| Self { 212 cred_props, 213 cred_protect, 214 min_pin_length, 215 prf, 216 }) 217 }) 218 }) 219 }) 220 } 221 } 222 impl<const LEN: usize> EncodeBuffer for UserHandle<LEN> { 223 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) { 224 buffer.extend_from_slice(self.0.as_slice()); 225 } 226 } 227 impl<'a, const LEN: usize> DecodeBuffer<'a> for UserHandle<LEN> 228 where 229 Self: Default, 230 { 231 type Err = EncDecErr; 232 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 233 data.split_at_checked(LEN) 234 .ok_or(EncDecErr) 235 .map(|(val_slice, rem)| { 236 *data = rem; 237 let mut val = Self::default(); 238 val.0.copy_from_slice(val_slice); 239 val 240 }) 241 } 242 } 243 impl<const USER_LEN: usize> Encode for RegistrationServerState<USER_LEN> { 244 type Output<'a> 245 = Vec<u8> 246 where 247 Self: 'a; 248 type Err = SystemTimeError; 249 #[expect( 250 clippy::arithmetic_side_effects, 251 reason = "comment justifies correctness" 252 )] 253 #[inline] 254 fn encode(&self) -> Result<Self::Output<'_>, Self::Err> { 255 // Length of the anticipated most common output: 256 // * 1 for `CredentialMediationRequirement` 257 // * 16 for `SentChallenge` 258 // * 1 for `CoseAlgorithmIdentifiers` 259 // * 4 for `AuthenticatorSelectionCriteria` 260 // * 4–10 for `Extension` 261 // * 12 for `SystemTime` 262 // * 1–64 for `UserHandle<USER_LEN>` 263 // Overflow cannot occur since `self.user_id` has max length of 64. 264 let mut buffer = Vec::with_capacity( 265 1 + 16 266 + 1 267 + 4 268 + (1 + usize::from(self.extensions.cred_props.is_some()) 269 + if matches!(self.extensions.cred_protect, CredProtect::None) { 270 1 271 } else { 272 3 273 } 274 + if self.extensions.min_pin_length.is_none() { 275 1 276 } else { 277 3 278 } 279 + 1 280 + usize::from(!matches!(self.extensions.prf, ServerPrfInfo::None))) 281 + 12 282 + self.user_id.0.len(), 283 ); 284 self.mediation.encode_into_buffer(&mut buffer); 285 self.challenge.encode_into_buffer(&mut buffer); 286 self.pub_key_cred_params.encode_into_buffer(&mut buffer); 287 self.authenticator_selection.encode_into_buffer(&mut buffer); 288 self.extensions.encode_into_buffer(&mut buffer); 289 self.expiration.encode_into_buffer(&mut buffer).map(|()| { 290 self.user_id.encode_into_buffer(&mut buffer); 291 buffer 292 }) 293 } 294 } 295 /// Error returned from [`RegistrationServerState::decode`]. 296 #[derive(Clone, Copy, Debug, Eq, PartialEq)] 297 pub enum DecodeRegistrationServerStateErr { 298 /// Variant returned when there was trailing data after decoding a [`RegistrationServerState`]. 299 TrailingData, 300 /// Variant returned for all other errors. 301 Other, 302 } 303 impl Display for DecodeRegistrationServerStateErr { 304 #[inline] 305 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 306 f.write_str(match *self { 307 Self::TrailingData => "trailing data existed after decoding a RegistrationServerState", 308 Self::Other => "RegistrationServerState could not be decoded", 309 }) 310 } 311 } 312 impl Error for DecodeRegistrationServerStateErr {} 313 impl<const USER_LEN: usize> Decode for RegistrationServerState<USER_LEN> 314 where 315 UserHandle<USER_LEN>: Default, 316 { 317 type Input<'a> = &'a [u8]; 318 type Err = DecodeRegistrationServerStateErr; 319 #[inline] 320 fn decode(mut input: Self::Input<'_>) -> Result<Self, Self::Err> { 321 CredentialMediationRequirement::decode_from_buffer(&mut input).map_err(|_e| DecodeRegistrationServerStateErr::Other).and_then(|mediation| { 322 SentChallenge::decode_from_buffer(&mut input).map_err(|_e| DecodeRegistrationServerStateErr::Other).and_then(|challenge| { 323 CoseAlgorithmIdentifiers::decode_from_buffer(&mut input).map_err(|_e| DecodeRegistrationServerStateErr::Other).and_then(|pub_key_cred_params| { 324 AuthenticatorSelectionCriteria::decode_from_buffer(&mut input).map_err(|_e| DecodeRegistrationServerStateErr::Other).and_then( 325 |authenticator_selection| { 326 ServerExtensionInfo::decode_from_buffer(&mut input).map_err(|_e| DecodeRegistrationServerStateErr::Other).and_then(|extensions| { 327 super::validate_options_helper(authenticator_selection, extensions) 328 .map_err(|_e| DecodeRegistrationServerStateErr::Other) 329 .and_then(|()| { 330 SystemTime::decode_from_buffer(&mut input).map_err(|_e| DecodeRegistrationServerStateErr::Other).and_then(|expiration| { 331 UserHandle::decode_from_buffer(&mut input).map_err(|_e| DecodeRegistrationServerStateErr::Other).and_then(|user_id| { 332 if input.is_empty() { 333 Ok(Self { mediation, challenge, pub_key_cred_params, authenticator_selection, extensions, expiration, user_id, }) 334 } else { 335 Err(DecodeRegistrationServerStateErr::TrailingData) 336 } 337 }) 338 }) 339 }) 340 }) 341 }, 342 ) 343 }) 344 }) 345 }) 346 } 347 }