bin.rs (31335B)
1 use super::{ 2 super::super::bin::{ 3 Decode, DecodeBuffer, EncDecErr, Encode, EncodeBuffer, EncodeBufferFallible as _, 4 }, 5 Aaguid, Attestation, AuthenticationExtensionsPrfOutputs, AuthenticatorAttachment, 6 AuthenticatorExtensionOutputMetadata, AuthenticatorExtensionOutputStaticState, Backup, 7 ClientExtensionsOutputsMetadata, ClientExtensionsOutputsStaticState, CompressedP256PubKey, 8 CompressedP384PubKey, CompressedPubKeyOwned, CredentialPropertiesOutput, 9 CredentialProtectionPolicy, DynamicState, Ed25519PubKey, FourToSixtyThree, Metadata, 10 MlDsa44PubKey, MlDsa65PubKey, MlDsa87PubKey, ResidentKeyRequirement, RsaPubKey, StaticState, 11 UncompressedP256PubKey, UncompressedP384PubKey, UncompressedPubKey, 12 }; 13 use core::{ 14 convert::Infallible, 15 error::Error, 16 fmt::{self, Display, Formatter}, 17 }; 18 use p256::{ 19 NistP256, 20 elliptic_curve::{Curve, common::typenum::ToInt as _}, 21 }; 22 use p384::NistP384; 23 impl EncodeBuffer for CredentialProtectionPolicy { 24 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) { 25 match *self { 26 Self::None => 0u8, 27 Self::UserVerificationOptional => 1, 28 Self::UserVerificationOptionalWithCredentialIdList => 2, 29 Self::UserVerificationRequired => 3, 30 } 31 .encode_into_buffer(buffer); 32 } 33 } 34 impl<'a> DecodeBuffer<'a> for CredentialProtectionPolicy { 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 => Ok(Self::UserVerificationOptional), 40 2 => Ok(Self::UserVerificationOptionalWithCredentialIdList), 41 3 => Ok(Self::UserVerificationRequired), 42 _ => Err(EncDecErr), 43 }) 44 } 45 } 46 impl EncodeBuffer for ResidentKeyRequirement { 47 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) { 48 match *self { 49 Self::Required => 0u8, 50 Self::Discouraged => 1, 51 Self::Preferred => 2, 52 } 53 .encode_into_buffer(buffer); 54 } 55 } 56 impl<'a> DecodeBuffer<'a> for ResidentKeyRequirement { 57 type Err = EncDecErr; 58 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 59 u8::decode_from_buffer(data).and_then(|val| match val { 60 0 => Ok(Self::Required), 61 1 => Ok(Self::Discouraged), 62 2 => Ok(Self::Preferred), 63 _ => Err(EncDecErr), 64 }) 65 } 66 } 67 impl EncodeBuffer for MlDsa87PubKey<&[u8]> { 68 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) { 69 // We don't rely on `[u8]::encode_into_buffer` since 70 // we always know the `slice` has length 2592; thus 71 // we want to "pretend" this is an array (i.e., don't encode the length). 72 buffer.extend_from_slice(self.0); 73 } 74 } 75 impl<'a> DecodeBuffer<'a> for MlDsa87PubKey<Box<[u8]>> { 76 type Err = EncDecErr; 77 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 78 // Only `array`s that implement `Default` implement `DecodeBuffer`; 79 // thus we must manually implement it. 80 let mut key = vec![0; 2592]; 81 data.split_at_checked(key.len()) 82 .ok_or(EncDecErr) 83 .map(|(key_slice, rem)| { 84 *data = rem; 85 key.copy_from_slice(key_slice); 86 Self(key.into_boxed_slice()) 87 }) 88 } 89 } 90 impl EncodeBuffer for MlDsa65PubKey<&[u8]> { 91 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) { 92 // We don't rely on `[u8]::encode_into_buffer` since 93 // we always know the `slice` has length 1952; thus 94 // we want to "pretend" this is an array (i.e., don't encode the length). 95 buffer.extend_from_slice(self.0); 96 } 97 } 98 impl<'a> DecodeBuffer<'a> for MlDsa65PubKey<Box<[u8]>> { 99 type Err = EncDecErr; 100 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 101 // Only `array`s that implement `Default` implement `DecodeBuffer`; 102 // thus we must manually implement it. 103 let mut key = vec![0; 1952]; 104 data.split_at_checked(key.len()) 105 .ok_or(EncDecErr) 106 .map(|(key_slice, rem)| { 107 *data = rem; 108 key.copy_from_slice(key_slice); 109 Self(key.into_boxed_slice()) 110 }) 111 } 112 } 113 impl EncodeBuffer for MlDsa44PubKey<&[u8]> { 114 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) { 115 // We don't rely on `[u8]::encode_into_buffer` since 116 // we always know the `slice` has length 1312; thus 117 // we want to "pretend" this is an array (i.e., don't encode the length). 118 buffer.extend_from_slice(self.0); 119 } 120 } 121 impl<'a> DecodeBuffer<'a> for MlDsa44PubKey<Box<[u8]>> { 122 type Err = EncDecErr; 123 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 124 // Only `array`s that implement `Default` implement `DecodeBuffer`; 125 // thus we must manually implement it. 126 let mut key = vec![0; 1312]; 127 data.split_at_checked(key.len()) 128 .ok_or(EncDecErr) 129 .map(|(key_slice, rem)| { 130 *data = rem; 131 key.copy_from_slice(key_slice); 132 Self(key.into_boxed_slice()) 133 }) 134 } 135 } 136 impl EncodeBuffer for Ed25519PubKey<&[u8]> { 137 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) { 138 // We don't rely on `[u8]::encode_into_buffer` since 139 // we always know the `slice` has length 32; thus 140 // we want to "pretend" this is an array (i.e., don't encode the length). 141 buffer.extend_from_slice(self.0); 142 } 143 } 144 impl<'a> DecodeBuffer<'a> for Ed25519PubKey<[u8; ed25519_dalek::PUBLIC_KEY_LENGTH]> { 145 type Err = EncDecErr; 146 // We don't verify `Self` is in fact "valid" (i.e., we don't call 147 // [`Self::validate`]) since that's expensive and an error will 148 // happen later during authentication anyway. Note even if we did, 149 // that wouldn't detect a public key that was altered in persistent 150 // storage in such a way that it's still valid; thus there is no 151 // benefit in performing "expensive" validation checks. 152 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 153 <[u8; ed25519_dalek::PUBLIC_KEY_LENGTH]>::decode_from_buffer(data).map(Self) 154 } 155 } 156 impl EncodeBuffer for UncompressedP256PubKey<'_> { 157 #[expect(clippy::indexing_slicing, reason = "comment justifies its correctness")] 158 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) { 159 /// Number of bytes the y-coordinate takes. 160 const Y_LEN: usize = <NistP256 as Curve>::FieldBytesSize::INT; 161 /// The index of the least significant byte of the y-coordinate. 162 const ODD_BYTE_INDEX: usize = Y_LEN - 1; 163 // We don't rely on `[u8]::encode_into_buffer` since 164 // we always know the `slice` has length 32; thus 165 // we want to "pretend" this is an array (i.e., don't encode the length). 166 buffer.extend_from_slice(self.0); 167 // `self.1.len() == 32` and `ODD_BYTE_INDEX == 31`, so indexing is fine. 168 (self.1[ODD_BYTE_INDEX] & 1 == 1).encode_into_buffer(buffer); 169 } 170 } 171 impl<'a> DecodeBuffer<'a> for CompressedP256PubKey<[u8; <NistP256 as Curve>::FieldBytesSize::INT]> { 172 type Err = EncDecErr; 173 // We don't verify `Self` is in fact "valid" (i.e., we don't call 174 // [`Self::validate`]) since that's expensive and an error will 175 // happen later during authentication anyway. Note even if we did, 176 // that wouldn't detect a public key that was altered in persistent 177 // storage in such a way that it's still valid; thus there is no 178 // benefit in performing "expensive" validation checks. 179 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 180 <[u8; <NistP256 as Curve>::FieldBytesSize::INT]>::decode_from_buffer(data) 181 .and_then(|x| bool::decode_from_buffer(data).map(|y_is_odd| Self { x, y_is_odd })) 182 } 183 } 184 impl EncodeBuffer for UncompressedP384PubKey<'_> { 185 #[expect(clippy::indexing_slicing, reason = "comment justifies its correctness")] 186 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) { 187 /// Number of bytes the y-coordinate takes. 188 const Y_LEN: usize = <NistP384 as Curve>::FieldBytesSize::INT; 189 /// The index of the least significant byte of the y-coordinate. 190 const ODD_BYTE_INDEX: usize = Y_LEN - 1; 191 // We don't rely on `[u8]::encode_into_buffer` since 192 // we always know the `slice` has length 48; thus 193 // we want to "pretend" this is an array (i.e., don't encode the length). 194 buffer.extend_from_slice(self.0); 195 // `self.1.len() == 48` and `ODD_BYTE_INDEX == 47`, so indexing is fine. 196 (self.1[ODD_BYTE_INDEX] & 1 == 1).encode_into_buffer(buffer); 197 } 198 } 199 impl<'a> DecodeBuffer<'a> for CompressedP384PubKey<[u8; <NistP384 as Curve>::FieldBytesSize::INT]> { 200 type Err = EncDecErr; 201 // We don't verify `Self` is in fact "valid" (i.e., we don't call 202 // [`Self::validate`]) since that's expensive and an error will 203 // happen later during authentication anyway. Note even if we did, 204 // that wouldn't detect a public key that was altered in persistent 205 // storage in such a way that it's still valid; thus there is no 206 // benefit in performing "expensive" validation checks. 207 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 208 // Only `array`s that implement `Default` implement `DecodeBuffer`; 209 // thus we must manually implement it. 210 let mut x = [0; <NistP384 as Curve>::FieldBytesSize::INT]; 211 data.split_at_checked(x.len()) 212 .ok_or(EncDecErr) 213 .and_then(|(x_slice, rem)| { 214 *data = rem; 215 bool::decode_from_buffer(data).map(|y_is_odd| { 216 x.copy_from_slice(x_slice); 217 Self { x, y_is_odd } 218 }) 219 }) 220 } 221 } 222 impl EncodeBuffer for RsaPubKey<&[u8]> { 223 #[expect(clippy::unreachable, reason = "we want to crash when there is a bug")] 224 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) { 225 // Max length is 2048, so this won't error. 226 self.0 227 .encode_into_buffer(buffer) 228 .unwrap_or_else(|_e| unreachable!("there is a bug in [u8]::encode_into_buffer")); 229 self.1.encode_into_buffer(buffer); 230 } 231 } 232 impl<'a> DecodeBuffer<'a> for RsaPubKey<Box<[u8]>> { 233 type Err = EncDecErr; 234 // We don't verify `Self` is in fact "valid" (i.e., we don't call 235 // [`Self::validate`]) since that's expensive and an error will 236 // happen later during authentication anyway. Note even if we did, 237 // that wouldn't detect a public key that was altered in persistent 238 // storage in such a way that it's still valid; thus there is no 239 // benefit in performing "expensive" validation checks. 240 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 241 Box::decode_from_buffer(data).and_then(|n| { 242 u32::decode_from_buffer(data) 243 .and_then(|e| Self::try_from((n, e)).map_err(|_e| EncDecErr)) 244 }) 245 } 246 } 247 impl EncodeBuffer for UncompressedPubKey<'_> { 248 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) { 249 match *self { 250 Self::MlDsa87(key) => { 251 0u8.encode_into_buffer(buffer); 252 key.encode_into_buffer(buffer); 253 } 254 Self::MlDsa65(key) => { 255 1u8.encode_into_buffer(buffer); 256 key.encode_into_buffer(buffer); 257 } 258 Self::MlDsa44(key) => { 259 2u8.encode_into_buffer(buffer); 260 key.encode_into_buffer(buffer); 261 } 262 Self::Ed25519(key) => { 263 3u8.encode_into_buffer(buffer); 264 key.encode_into_buffer(buffer); 265 } 266 Self::P256(key) => { 267 4u8.encode_into_buffer(buffer); 268 key.encode_into_buffer(buffer); 269 } 270 Self::P384(key) => { 271 5u8.encode_into_buffer(buffer); 272 key.encode_into_buffer(buffer); 273 } 274 Self::Rsa(key) => { 275 6u8.encode_into_buffer(buffer); 276 key.encode_into_buffer(buffer); 277 } 278 } 279 } 280 } 281 impl<'a> DecodeBuffer<'a> for CompressedPubKeyOwned { 282 type Err = EncDecErr; 283 // We don't verify `Self` is in fact "valid" (i.e., we don't call 284 // [`Self::validate`]) since that's expensive and an error will 285 // happen later during authentication anyway. Note even if we did, 286 // that wouldn't detect a public key that was altered in persistent 287 // storage in such a way that it's still valid; thus there is no 288 // benefit in performing "expensive" validation checks. 289 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 290 u8::decode_from_buffer(data).and_then(|val| match val { 291 0 => MlDsa87PubKey::decode_from_buffer(data).map(Self::MlDsa87), 292 1 => MlDsa65PubKey::decode_from_buffer(data).map(Self::MlDsa65), 293 2 => MlDsa44PubKey::decode_from_buffer(data).map(Self::MlDsa44), 294 3 => Ed25519PubKey::decode_from_buffer(data).map(Self::Ed25519), 295 4 => CompressedP256PubKey::decode_from_buffer(data).map(Self::P256), 296 5 => CompressedP384PubKey::decode_from_buffer(data).map(Self::P384), 297 6 => RsaPubKey::decode_from_buffer(data).map(Self::Rsa), 298 _ => Err(EncDecErr), 299 }) 300 } 301 } 302 impl EncodeBuffer for AuthenticatorExtensionOutputStaticState { 303 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) { 304 self.cred_protect.encode_into_buffer(buffer); 305 self.hmac_secret.encode_into_buffer(buffer); 306 } 307 } 308 impl<'a> DecodeBuffer<'a> for AuthenticatorExtensionOutputStaticState { 309 type Err = EncDecErr; 310 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 311 CredentialProtectionPolicy::decode_from_buffer(data).and_then(|cred_protect| { 312 Option::decode_from_buffer(data).map(|hmac_secret| Self { 313 cred_protect, 314 hmac_secret, 315 }) 316 }) 317 } 318 } 319 impl EncodeBuffer for Attestation { 320 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) { 321 match *self { 322 Self::None => 0u8, 323 Self::Surrogate => 1, 324 } 325 .encode_into_buffer(buffer); 326 } 327 } 328 impl<'a> DecodeBuffer<'a> for Attestation { 329 type Err = EncDecErr; 330 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 331 u8::decode_from_buffer(data).and_then(|val| match val { 332 0 => Ok(Self::None), 333 1 => Ok(Self::Surrogate), 334 _ => Err(EncDecErr), 335 }) 336 } 337 } 338 impl EncodeBuffer for Aaguid<'_> { 339 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) { 340 buffer.extend_from_slice(self.0); 341 } 342 } 343 /// Owned version of [`Aaguid`] that exists for [`MetadataOwned::aaguid`]. 344 #[derive(Clone, Copy, Debug, Eq, PartialEq)] 345 pub struct AaguidOwned(pub [u8; super::AAGUID_LEN]); 346 impl<'a: 'b, 'b> From<&'a AaguidOwned> for Aaguid<'b> { 347 #[inline] 348 fn from(value: &'a AaguidOwned) -> Self { 349 Self(value.0.as_slice()) 350 } 351 } 352 impl<'a> DecodeBuffer<'a> for AaguidOwned { 353 type Err = EncDecErr; 354 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 355 <[u8; super::AAGUID_LEN]>::decode_from_buffer(data).map(Self) 356 } 357 } 358 impl EncodeBuffer for FourToSixtyThree { 359 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) { 360 self.into_u8().encode_into_buffer(buffer); 361 } 362 } 363 impl EncodeBuffer for AuthenticatorExtensionOutputMetadata { 364 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) { 365 self.min_pin_length.encode_into_buffer(buffer); 366 } 367 } 368 impl<'a> DecodeBuffer<'a> for FourToSixtyThree { 369 type Err = EncDecErr; 370 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 371 u8::decode_from_buffer(data).and_then(|val| Self::from_u8(val).ok_or(EncDecErr)) 372 } 373 } 374 impl<'a> DecodeBuffer<'a> for AuthenticatorExtensionOutputMetadata { 375 type Err = EncDecErr; 376 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 377 Option::decode_from_buffer(data).map(|min_pin_length| Self { min_pin_length }) 378 } 379 } 380 impl EncodeBuffer for CredentialPropertiesOutput { 381 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) { 382 self.rk.encode_into_buffer(buffer); 383 } 384 } 385 impl<'a> DecodeBuffer<'a> for CredentialPropertiesOutput { 386 type Err = EncDecErr; 387 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 388 Option::decode_from_buffer(data).map(|rk| Self { rk }) 389 } 390 } 391 impl EncodeBuffer for AuthenticationExtensionsPrfOutputs { 392 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) { 393 self.enabled.encode_into_buffer(buffer); 394 } 395 } 396 impl<'a> DecodeBuffer<'a> for AuthenticationExtensionsPrfOutputs { 397 type Err = EncDecErr; 398 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 399 bool::decode_from_buffer(data).map(|enabled| Self { enabled }) 400 } 401 } 402 impl EncodeBuffer for ClientExtensionsOutputsMetadata { 403 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) { 404 self.cred_props.encode_into_buffer(buffer); 405 } 406 } 407 impl EncodeBuffer for ClientExtensionsOutputsStaticState { 408 fn encode_into_buffer(&self, buffer: &mut Vec<u8>) { 409 self.prf.encode_into_buffer(buffer); 410 } 411 } 412 impl<'a> DecodeBuffer<'a> for ClientExtensionsOutputsMetadata { 413 type Err = EncDecErr; 414 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 415 Option::decode_from_buffer(data).map(|cred_props| Self { cred_props }) 416 } 417 } 418 impl<'a> DecodeBuffer<'a> for ClientExtensionsOutputsStaticState { 419 type Err = EncDecErr; 420 fn decode_from_buffer(data: &mut &'a [u8]) -> Result<Self, Self::Err> { 421 Option::decode_from_buffer(data).map(|prf| Self { prf }) 422 } 423 } 424 impl Encode for Metadata<'_> { 425 type Output<'a> 426 = Vec<u8> 427 where 428 Self: 'a; 429 type Err = Infallible; 430 #[inline] 431 fn encode(&self) -> Result<Self::Output<'_>, Self::Err> { 432 // Length of the anticipated most common output: 433 // * 1 for `Attestation` 434 // * 16 for `Aaguid`. 435 // * 1 or 2 for `AuthenticatorExtensionOutputMetadata` where we assume 1 is the most common 436 // * 1–3 for `ClientExtensionsOutputsMetadata` where we assume 1 is the most common 437 // * 1 for `ResidentKeyRequirement` 438 let mut buffer = Vec::with_capacity(1 + 16 + 1 + 1 + 1); 439 self.attestation.encode_into_buffer(&mut buffer); 440 self.aaguid.encode_into_buffer(&mut buffer); 441 self.extensions.encode_into_buffer(&mut buffer); 442 self.client_extension_results 443 .encode_into_buffer(&mut buffer); 444 self.resident_key.encode_into_buffer(&mut buffer); 445 Ok(buffer) 446 } 447 } 448 /// Owned version of [`Metadata`] that exists to [`Self::decode`] the output of [`Metadata::encode`]. 449 #[derive(Clone, Copy, Debug)] 450 pub struct MetadataOwned { 451 /// [`Metadata::attestation`]. 452 pub attestation: Attestation, 453 /// [`Metadata::aaguid`]. 454 pub aaguid: AaguidOwned, 455 /// [`Metadata::extensions`]. 456 pub extensions: AuthenticatorExtensionOutputMetadata, 457 /// [`Metadata::client_extension_results`]. 458 pub client_extension_results: ClientExtensionsOutputsMetadata, 459 /// [`Metadata::resident_key`]. 460 pub resident_key: ResidentKeyRequirement, 461 } 462 impl<'a: 'b, 'b> From<&'a MetadataOwned> for Metadata<'b> { 463 #[inline] 464 fn from(value: &'a MetadataOwned) -> Self { 465 Self { 466 attestation: value.attestation, 467 aaguid: (&value.aaguid).into(), 468 extensions: value.extensions, 469 client_extension_results: value.client_extension_results, 470 resident_key: value.resident_key, 471 } 472 } 473 } 474 /// Error returned from [`MetadataOwned::decode`]. 475 #[derive(Clone, Copy, Debug, Eq, PartialEq)] 476 pub enum DecodeMetadataOwnedErr { 477 /// Variant returned when [`MetadataOwned::attestation`] could not be decoded. 478 Attestation, 479 /// Variant returned when [`MetadataOwned::aaguid`] could not be decoded. 480 Aaguid, 481 /// Variant returned when [`MetadataOwned::extensions`] could not be decoded. 482 Extensions, 483 /// Variant returned when [`MetadataOwned::client_extension_results`] could not be decoded. 484 ClientExtensionResults, 485 /// Variant returned when [`MetadataOwned::resident_key`] could not be decoded. 486 ResidentKey, 487 /// Variant returned when [`MetadataOwned`] was decoded with trailing data. 488 TrailingData, 489 } 490 impl Display for DecodeMetadataOwnedErr { 491 #[inline] 492 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 493 f.write_str(match *self { 494 Self::Attestation => "attestation could not be decoded", 495 Self::Aaguid => "aaguid could not be decoded", 496 Self::Extensions => "extensions could not be decoded", 497 Self::ClientExtensionResults => "client_extension_results could not be decoded", 498 Self::ResidentKey => "resident_key could not be decoded", 499 Self::TrailingData => "trailing data existed after decoding MetadataOwned", 500 }) 501 } 502 } 503 impl Error for DecodeMetadataOwnedErr {} 504 impl Decode for MetadataOwned { 505 type Input<'a> = &'a [u8]; 506 type Err = DecodeMetadataOwnedErr; 507 #[inline] 508 fn decode(mut input: Self::Input<'_>) -> Result<Self, Self::Err> { 509 Attestation::decode_from_buffer(&mut input) 510 .map_err(|_e| DecodeMetadataOwnedErr::Attestation) 511 .and_then(|attestation| { 512 AaguidOwned::decode_from_buffer(&mut input) 513 .map_err(|_e| DecodeMetadataOwnedErr::Aaguid) 514 .and_then(|aaguid| { 515 AuthenticatorExtensionOutputMetadata::decode_from_buffer(&mut input) 516 .map_err(|_e| DecodeMetadataOwnedErr::Extensions) 517 .and_then(|extensions| { 518 ClientExtensionsOutputsMetadata::decode_from_buffer(&mut input) 519 .map_err(|_e| DecodeMetadataOwnedErr::ClientExtensionResults) 520 .and_then(|client_extension_results| { 521 ResidentKeyRequirement::decode_from_buffer(&mut input) 522 .map_err(|_e| DecodeMetadataOwnedErr::ResidentKey) 523 .and_then(|resident_key| { 524 if input.is_empty() { 525 Ok(Self { 526 attestation, 527 aaguid, 528 extensions, 529 client_extension_results, 530 resident_key, 531 }) 532 } else { 533 Err(DecodeMetadataOwnedErr::TrailingData) 534 } 535 }) 536 }) 537 }) 538 }) 539 }) 540 } 541 } 542 impl Encode for StaticState<UncompressedPubKey<'_>> { 543 type Output<'a> 544 = Vec<u8> 545 where 546 Self: 'a; 547 type Err = Infallible; 548 /// Transforms `self` into a `Vec` that can subsequently be [`StaticState::decode`]d into a [`StaticState`] of 549 /// [`CompressedPubKeyOwned`]. 550 #[expect( 551 clippy::arithmetic_side_effects, 552 reason = "comment justifies its correctness" 553 )] 554 #[inline] 555 fn encode(&self) -> Result<Self::Output<'_>, Self::Err> { 556 let mut buffer = Vec::with_capacity( 557 // The maximum value is 2593 so overflow cannot happen. 558 // `key.0.len() <= MAX_RSA_N_BYTES` which is 2048. 559 match self.credential_public_key { 560 UncompressedPubKey::MlDsa87(_) => 2593, 561 UncompressedPubKey::MlDsa65(_) => 1953, 562 UncompressedPubKey::MlDsa44(_) => 1313, 563 UncompressedPubKey::Ed25519(_) => 33, 564 UncompressedPubKey::P256(_) => 34, 565 UncompressedPubKey::P384(_) => 50, 566 UncompressedPubKey::Rsa(key) => 1 + 2 + key.0.len() + 4, 567 } + 1 568 + 1 569 + usize::from(self.extensions.hmac_secret.is_some()) 570 + 1 571 + usize::from(self.client_extension_results.prf.is_some()), 572 ); 573 self.credential_public_key.encode_into_buffer(&mut buffer); 574 self.extensions.encode_into_buffer(&mut buffer); 575 self.client_extension_results 576 .encode_into_buffer(&mut buffer); 577 Ok(buffer) 578 } 579 } 580 /// Error returned from [`StaticState::decode`]. 581 #[derive(Clone, Copy, Debug, Eq, PartialEq)] 582 pub enum DecodeStaticStateErr { 583 /// Variant returned when [`StaticState::credential_public_key`] could not be decoded. 584 CredentialPublicKey, 585 /// Variant returned when [`StaticState::extensions`] could not be decoded. 586 Extensions, 587 /// Variant returned when [`StaticState::client_extension_results`] could not be decoded. 588 ClientExtensionResults, 589 /// Variant returned when there was trailing data after decoding a [`StaticState`]. 590 TrailingData, 591 } 592 impl Display for DecodeStaticStateErr { 593 #[inline] 594 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 595 f.write_str(match *self { 596 Self::CredentialPublicKey => "credential_public_key could not be decoded", 597 Self::Extensions => "extensions could not be decoded", 598 Self::ClientExtensionResults => "client_extension_results could not be decoded", 599 Self::TrailingData => "there was trailing data after decoding a StaticState", 600 }) 601 } 602 } 603 impl Error for DecodeStaticStateErr {} 604 impl Decode for StaticState<CompressedPubKeyOwned> { 605 type Input<'a> = &'a [u8]; 606 type Err = DecodeStaticStateErr; 607 /// Interprets `input` as the [`StaticState::Output`] of [`StaticState::encode`]. 608 #[inline] 609 fn decode(mut input: Self::Input<'_>) -> Result<Self, Self::Err> { 610 CompressedPubKeyOwned::decode_from_buffer(&mut input) 611 .map_err(|_e| DecodeStaticStateErr::CredentialPublicKey) 612 .and_then(|credential_public_key| { 613 AuthenticatorExtensionOutputStaticState::decode_from_buffer(&mut input) 614 .map_err(|_e| DecodeStaticStateErr::Extensions) 615 .and_then(|extensions| { 616 ClientExtensionsOutputsStaticState::decode_from_buffer(&mut input) 617 .map_err(|_e| DecodeStaticStateErr::ClientExtensionResults) 618 .and_then(|client_extension_results| { 619 if input.is_empty() { 620 Ok(Self { 621 credential_public_key, 622 extensions, 623 client_extension_results, 624 }) 625 } else { 626 Err(DecodeStaticStateErr::TrailingData) 627 } 628 }) 629 }) 630 }) 631 } 632 } 633 impl Encode for DynamicState { 634 type Output<'a> 635 = [u8; 7] 636 where 637 Self: 'a; 638 type Err = Infallible; 639 #[expect( 640 clippy::little_endian_bytes, 641 reason = "need cross-platform correctness" 642 )] 643 #[inline] 644 fn encode(&self) -> Result<Self::Output<'_>, Self::Err> { 645 let mut buffer = [ 646 u8::from(self.user_verified), 647 match self.backup { 648 Backup::NotEligible => 0, 649 Backup::Eligible => 1, 650 Backup::Exists => 2, 651 }, 652 0, 653 0, 654 0, 655 0, 656 match self.authenticator_attachment { 657 AuthenticatorAttachment::None => 0, 658 AuthenticatorAttachment::Platform => 1, 659 AuthenticatorAttachment::CrossPlatform => 2, 660 }, 661 ]; 662 buffer[2..6].copy_from_slice(self.sign_count.to_le_bytes().as_slice()); 663 Ok(buffer) 664 } 665 } 666 /// Error returned from [`DynamicState::decode`]. 667 #[derive(Clone, Copy, Debug, Eq, PartialEq)] 668 pub enum DecodeDynamicStateErr { 669 /// Variant returned when [`DynamicState::user_verified`] could not be decoded. 670 UserVerified, 671 /// Variant returned when [`DynamicState::backup`] could not be decoded. 672 Backup, 673 /// Variant returned when [`DynamicState::sign_count`] could not be decoded. 674 SignCount, 675 /// Variant returned when [`DynamicState::authenticator_attachment`] could not be decoded. 676 AuthenticatorAttachment, 677 } 678 impl Display for DecodeDynamicStateErr { 679 #[inline] 680 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 681 f.write_str(match *self { 682 Self::UserVerified => "user_verified could not be decoded", 683 Self::Backup => "backup could not be decoded", 684 Self::SignCount => "sign_count could not be decoded", 685 Self::AuthenticatorAttachment => "authenticator_attachment could not be decoded", 686 }) 687 } 688 } 689 impl Error for DecodeDynamicStateErr {} 690 impl Decode for DynamicState { 691 type Input<'a> = [u8; 7]; 692 type Err = DecodeDynamicStateErr; 693 #[expect( 694 clippy::panic_in_result_fn, 695 reason = "want to crash when there is a bug" 696 )] 697 #[inline] 698 fn decode(input: Self::Input<'_>) -> Result<Self, Self::Err> { 699 let mut buffer = input.as_slice(); 700 bool::decode_from_buffer(&mut buffer) 701 .map_err(|_e| DecodeDynamicStateErr::UserVerified) 702 .and_then(|user_verified| { 703 Backup::decode_from_buffer(&mut buffer) 704 .map_err(|_e| DecodeDynamicStateErr::Backup) 705 .and_then(|backup| { 706 u32::decode_from_buffer(&mut buffer) 707 .map_err(|_e| DecodeDynamicStateErr::SignCount) 708 .and_then(|sign_count| { 709 AuthenticatorAttachment::decode_from_buffer(&mut buffer) 710 .map_err(|_e| DecodeDynamicStateErr::AuthenticatorAttachment) 711 .map(|authenticator_attachment| { 712 assert!( 713 buffer.is_empty(), 714 "there is a bug in DynamicState::decode" 715 ); 716 Self { 717 user_verified, 718 backup, 719 sign_count, 720 authenticator_attachment, 721 } 722 }) 723 }) 724 }) 725 }) 726 } 727 }