Repository navigation
Fall back to the PIV management key when the admin channel truncates a generated key - #17
Merged
Merged
Conversation
…a generated key On-card RSA generation returns a 7F49 template larger than one 256-byte response. Cards that do not chain on the secured response path deliver the first 256 bytes with a plain success status and drop the rest, so the CLI parsed a partial template and failed with a raw TLV error. Detect that response and repeat the generation over plain APDUs behind a mutual PIV management key (9B) authentication, where the card does chain. Detection requires an RSA mechanism, SW 9000, exactly 256 bytes, and a leading 7F49 header declaring more, so it cannot fire for ECC or for a card that chains. Cards that return the full template are untouched. Add factory piv preperso set-mgmt-key to load the 9B value, since the profiles create the key object but never gave it one, and report 9B in factory piv preperso status. The value comes from --default-keys or PIV_MGMT_KEY, never the command line. A public-key template the CLI still cannot parse now ends in a CLI error naming the response length instead of an unhandled exception. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
scripts/test-local.sh runs lint, typecheck, the pytest matrix, the package build and the HTML docs build in python:X-slim containers, matching .github/workflows/ci.yml and docs.yml. The default pytest matrix covers every Python version the package declares, 3.10 through 3.14, which is wider than CI. Each job works on a copy of the repository that leaves .git and ignored paths behind, so nothing is written to the checkout. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Conflicts in CHANGELOG.md and tests/unit/test_redaction.py, both additive: each side appended to the same place. Every line from both sides is kept, main's entries and tests first and this branch's after them. The only line that appears once instead of twice is the Fixed heading both sides opened. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A PIV_MGMT_KEY or PIV_SCP03_* value that was not valid hex raised the hex parser's own ValueError, which quotes its input and is not a CLI error, so one mistyped digit printed the rest of the key in a traceback. Both resolvers now raise SecretInputError naming the variable, without the value and without the parser's exception chained to it. generate-key and the quickstart generate-key step report the management-key authentication as management_key_auth instead of management_key. factory piv preperso status already uses management_key for a different object (present, mechanism, value_set, sw), and one name should not carry two shapes. Document that --default-keys supplies the management key value as well, so PIV_MGMT_KEY is not read when it is given. Add a quickstart test that runs through the fallback into the certificate step against a card model that tracks the secure channel and the 9B role, so a step that does not reopen the admin channel fails. Sort the new NO_DRY_RUN entry, and say in scripts/test-local.sh that the SELinux label is the one change the script makes to the checkout. Co-Authored-By: Claude Fable 5.1 <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.
Summary
piv perso generate-keyandpiv quickstartfail withTLV value extends beyond bufferon cards whose applet does not chain responses on the secured path. RSA public-key templates are larger than one 256-byte response (270 bytes for RSA-2048), and such a card returns the first 256 bytes with SW9000and drops the rest.The CLI now detects that response and completes the generation over plain APDUs after authenticating the PIV management key (9B), where the card chains normally. Cards that already return the full template follow exactly the same path as before.
Changes
9000, exactly 256 bytes, and a leading7F49header that declares more than arrived. It cannot fire for ECC or for a card that chains.61xxhandling reassembles the template.factory piv preperso set-mgmt-key, new. Loads the 9B value over the admin channel. Refuses to overwrite a value that is set unless--replaceis given, and never creates a missing 9B object.factory piv preperso statusreports whether 9B exists and holds a value.PIV_MGMT_KEY, new environment variable (hex, 16/24/32 bytes).--default-keysalso supplies the published test value for 9B. Never read from the command line; registered with the redactor.generate-keygainsgenerate_pathandmanagement_key; the quickstartgenerate-keystep carries the same two fields. Additive.scripts/test-local.sh, separate commit: runs the CI jobs locally in Docker.Testing
Local: ruff, ruff format, mypy, 433 unit tests (86 new), Sphinx with
-W, and the package build all pass.On hardware, contact reader:
statusreported the empty 9B beforeset-mgmt-keyand a value after.PERMIT_MUTUALNot covered
🤖 Generated with Claude Code