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
openpgp statusnames the algorithm in full —RSA-2048,EdDSA Ed25519— where it printed the bare family (RSA,EdDSA). The--jsonfieldssig_algo/dec_algo/aut_algocarry the same fuller text.openpgp signandopenpgp authenticatehand an ECC slot the bare digest and an RSA slot a PKCS#1DigestInfo, chosen from the slot's algorithm; a slot whose algorithm cannot be read is an error rather than a guess.--hash sha1is refused on an ECC slot.piv status'scert_len(text and--json) is now the certificate's DER length, not the card's object size — typically nine bytes smaller than before.
Library (crates.io) API changes
| Crate | Change |
|---|---|
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:
| Crate | Change |
|---|---|
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:
keyroostctl factory-resetis a new top-level command that resets every applet on a key. It reuses a name that was removed in v0.6.0 with a different meaning — see the warning under v0.6.0 below.keyroostctl piv move-key --from <slot> --to <slot>— new; the 20 retired PIV slots (82–95) are now accepted anywhere--slotis.keyroostctl fido ssh-cert list|extract— new; read-only.
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.
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.
| Crate | Change |
|---|---|
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 info | keyroostctl 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-info | keyroostctl 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-retries | keyroostctl 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.1 | keyroostctl manpage ./man |
factory-reset was reusedSince 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.