kkeyroost

Reference · Migration

Migration notes

Breaking changes by release, with the exact before → after for scripts and library consumers. Newest first; each release's notes link back here.

v0.9.0

Nothing changes for scripts beyond three output details, listed first. The version jump is again about the published library crates: the OpenPGP applet learned ECC keys and the Token2 OTP applet learned PINs, and both reshaped public types.

CLI output details

Library (crates.io) API changes

CrateChange
keyroost-openpgp PublicKey is an enum — Rsa { modulus, exponent } or Ecc { point }; match on it instead of reading fields. rsa_v4_fingerprint_from is gone: use v4_fingerprint(&key, &attrs, time), which routes by the slot's parsed algorithm attributes.
keyroost-transport OpenPgpSession::generate_key(crt, alg) takes an Option<KeyAlg> — pass None for the old behaviour. OpenPgpStatus gained sig_attrs / dec_attrs / aut_attrs (struct literals must set them). TransportError gained OpenPgpSlotMismatch and OpenPgpSlotNotRsa; OtpTransportError gained PinRequired and PinSessionMissing — exhaustive matches need arms.
keyroost-token2otp EncryptError gained BadLength, BadCiphertext and BadAuthTag; OtpError gained PinInvalidRetries.
keyroost-piv parse_version is removed; PivStatus keeps the GET VERSION reply as raw bytes and format_version_bytes renders it, so cards that answer with more or fewer than three bytes work.
all library crates The public error enums and status structs are now #[non_exhaustive] — an exhaustive match needs a _ => arm and struct literals of status types are no longer possible outside their crate. From now on adding a variant or field is not a breaking change.

v0.8.0

No CLI or GUI changes break anything — the version jump is entirely about the published library crates (there is no v0.7.9; the 0.7 series ends at 0.7.8). Two adjustments for library consumers:

CrateChange
keyroost-piv Instruction gained the Attest variant and is now #[non_exhaustive] — add a catch-all arm (_ =>) to any exhaustive match. Future instruction additions will then no longer be breaking.
keyroost-resolve Device gained the unverified: Caps field (the tri-state capability display). Struct literals must set it — Caps::default() preserves the old behavior.

v0.7.8

Bug-fix release — no breaking changes for scripts or library consumers. One addition: keyroostctl fido reset --reader <substring> resets a FIDO2 card in a smart-card reader in place (no replug, no touch). Also restores behaviour v0.7.7 narrowed: every Token2 key is offered the on-device OTP surface again, regardless of USB product id.

v0.7.7

No flag or API renames. One reused name to watch for, and three additions that break nothing:

v0.7.6

Bug-fix release — no breaking changes for scripts or library consumers.

v0.7.5

CLI: the global device selector is now --device

The global flag that selects a key by its friendly name was renamed:

keyroostctl --name mykey fido info      # ≤ 0.7.4
keyroostctl --device mykey fido info    # 0.7.5+

--name collided with the --name option of the fingerprint subcommands (fido fingerprint-enroll / fingerprint-rename), where it names the fingerprint. No compatibility alias is provided — an alias would recreate the exact collision the rename fixes.

Watch out

Under the fingerprint subcommands, --name still parses — it means the fingerprint's label, not the device. A script that passes the old global spelling there won't error; it will name the fingerprint instead. Everywhere else the old spelling fails loudly with an "unexpected argument" error.

OATH: partial listings are now reported

oath list prints a stderr warning when the key holds entries that could not be decoded (written by another tool, or with a non-UTF-8 name) — previously they were silently omitted. The stdout / --json output format is unchanged, so scripts that only read stdout are unaffected.

Library (crates.io) API changes

For consumers of the published crates — CLI and GUI users are unaffected.

CrateChange
keyroost-oath parse_list returns Listing { credentials, skipped } instead of Vec<CredentialInfo>; skipped > 0 means the listing is partial.
keyroost-transport OathSession::list returns oath::Listing; TransportError::AuthFailed.tries_remaining is now Option<u8> (None = the card gave no count — don't render it as 0).
keyroost-piv pad_pin (and the VERIFY / CHANGE / UNBLOCK builders using it) asserts a 6–8 byte PIN instead of silently truncating longer input. Validate length before calling, as the in-tree transport does.
keyroost-ctap The CtapTransport trait gains read_timeout() (a default impl is provided, so existing implementations keep compiling). reset() and the bio-enroll operations now restore the caller's timeout rather than the crate default.

v0.6.0 — command names moved under molto / fido

The Molto2 and FIDO commands were nested under molto and fido groups. The old flat names were removed — update scripts as follows:

Old (≤ 0.5.x)New (0.6.0+)
keyroostctl infokeyroostctl molto info
keyroostctl set-seed …keyroostctl molto seed …
keyroostctl set-title …keyroostctl molto title …
keyroostctl configure …keyroostctl molto config …
keyroostctl sync-time …keyroostctl molto sync-time …
keyroostctl set-customer-key …keyroostctl molto customer-key …
keyroostctl import …keyroostctl molto import …
keyroostctl import-file …keyroostctl molto import-file …
keyroostctl factory-reset …keyroostctl molto reset …see the warning below
keyroostctl fido-infokeyroostctl fido info
keyroostctl fido-reset …keyroostctl fido reset …
keyroostctl fido-pin-set …keyroostctl fido pin-set …
keyroostctl fido-pin-change …keyroostctl fido pin-change …
keyroostctl fido-pin-retrieskeyroostctl fido pin-retries
keyroostctl fido-creds-list …keyroostctl fido creds-list …
keyroostctl fido-creds-metadata …keyroostctl fido creds-metadata …
keyroostctl fido-creds-delete …keyroostctl fido creds-delete …
keyroostctl manpage > x.1keyroostctl manpage ./man
Danger: factory-reset was reused

Since v0.7.7 keyroostctl factory-reset exists again as a top-level command — but it is not the old Molto2 reset. It wipes every resettable applet on the selected key: OATH, OpenPGP, PIV, Token2 OTP, then FIDO2. Both the old flat command and the new one are confirmed with --yes, so a stale keyroostctl factory-reset --yes will not fail with "unknown subcommand" — it will run and destroy far more than the script intended. Audit any script from ≤ 0.5.x for that exact string and change it to keyroostctl molto reset.

The customer-key flags (--key, --key-ascii, --key-env, --key-ascii-env) moved under molto — e.g. keyroostctl molto customer-key --key-env K. The piv, oath, openpgp, otp, key-name, list, doctor, and completions commands were unchanged.

Related