Skip to content

PresenceRequired status not received immediately when using USB #38

@iinuwa

Description

@iinuwa

We would like to show a notification for users to perform the user presence gesture (e.g. touch the button) on USB devices so that there's a visual indication on the screen of what to do next. (The device itself should be in "wink" mode, but having it on screen would be helpful.)

We have code in libwebauthn that emits this, seemingly at the right time, according to logs, but the credential service doesn't receive it until about 20 seconds later. This seems to be some timeout issue/race condition.

See logs (omitted credential ID for brevity):

Starting...
Starting credential service...   ✅
Starting GUI thread...   ✅
Starting D-Bus service... ✅
Waiting for messages...
2025-06-05T17:48:01.197050Z  INFO xyz_iinuwa_credential_manager_portal_gtk::application: Credential Manager (xyz.iinuwa.CredentialManagerUi.Devel)
2025-06-05T17:48:01.197079Z  INFO xyz_iinuwa_credential_manager_portal_gtk::application: Version: 0.1.0-90c2dd3 (Devel)
2025-06-05T17:48:01.197085Z  INFO xyz_iinuwa_credential_manager_portal_gtk::application: Datadir: /home/isaiah/Development/rust/linux-webauthn-platform-api/build/xyz-iinuwa-credential-manager-portal-gtk/data/resources
2025-06-05T17:48:01.198326Z DEBUG xyz_iinuwa_credential_manager_portal_gtk::application::imp: GtkApplication<ExampleApplication>::startup
2025-06-05T17:48:01.323066Z DEBUG xyz_iinuwa_credential_manager_portal_gtk::application::imp: GtkApplication<ExampleApplication>::activate
Device { id: "0", transport: Usb }
Selected device 0
2025-06-05T17:48:03.279785Z DEBUG xyz_iinuwa_credential_manager_portal_gtk::credential_service::usb: polling for USB status
2025-06-05T17:48:03.279828Z DEBUG xyz_iinuwa_credential_manager_portal_gtk::credential_service::usb: current usb state: Idle
2025-06-05T17:48:03.286309Z DEBUG xyz_iinuwa_credential_manager_portal_gtk::credential_service::usb: current usb state: Connected(HidDevice { backend: HidApiDevice(HidDeviceInfo { vendor_id: 4617, product_id: 48878 }) })
2025-06-05T17:48:03.286404Z  INFO xyz_iinuwa_credential_manager_portal_gtk::view_model: Found USB device
2025-06-05T17:48:03.350957Z DEBUG webauthn_get_assertion{dev=SoloKeys Solo 2 Security Key (r964)}:_negotiate_protocol: libwebauthn::webauthn: Selected protocol: FIDO2
2025-06-05T17:48:03.390799Z  INFO webauthn_get_assertion{dev=SoloKeys Solo 2 Security Key (r964)}: libwebauthn::proto::ctap2::preflight: Credential list BEFORE preflight: [Ctap2PublicKeyCredentialDescriptor { id: [...], type: PublicKey, transports: None }]
2025-06-05T17:48:03.582448Z DEBUG webauthn_get_assertion{dev=SoloKeys Solo 2 Security Key (r964)}: libwebauthn::proto::ctap2::preflight: Pre-flight: Found already known credential Ctap2PublicKeyCredentialDescriptor { id: [...], type: PublicKey, transports: None }
2025-06-05T17:48:03.582534Z  INFO webauthn_get_assertion{dev=SoloKeys Solo 2 Security Key (r964)}: libwebauthn::proto::ctap2::preflight: Credential list AFTER preflight: [Ctap2PublicKeyCredentialDescriptor { id: [...], type: PublicKey, transports: None }]
2025-06-05T17:48:03.638575Z DEBUG webauthn_get_assertion{dev=SoloKeys Solo 2 Security Key (r964)}:user_verification:user_verification_helper: libwebauthn::webauthn: Checking if user verification is required rp_uv_preferred=true dev_uv_protected=true uv=true
2025-06-05T17:48:03.650791Z DEBUG webauthn_get_assertion{dev=SoloKeys Solo 2 Security Key (r964)}:user_verification:user_verification_helper: libwebauthn::transport::channel: Sending state update: PinRequired(PinRequiredUpdate { reply_to: Sender { inner: Some(Inner { state: State { is_complete: false, is_closed: false, is_rx_task_set: false, is_tx_task_set: false } }) }, reason: RelyingPartyRequest, attempts_left: Some(8) })
2025-06-05T17:48:03.651118Z DEBUG xyz_iinuwa_credential_manager_portal_gtk::credential_service::usb: current usb state: NeedsPin { attempts_left: Some(8), pin_tx: Sender { chan: Tx { inner: Chan { tx: Tx { block_tail: 0x7fffac00ea70, tail_position: 0 }, semaphore: Semaphore { semaphore: Semaphore { permits: 1 }, bound: 1 }, rx_waker: AtomicWaker, tx_count: 2, rx_fields: "..." } } } }

