Skip to content

keep-cli: hardening & test-coverage backlog (9 items) #788

Description

@kwsantiago

Hardening and test-coverage findings in keep-cli.

Read this before picking anything up. The original list was produced by an automated pass whose header claimed each entry was verified still open. A manual pass on 2026-07-30 read the code for all nine and that claim did not hold: two were already fixed, two overstated a gap that had been partly closed, and one asked for the wrong property entirely.

Entries here name where the code looks wrong. They are not instructions. Read the code before acting on one, and if it does not say what the entry says, correct the entry.

Open

  • Software and hardware DKG scaffolding duplicated — Two large command functions with duplicated relay setup, round-1 publish, fetch loops, timeouts and encryption. No shared transport helper extracted. Also listed on the keep-frost-net backlog; do them together.
  • Wallet spend holds the share resident for the coordination waitcmd_wallet_spend unlocks the vault and keeps the FROST and OPRF share material resident for the whole wait, with no re-authentication at finalize. A fifteen-minute cap bounds the window; the resident-key exposure inside it is unchanged.
  • Software DKG has no echo round over the full round-1 set — Narrowed. An equivocation check exists and is deliberately extracted so the decision is unit-testable without relay I/O, and peers wait for group-key confirmations. What is still missing is an echo round hashing the complete round-1 set, and a comment in the fetch loop still records the single-relay exposure.
  • OPRF serve plumbing partly untested — Narrowed. load_oprf_key_share has three tests covering a missing file, malformed bytes and a valid round trip. The share-file and dealer flags and the seal handler remain uncovered.
  • Duress state directory has no tamper-evident anchor — Narrowed. The premise that an absent state file silently unfreezes no longer holds: a read-side check refuses to trust the state directory when it is group- or world-writable without the sticky bit, shared with the boot-time probe so the two cannot drift. What the entry additionally asked for, an anchor making deletion detectable rather than merely hard, is a separate and larger change.

Removed as already fixed

The signature share is no longer printed unconditionally; it goes through a debug-level log, with a comment recording that publication in the signature event is its intended egress. write_secret_file has tests covering empty and binary payloads, stale-temp cleanup from a crashed run, and replacing a symlinked destination without writing through it. Session id generation now routes through the core entropy helper, which applies the health check that fails closed; the framing in the original entry was wrong, since the previous source was already a CSPRNG and what it skipped was the health check rather than randomness quality.

Removed as wrong

Nonce store not encrypted at rest. The file holds no secrets. Each record is a commitment, timestamps, a used flag and a session id. A FROST commitment is public by construction: it is broadcast to the coordinator, and the secret nonce it commits to never leaves the signing device. Encrypting a file of public commitments buys no confidentiality and adds key management for nothing.

The property that would matter is integrity, since the used flag is a reuse guard and reuse of a FROST nonce leaks the share. Except the flag is not doing that job: the function that marks a nonce used and the one that queries it are both dead code with no callers. Nothing in the CLI ever sets it, so the used count an operator sees is always zero and no host-side reuse check happens. Reuse prevention rests entirely on the device, which tracks consumed session ids and writes nonce checkpoints, and that is the right place for it. The real work is either removing the unused tracking so the store is honestly a record of what was generated, or wiring it up so the flag is set and consulted, at which point integrity protection becomes worth discussing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    p2PriorityrustPull requests that update rust codesecuritySecurity-related issues

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions