Added
-
piv self-signandpiv request-certcan generate the key first.
--generate-keyfolds a freshgenerate-keyinto the signing command,
with the same--algorithm,--pin-policyand--touch-policyoptions,
so cards without GET METADATA no longer need the--save-pubkey/
--load-pubkeydetour. Contributed by @episource. (#116) -
The activity log now covers PIV. User actions and background reads
are told apart, and with tracing on each APDU appears by name (for example
GET DATA 5FC105) with the same redaction as--debug. The log can be
detached into its own window and cleared. Contributed by @episource.
(#114) -
OpenPGP keys in modern algorithms.
openpgp generate-key --algorithm
(and the GUI's Generate dialog) can set a slot to Ed25519, X25519, NIST
P-256/384/521, secp256k1, brainpool 256/384/512, or RSA 2048/3072/4096
before generating; previously a slot could only ever produce its factory
default (RSA-2048). The menu comes from the card's own algorithm list
(openpgp algorithms, new) when it publishes one.sign/authenticate
frame input correctly for ECC slots,decryptperforms ECDH on an ECDH
slot, andstatusnames the curve. Verified on a YubiKey 5.7. Requested
by @mdedonno1337. (#106) -
OTP codes on a Token2 key can be put behind a PIN. Keys running the
R3.4 OTP applet can require a PIN before they hand out codes:otp set-pinprotects a key,otp verifyopens the read window,
otp change-pin/otp remove-pinmanage it,otp pin-statusreports
whether one is set and how many attempts remain, andlist/add/
deletetake--pin-envor--pin-stdinto unlock in passing (the
PIN is never an argument). The GUI's OTP pane grows an unlock prompt, a
set/change/remove dialog and a "Lock now" action. The PIN travels
encrypted under a per-connection ECDH session and is never sent in the
clear. Two things to know before setting one: there is no reset — an
exhausted retry counter is recoverable only by erasing every OTP entry
on the key — and keyroost does not verify the device's P-521 agreement
signature, so over NFC an attacker who runs the key agreement can take
one verify blob away and brute-force a numeric PIN offline without
touching the retry counter. Keys without the feature are unaffected:
they answer the capability probe with "no such command" and everything
behaves exactly as before. Contributed by @token2. (#107)
Changed
-
APDU errors now say what the status word means. A failure like
SW=6A80carries the ISO 7816 meaning in parentheses ("incorrect
parameters in the command data field") when the word is a standard one;
unrecognised words stay bare rather than guessed at. Applies to every
applet's errors, CLI and GUI. Contributed by @episource. (#118) -
Library API (
keyroost-openpgp,keyroost-transport):PublicKeyis now
an enum (Rsa/Ecc),OpenPgpSession::generate_keytakes an optional
algorithm,rsa_v4_fingerprint_fromis replaced byv4_fingerprint, and
OpenPgpStatuscarries each slot's raw algorithm attributes. The CLI's
openpgp status(and its--json*_algofields) now report
RSA-2048/EdDSA Ed25519rather than the bare family name.
TransportErrorgains two new variants —OpenPgpSlotMismatch(a
requested algorithm that can't live in the requested slot) and
OpenPgpSlotNotRsa(an RSA-only operation, i.e. key import, run against a
slot that holds an ECC key) — so an exhaustive match overTransportError
needs new arms. -
Library API (
keyroost-token2otp):EncryptErrorgainsBadLength,
BadCiphertextandBadAuthTag, andOtpErrorgains
PinInvalidRetries; inkeyroost-transport,OtpTransportErrorgains
PinRequiredandPinSessionMissing. An exhaustivematchover any of
them needs new arms. -
Library API (
keyroost-piv):parse_versionis removed; the version is
now kept as raw bytes and rendered withformat_version_bytes(#110). -
Public error enums and status structs are
#[non_exhaustive]. Adding
a variant or a field to them is no longer a breaking change for library
users; a one-time_ =>arm is needed in exhaustive matches.
Fixed
-
The PIV pane's refresh no longer re-reads the same card objects. It
gathered each slot's key algorithm, certificate Subject DN and PIN/touch
policy through separate transport calls, so every slot's certificate was
fetched two or three times and GET METADATA twice. A new
PivSession::status_detailedreads each slot's certificate object and
GET METADATA exactly once and shares them across all three, roughly
halving the refresh's APDU traffic. A slot whose certificate object
carries no70TLV now reports as empty rather than "cert present",
matching whatpiv export-certalready reported for it.cert_lenin
piv status(and--json) now reports the certificate's DER length
rather than the card's object size, so it is a few bytes smaller than
before. Contributed by @episource. (#119) -
Library users enabling
keyroost-transport'shidapi-backendfeature on
its own no longer hit a compile error inkeyroost-ctap: the feature now
forwards to every crate that has a matching backend switch, not just
keyroost-hid. CI builds every feature at once and never saw the partial
combination;cargo semver-checksdoes, and did. -
Certificate import and signing now work on contact (T=0) smart-card
readers. Large PIV commands were sent as extended-length APDUs first,
with chaining only as a fallback after the card refused. A T=0 link cannot
carry extended-length APDUs at all, and a Token2 PIN+ card on such a reader
went silent instead of refusing — so the fallback never triggered and the
command failed with a PC/SC "transaction failed" error. keyroost now reads
the negotiated protocol and chains from the start on T=0; T=1 links are
unchanged. Reported by @mdedonno1337, who also confirmed the chained path
works on the affected card. (#103) -
The PIV slot tabs wrap instead of overflowing in a narrow window.
Contributed by @episource. (#114) -
PIV cards that answer GET VERSION with more than three bytes can now be
managed. The Swissbit iShield Key 2 Pro replies to the Yubico version
extension with four bytes; keyroost rejected the reply and with it the
card. The version is now kept as the card sent it and shown as-is (dotted
for up to four bytes, hex beyond), and the firmware checks that gate
YubiKey-specific behaviour compare the leading bytes exactly as before.
Contributed by @episource. (#110) -
Identiv uTrust FIDO2 PIV cards can now be managed. Their PIV applet
answers management-key authentication without the final card-to-host
proof, which keyroost treated as a failure. A card that accepts the
host's proof but sends none of its own is now accepted; every card that
does send its proof is verified exactly as before. The reduced assurance
on such cards is reported in--debugoutput. Contributed by @episource.
(#104)
Full changelog: https://github.com/framefilter/keyroost/blob/v0.9.0/CHANGELOG.md