Repository navigation
Resolve the mgmt-key algorithm by probing - #124
framefilter merged 3 commits into
Conversation
Cards that don't answer GET METADATA (pre-5.3 YubiKey firmware, non-Yubico PIV applets) left us assuming Triple-DES for the 9B management key. That is wrong for any such card provisioned with an AES management key: GENERAL AUTHENTICATE is then issued under the wrong P1 and the card rejects it. Resolve the algorithm instead of guessing: - GET METADATA still wins outright when the card answers it. - Otherwise probe every algorithm's GENERAL AUTHENTICATE P1 with a bare witness request (step 1 only -- no key-derived material reaches the card) and collect the ones the card starts with SW 9000. Narrow that set to the algorithms whose key matches the length in hand; if more than one remains (only 3DES and AES-192 collide, both 24 bytes) prefer 3DES, the historical default. If the card accepted no probe at all, fall back to the key length alone -- no worse than before. A real transport failure during probing propagates as itself; only a non-9000 status word means "not this P1, try the next". New: PivSession::reported_management_key_algorithm (metadata answer with no fallback) and resolve_management_key_algorithm. The 9 GUI PIV admin flows and the CLI's open_piv_authed now call the resolver; the CLI keeps its tailored wrong-length message for the metadata-present case. PivBadKeyLength's message is broadened to cover "matches no algorithm this card accepts". The length->candidates table and the probe-result selection are pure functions (mgmt_algs_for_key_len, pick_mgmt_alg) with unit tests; the probe loop itself needs a live card, consistent with the rest of this module.
|
Cryptnox OpenFIPS201 variant uses AES management as default, but does not implement yubico extension command |
…the CLI probe path The CLI wrapper around the management-key algorithm probe mapped every error from the resolver to the "does not match any algorithm this card accepts" message. The transport layer takes care to propagate a mid-probe transport failure (card pulled, reader gone) as itself; the wrapper undid that. Only PivBadKeyLength now gets the friendly wording. The comment above it also said the probe ran only for 24-byte keys, which is not what the resolver does. Maintainer-side fixup for framefilter#124. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XpyGDFxYw5DSD97HXBAc2q
…amefilter#124) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XpyGDFxYw5DSD97HXBAc2q
|
Thanks @episource, this closes a known gap. Two questions:
I pushed two commits on top of yours: 1dd8bbb narrows the CLI's map_err to PivBadKeyLength so a transport failure mid-probe isn't reported as a wrong-length key, and corrects the comment above it; 8003c34 adds the changelog fragment. Let me know if there's anything that doesn't meet your intent, happy to revisit. |
|
Thanks for catching cli's error handling being to broad. I've indeed tested management auth with a Cryptnox PIV card. The vendor claims this card uses plain OpenFIPS201 v2 as certified per Nist CMVP #5280. I bought this card for OpenFIPS201 v2 testing. I've only done management key Also consider, the default cryptnox-id (pre) perso sequence does not initialize the slot 9B management key object. The cryptnox-id's default way is SCP03 admin commands only, not the PIV standard For my tests I've used below cryptnox profile. It's derived from |
* release: 0.10.0 — version bump, changelog, and release-doc updates Section 2 of packaging/RELEASING.md, on a prep branch for review. - Workspace version 0.9.0 -> 0.10.0 across the workspace field and all 54 inter-crate path-dep pins; Cargo.lock regenerated. semver-checks confirms 0.10.0 is the correct (required) bump: one break, keyroost-token2otp's PinFlag gained a field and is not #[non_exhaustive]. - CHANGELOG: assembled the five queued changelog.d fragments into ## [0.10.0] - 2026-09-20 — nix flake (#109), PIV slot self-test (#127), Token2 OTP fingerprint unlock (#130), PIV mgmt-key algorithm probe (#124), OTP PIN-material trace redaction (#131). metainfo derives cleanly. - migration.html: documented that one library break. - Semantic doc audit (every doc file, no sampling) fixes: README crate table (+keyroost-pivtest), PIV bullet (+ the piv test self-test), OTP bullet (+ fingerprint unlock); an otp.html fingerprint-unlock section; SECURITY.md scoped-deps (+ p384 / ed25519-dalek / x25519-dalek, confined to keyroost-pivtest); TODO.md current-work header; RELEASING.md library-crate count 16 -> 17. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XpyGDFxYw5DSD97HXBAc2q * token2otp: seal PinFlag with #[non_exhaustive] while it's already breaking PinFlag gained an fp_enable field this release (#130), which was a breaking change because the struct was not #[non_exhaustive] — unlike the other response types that were sealed in 0.9.0. Since 0.10.0 already breaks PinFlag, sealing it in the same release means consumers absorb one break instead of two: after this, later firmware flags can be added as fields without breaking anyone. Only same-crate construction (parse()) uses a struct literal, and #[non_exhaustive] does not restrict that, so nothing in the workspace changes. Migration note and changelog updated. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XpyGDFxYw5DSD97HXBAc2q --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Currently keyroost uses the management key algorithm reported by
GET METADATA. This is a yubico extension APDU. For cards not supporting this extension, 3-DES was used unconditionally. This PR adds probing ifGET METADATAis not implemented by the card/token.