Fix #52: QR-initiated hybrid transport support on Android#97
Conversation
935c5c4 to
6dab92f
Compare
There was a problem hiding this comment.
Pull Request Overview
This PR fixes QR‑initiated hybrid transport support on Android by addressing connection and CBOR decoding errors, improving error handling for missing PIN/UV protocols, and updating timeout values.
- Fixes HTTP 400 errors by setting the fido.cable subprotocol on WSS requests (tunnel changes).
- Updates user verification flow to allow empty PIN/UV protocol fields and adjusts pre‑flight request handling.
- Increases timeout for example usage and updates README documentation accordingly.
Reviewed Changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| libwebauthn/src/webauthn.rs | Refactored error handling and conditional pre‑flight support in various CTAP2 request flows. |
| libwebauthn/src/transport/channel.rs | Added a default supports_preflight implementation and improved timeout error logs. |
| libwebauthn/src/transport/cable/tunnel.rs | Sets the Sec‑WebSocket‑Protocol header using a modified client request. |
| libwebauthn/src/transport/cable/channel.rs | Improved error logging in send/recv and disabled pre‑flight support for CableChannel. |
| libwebauthn/src/proto/ctap2/protocol.rs | Replaced hardcoded timeout constants with function parameters for CTAP2 commands. |
| libwebauthn/src/pin.rs | Updated select_uv_proto usage to handle missing protocols gracefully. |
| libwebauthn/examples/webauthn_cable.rs | Adjusted timeout values in the example to accommodate longer operations. |
| README.md | Updated documentation to reflect revised hybrid transport support. |
| warn!(?get_info_response.pin_auth_protos, "No supported PIN/UV auth protocols found"); | ||
| None | ||
| } | ||
|
|
There was a problem hiding this comment.
[nitpick] Consider extracting the warning for unsupported PIN/UV auth protocols into a helper to avoid duplication across multiple call sites.
| warn!(?get_info_response.pin_auth_protos, "No supported PIN/UV auth protocols found"); | |
| None | |
| } | |
| log_unsupported_pin_uv_protocols(&get_info_response.pin_auth_protos); | |
| None | |
| } | |
| fn log_unsupported_pin_uv_protocols(pin_auth_protos: &Option<Vec<u8>>) { | |
| warn!(?pin_auth_protos, "No supported PIN/UV auth protocols found"); | |
| } |
| trace!(?request); | ||
| self.cbor_send(&request.into(), TIMEOUT_GET_INFO).await?; | ||
| let cbor_response = self.cbor_recv(TIMEOUT_GET_INFO).await?; | ||
| self.cbor_send(&request.into(), timeout).await?; |
There was a problem hiding this comment.
Verify that all instances of the previously hardcoded TIMEOUT_GET_INFO have been consistently updated to use the dynamic timeout parameter.
| let Some(uv_proto) = select_uv_proto(&get_info_response).await else { | ||
| error!("No supported PIN/UV auth protocols found"); | ||
| return Err(Error::Ctap(CtapError::Other)); |
There was a problem hiding this comment.
[nitpick] Double-check that the updated error handling for select_uv_proto (returning an Option) is consistent with its usage in similar code blocks across the codebase.
| let Some(uv_proto) = select_uv_proto(&get_info_response).await else { | |
| error!("No supported PIN/UV auth protocols found"); | |
| return Err(Error::Ctap(CtapError::Other)); | |
| let uv_proto = match select_uv_proto(&get_info_response).await { | |
| Some(proto) => proto, | |
| None => { | |
| error!("No supported PIN/UV auth protocols found"); | |
| return Err(Error::Ctap(CtapError::Other)); | |
| } |
msirringhaus
left a comment
There was a problem hiding this comment.
Looks good. I added one suggestion, but we can also just leave it as is.
Changes
See list of commits for individual changes.
Testing
Tested successfully with a Pixel 8 Pro running Android 15.
Creation & assertion are successful using Bitwarden on the phone.
Motivation
I was originally getting a HTTP 400 error upon connecting to Google's caBLE servers:
This was fixed by setting the
fido.cablesubprotocol on the WSS request.Then, we were failing to decode the CBOR payload received over the tunnel:
This was caused by missing fields in
CableInitialMessage, which now includes a list of features (CTAP and digital credentials) as stringsOnce added, I was getting an error for missing supported PI/UV auth protocols:
So I modified
select_uv_prototo allow empty an empty GetInfopinUvAuthProtocolsfield if no UV is required.Now, the connection would get interrupted midway through the transaction. Checking
adb logcat, I could see this is due to #95:So I rebased on top of
masterwhich includes fix #96.Then UX was encountering request timeouts, so I updated the code to support user-defined timeout values.
Finally, pre-flight requests were timing out because Android shows UI for pre-flight requests. These are not supported, as they should be silent.
As pre-flights are an optional operation, they are now skipped for Hybrid transport authenticators.