diff --git a/xyz-iinuwa-credential-manager-portal-gtk/Cargo.lock b/xyz-iinuwa-credential-manager-portal-gtk/Cargo.lock index e705ff3e..522af907 100644 --- a/xyz-iinuwa-credential-manager-portal-gtk/Cargo.lock +++ b/xyz-iinuwa-credential-manager-portal-gtk/Cargo.lock @@ -1928,7 +1928,7 @@ dependencies = [ [[package]] name = "libwebauthn" version = "0.1.2" -source = "git+https://github.com/linux-credentials/libwebauthn?rev=21995110e729cb83f3cd5ff3ece4c42315fe8bd3#21995110e729cb83f3cd5ff3ece4c42315fe8bd3" +source = "git+https://github.com/linux-credentials/libwebauthn?rev=e73c76b5826801907340396b0fd9bd7dfb0f5760#e73c76b5826801907340396b0fd9bd7dfb0f5760" dependencies = [ "aes", "async-trait", diff --git a/xyz-iinuwa-credential-manager-portal-gtk/Cargo.toml b/xyz-iinuwa-credential-manager-portal-gtk/Cargo.toml index 9d452fc0..aafff1e3 100644 --- a/xyz-iinuwa-credential-manager-portal-gtk/Cargo.toml +++ b/xyz-iinuwa-credential-manager-portal-gtk/Cargo.toml @@ -20,7 +20,7 @@ serde_json = "1.0.140" tracing = "0.1.41" tracing-subscriber = "0.3" zbus = { version = "5.5.0", default-features = false, features = ["blocking-api", "tokio"] } -libwebauthn = { git = "https://github.com/linux-credentials/libwebauthn", rev = "21995110e729cb83f3cd5ff3ece4c42315fe8bd3" } +libwebauthn = { git = "https://github.com/linux-credentials/libwebauthn", rev = "e73c76b5826801907340396b0fd9bd7dfb0f5760" } async-trait = "0.1.88" tokio = { version = "1.45.0", features = ["rt-multi-thread"] } futures-lite = "2.6.0" diff --git a/xyz-iinuwa-credential-manager-portal-gtk/src/dbus.rs b/xyz-iinuwa-credential-manager-portal-gtk/src/dbus.rs index f6ae8a85..539d2a6d 100644 --- a/xyz-iinuwa-credential-manager-portal-gtk/src/dbus.rs +++ b/xyz-iinuwa-credential-manager-portal-gtk/src/dbus.rs @@ -9,7 +9,7 @@ use libwebauthn::ops::webauthn::{ Assertion, CredentialProtectionExtension, GetAssertionHmacOrPrfInput, GetAssertionLargeBlobExtension, GetAssertionRequest, GetAssertionRequestExtensions, MakeCredentialHmacOrPrfInput, MakeCredentialRequest, MakeCredentialResponse, - MakeCredentialsRequestExtensions, UserVerificationRequirement, + MakeCredentialsRequestExtensions, ResidentKeyRequirement, UserVerificationRequirement, }; use libwebauthn::proto::ctap2::{ Ctap2PublicKeyCredentialDescriptor, Ctap2PublicKeyCredentialRpEntity, @@ -351,30 +351,34 @@ impl CreateCredentialRequest { let other_options = serde_json::from_str::(&request_value.to_string()) .map_err(|_| webauthn::Error::Internal("Invalid request JSON".to_string()))?; - let (require_resident_key, user_verification) = if let Some(authenticator_selection) = - other_options.authenticator_selection - { - let is_authenticator_storage_capable = true; - let require_resident_key = authenticator_selection - .resident_key - .map(|r| r == "required" || (r == "preferred" && is_authenticator_storage_capable)) - .or(authenticator_selection.require_resident_key) // fallback to authenticator_selection.require_resident_key == true for WebAuthn Level 1 - .unwrap_or_default(); - - let user_verification = authenticator_selection - .user_verification - .map(|uv| match uv.as_ref() { - "required" => UserVerificationRequirement::Required, - "preferred" => UserVerificationRequirement::Preferred, - "discouraged" => UserVerificationRequirement::Discouraged, - _ => todo!("This should be fixed in the future"), - }) - .unwrap_or(UserVerificationRequirement::Preferred); - - (require_resident_key, user_verification) - } else { - (false, UserVerificationRequirement::Preferred) - }; + let (resident_key, user_verification) = + if let Some(authenticator_selection) = other_options.authenticator_selection { + let resident_key = match authenticator_selection.resident_key.as_deref() { + Some("required") => Some(ResidentKeyRequirement::Required), + Some("preferred") => Some(ResidentKeyRequirement::Preferred), + Some("discouraged") => Some(ResidentKeyRequirement::Discouraged), + Some(_) => None, + // legacy webauthn-1 member + None if authenticator_selection.require_resident_key == Some(true) => { + Some(ResidentKeyRequirement::Required) + } + None => None, + }; + + let user_verification = authenticator_selection + .user_verification + .map(|uv| match uv.as_ref() { + "required" => UserVerificationRequirement::Required, + "preferred" => UserVerificationRequirement::Preferred, + "discouraged" => UserVerificationRequirement::Discouraged, + _ => todo!("This should be fixed in the future"), + }) + .unwrap_or(UserVerificationRequirement::Preferred); + + (resident_key, user_verification) + } else { + (None, UserVerificationRequirement::Preferred) + }; let extensions = if let Some(incoming_extensions) = other_options.extensions { let extensions = MakeCredentialsRequestExtensions { cred_props: incoming_extensions.cred_props, @@ -465,7 +469,7 @@ impl CreateCredentialRequest { relying_party: rp, user, - require_resident_key, + resident_key, user_verification, algorithms, exclude, diff --git a/xyz-iinuwa-credential-manager-portal-gtk/src/webauthn.rs b/xyz-iinuwa-credential-manager-portal-gtk/src/webauthn.rs index 7a3eff7f..89d568df 100644 --- a/xyz-iinuwa-credential-manager-portal-gtk/src/webauthn.rs +++ b/xyz-iinuwa-credential-manager-portal-gtk/src/webauthn.rs @@ -10,7 +10,7 @@ use libwebauthn::{ }; use serde::{Deserialize, Serialize}; use serde_json::json; -use tracing::{debug, error}; +use tracing::debug; use crate::cose::{CoseKeyAlgorithmIdentifier, CoseKeyType}; @@ -363,16 +363,10 @@ impl TryFrom<&Ctap2AttestationStatement> for AttestationStatement { .collect(), }) } - Ctap2AttestationStatement::FidoU2F(att_stmt) => { - if att_stmt.certificates.len() != 1 { - error!("fido-u2f attestation statement has to have one certificate, but we received {}!", att_stmt.certificates.len()); - return Err(Error::InvalidState); - } - Ok(Self::U2F { - signature: att_stmt.signature.as_ref().to_vec(), - certificate: att_stmt.certificates[0].to_vec(), - }) - } + Ctap2AttestationStatement::FidoU2F(att_stmt) => Ok(Self::U2F { + signature: att_stmt.signature.as_ref().to_vec(), + certificate: att_stmt.certificate.to_vec(), + }), _ => { debug!("Unsupported attestation type: {:?}", value); Err(Error::NotSupported)