From 3edba7bdaba897c70a473aeaae79270582d5fc79 Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Sat, 22 Jun 2024 13:43:32 +0200 Subject: [PATCH] Support attestation in get_assertion --- src/ctap2.rs | 42 ++++++++++++++++++++++++++++++++++++++++++ src/state.rs | 2 ++ 2 files changed, 44 insertions(+) diff --git a/src/ctap2.rs b/src/ctap2.rs index a6423bf..bc447bf 100644 --- a/src/ctap2.rs +++ b/src/ctap2.rs @@ -1063,6 +1063,7 @@ impl Authenticator for crate::Authenti up_performed, multiple_credentials, extensions: parameters.extensions.clone(), + attestation_formats_preference: parameters.attestation_formats_preference.clone(), }); let num_credentials = match num_credentials { @@ -1677,6 +1678,46 @@ impl crate::Authenticator { .to_bytes() .unwrap(); + let att_stmt_fmt = + SupportedAttestationFormat::select(data.attestation_formats_preference.as_ref()); + let att_stmt = if let Some(format) = att_stmt_fmt { + match format { + SupportedAttestationFormat::None => { + Some(AttestationStatement::None(NoneAttestationStatement {})) + } + SupportedAttestationFormat::Packed => { + let (attestation_maybe, _) = self.state.identity.attestation(&mut self.trussed); + let (signature, attestation_algorithm) = { + if let Some(attestation) = attestation_maybe.as_ref() { + let signature = syscall!(self.trussed.sign_p256( + attestation.0, + &commitment, + SignatureSerialization::Asn1Der, + )) + .signature; + (signature.to_bytes().map_err(|_| Error::Other)?, -7) + } else { + (signature.clone(), credential.algorithm()) + } + }; + let packed = PackedAttestationStatement { + alg: attestation_algorithm, + sig: signature, + x5c: attestation_maybe.as_ref().map(|attestation| { + // See: https://www.w3.org/TR/webauthn-2/#sctn-packed-attestation-cert-requirements + let cert = attestation.1.clone(); + let mut x5c = Vec::new(); + x5c.push(cert).ok(); + x5c + }), + }; + Some(AttestationStatement::Packed(packed)) + } + } + } else { + None + }; + if !is_rk { syscall!(self.trussed.delete(key)); } @@ -1688,6 +1729,7 @@ impl crate::Authenticator { } .build(); response.number_of_credentials = num_credentials; + response.att_stmt = att_stmt; // User with empty IDs are ignored for compatibility if is_rk { diff --git a/src/state.rs b/src/state.rs index 88cdf77..f0fe6a6 100644 --- a/src/state.rs +++ b/src/state.rs @@ -3,6 +3,7 @@ //! Needs cleanup. use ctap_types::{ + ctap2::AttestationFormatsPreference, // 2022-02-27: 10 credentials sizes::MAX_CREDENTIAL_COUNT_IN_LIST, // U8 currently Error, @@ -216,6 +217,7 @@ pub struct ActiveGetAssertionData { pub up_performed: bool, pub multiple_credentials: bool, pub extensions: Option, + pub attestation_formats_preference: Option, } #[derive(Debug, Default)]