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