linux-credentials / linux-credentials/credentialsd

Feature Request: Support pre-computed clientDataHash (parity with Android/iOS APIs)

Open
#124 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement
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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.