linux-credentials / linux-credentials/credentialsd
Feature Request: Support pre-computed clientDataHash (parity with Android/iOS APIs)
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 259
- Forks
- 19
- Avg merge
- 1d 2h
- Merged PRs (30d)
- 12
Description
### Summary
Add support for accepting a pre-computed `clientDataHash` (SHA-256) as an alternative to `clientDataJSON` in the D-Bus API. This aligns with Android and iOS platform APIs, and enables a wider range of WebAuthn integration scenarios.
### Background
The CTAP2 specification defines that authenticator operations (`authenticatorMakeCredential` and `authenticatorGetAssertion`) accept a **hash** of the client data, not the raw JSON:
> **hash (0x01)**: Hash of the serialized client data, provided by the client.
Reference: [FIDO CTAP2 Specification §6.1](https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-20210615.html#authenticatorMakeCredential)
While browser-based WebAuthn flows typically construct `clientDataJSON` locally, there are several scenarios where the caller may already have the hash:
1. **Cross-device authentication (CTAP2 Hybrid/caBLE)** - The initiating device may provide the hash directly
2. **Native application integrations** - Apps may negotiate client data with their backend
3. **Remote desktop/VDI scenarios** - The remote server constructs clientData and transmits only the hash
4. **Proxy/relay architectures** - Intermediate systems may only forward the hash
### Prior Art - Platform API Parity
Both Android and iOS platform APIs support this pattern:
#### Android (Credential Manager API)
```kotlin
val request = GetPublicKeyCredentialOption(
requestJson = "...",
clientDataHash = clientDataHashBytes // Optional pre-computed hash
)
```
Reference: [Android Credential Manager Documentation](https://developer.android.com/identity/sign-in/credential-manager)
#### iOS (ASAuthorizationPublicKeyCredentialProvider)
```swift
let request = provider.createCredentialAssertionRequest(challenge: challenge)
request.clientDataHash = clientDataHash // Supports pre-computed hash
```
Reference: [Apple Developer Documentation](https://developer.apple.com/documentation/authenticationservices/asauthorizationpublickeycredentialprovider)
Adding this support to credentialsd would bring Linux to **feature parity** with these platforms.
### Proposed API Change
Add an optional `client_data_hash` parameter to the D-Bus methods:
#### Option A: New optional parameter (backward compatible)
```xml
```
Behavior:
- If `client_data_hash` is provided (non-empty), use it directly
- If `client_data_hash` is empty, compute hash from `request_json.clientDataJSON` (current behavior)
#### Option B: Separate methods
```xml
```
### Use Case
This feature enables various integration scenarios where the caller has a pre-computed hash rather than raw JSON:
- **Cross-device flows** where another device initiated the WebAuthn ceremony
- **Native applications** with custom client data handling
- **Remote desktop environments** where authentication is redirected to the local machine
- **Enterprise SSO integrations** with proxy architectures
The key benefit is **flexibility** - allowing callers to provide either the raw JSON (current behavior) or a pre-computed hash when that's what they have available.
### Security Considerations
This change maintains the same security model:
- The authenticator still requires user interaction (touch/PIN)
- The UI still displays the relying party information
- The cryptographic signature is still bound to the hash
The only difference is **who computes the hash** - the caller vs the credential service.
### Implementation Notes
Looking at `libwebauthn`, the underlying `register()` and `sign()` functions may already work with the hash internally. The change would primarily be in:
1. D-Bus interface definition (`xyz.iinuwa.credentials.xml`)
2. Request parsing in `credentialsd`
3. Passing the hash through to libwebauthn
### Related
- [W3C WebAuthn Level 3 §5.8.1](https://w3c.github.io/webauthn/#client-data-hash) - client data hash computation
- [FIDO CTAP2 Specification](https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-20210615.html) - authenticator protocol
- Android and iOS platform APIs (referenced above)
### Questions
1. Would you prefer Option A (optional parameter) or Option B (new method)?
2. Are there any security considerations I might have missed?
3. Is this something you're planning to implement, or would you be open to accepting a community contribution? I'd be happy to work on a PR if that would be helpful.
Thank you for considering this feature request!
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the D-Bus interface definition in xyz.iinuwa.credentials.xml and the request parsing in credentialsd. Then inspect libwebauthn's register() and sign() functions to determine whether they accept a client data hash. Done means choosing and implementing a compatible API shape, forwarding the hash correctly, preserving the existing JSON behavior, and covering both paths with tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- api, security
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100