Support Identiv uTrust FIDO2's PIV applet by tolerating cards not fully implementing mutual GENERAL AUTHENTICATE - #104
Open
episource wants to merge 1 commit into
Conversation
`PivSession::authenticate_management`'s step 2 (GENERAL AUTHENTICATE with the decrypted witness plus our own challenge) unconditionally parsed the response as a `7C` dynamic-auth template to pull out the card's encrypted echo of our challenge (`0x82`), the half of mutual auth that lets the host verify the card. On an Identiv uTrust FIDO2 Security Key, that step answers `SW_OK` with an empty body instead — the card verifies our witness (a wrong one is still rejected with a non-success status, unchanged) but never implements sending the challenge back. `parse_general_auth` then failed on the empty buffer with "PIV response is not a 0x7C dynamic-auth template", which surfaced as a hard error before every management-key-gated command (`generate-key`, `import-cert`, `set-management-key`, ...) ever got to run. Treat an empty, `SW_OK` step-2 response as a completed (one-directional) authentication rather than a parse error: our witness was still checked, so a wrong key is still caught here — this card just can't prove itself back to us, and there's no `0x82` template to wait for. Same category of device quirk as the existing Nitrokey stub-`GET METADATA` and empty-`53` cert-object handling in this file. This maps directly onto the two authentication modes NIST SP 800-73 describes for the management key over GENERAL AUTHENTICATE: "client (application) authentication" — only the client proves possession of the key to the card — versus "mutual authentication", which adds the card proving itself back to the client. Client auth is the half that actually gates PIV admin operations (it's what authorizes *us* to write to the card), so it's sufficient on its own — which is exactly what this fallback now accepts. Deliberately not switching the step-2 *request* itself to the leaner, client-auth-only shape (dropping our `0x81` challenge tag) to match: the mutual-shaped request is a strict superset with no extra cost — cards that only implement client auth answer exactly as observed here regardless, and cards that implement the full round (this crate's hardware-verified Token2/Yubico-compatible targets) give us the extra assurance, before writing new key material, that the `SW_OK` we got back came from something that actually holds the key rather than a card that blindly answers success. Trimming the request would only pay off against a card that hard-rejects the mutual shape outright (non-`9000` SW) rather than short-answering it as Identiv does here — no such device has been observed, and Token2/Yubico-compatible firmware may well expect the full shape, so narrowing the request now would trade a working, hardware- verified path for an unvalidated one. Revisit only against a real device that fails the mutual-shaped request, per a targeted fallback in the same style as `general_auth_sign_chained`. Co-Authored-By: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The Identiv/Hirsch uTrust FIDO2 token doesn't implement full mutual GENERAL AUTHENTICATE for the card's management key: instead of the expected challenge template, it returns an empty response with a success status word. Since none of the PIV operations implemented here require anything beyond client authentication — card authentication is optional — this PR changes management key authentication to tolerate this and proceed silently. This PR does not switch to plain client authentication, but adjusts as little code as possible to support this very specific token.