# I type in my PIN here and immediately get the below line

2025-06-05T17:48:06.207109Z DEBUG webauthn_get_assertion{dev=SoloKeys Solo 2 Security Key (r964)}: libwebauthn::transport::channel: Sending state update: PresenceRequired

# Even though libwebauthn sends the data, the cred service doesn't see it, and so the GUI doesn't update. Notably, the device IS winking, and if I push it, the cred service skips to the Completed state and releases the credential properly

# 30 seconds pass, and it retries the operation

2025-06-05T17:48:36.499156Z  WARN xyz_iinuwa_credential_manager_portal_gtk::credential_service::usb: Retrying WebAuthn get credential operation
2025-06-05T17:48:36.499223Z DEBUG webauthn_get_assertion{dev=SoloKeys Solo 2 Security Key (r964)}:_negotiate_protocol: libwebauthn::webauthn: Selected protocol: FIDO2
2025-06-05T17:48:36.526780Z  INFO webauthn_get_assertion{dev=SoloKeys Solo 2 Security Key (r964)}: libwebauthn::proto::ctap2::preflight: Credential list BEFORE preflight: [Ctap2PublicKeyCredentialDescriptor { id: [...], type: PublicKey, transports: None }]
2025-06-05T17:48:36.723123Z DEBUG webauthn_get_assertion{dev=SoloKeys Solo 2 Security Key (r964)}: libwebauthn::proto::ctap2::preflight: Pre-flight: Found already known credential Ctap2PublicKeyCredentialDescriptor { id: [...], type: PublicKey, transports: None }
2025-06-05T17:48:36.723248Z  INFO webauthn_get_assertion{dev=SoloKeys Solo 2 Security Key (r964)}: libwebauthn::proto::ctap2::preflight: Credential list AFTER preflight: [Ctap2PublicKeyCredentialDescriptor { id: [...], type: PublicKey, transports: None }]

# Device is still in winking for user presence state, so we skip the PIN this time.
# PresenceRequired emitted again from libwebauthn below.

2025-06-05T17:48:36.753117Z DEBUG webauthn_get_assertion{dev=SoloKeys Solo 2 Security Key (r964)}: libwebauthn::transport::channel: Sending state update: PresenceRequired
2025-06-05T17:48:36.753297Z DEBUG xyz_iinuwa_credential_manager_portal_gtk::credential_service::usb: current usb state: NeedsUserPresence

# ^ now the cred service and GUI see the NeedsUserPresence state
# I got distracted and waited a while to push the button, so the delay between the above line and the one below is not important

2025-06-05T17:48:45.492149Z DEBUG xyz_iinuwa_credential_manager_portal_gtk::credential_service::usb: USB update channel closed.
2025-06-05T17:48:45.492201Z DEBUG xyz_iinuwa_credential_manager_portal_gtk::credential_service::usb: Reached end of USB update task

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions