feat(store): encrypt chat bodies at rest; Ctrl-Q CLEAR/QUIT #1

Merged
sirius merged 1 commit from wt/t_b0456c4b into main 2026-09-10 21:29:46 +00:00
Owner

Summary

  • Chat bodies encrypted at rest: random 32-byte data key wrapped with Argon2id (same params as backup) + ChaCha20-Poly1305. messages.plaintext on disk is nonce || ciphertext. Identity keys stay plaintext in sqlite (not sqlcipher; not wrapped with identity_sk).
  • Unlock at Store::open_at / Node::start via ONIONWIRE_STORE_PASSPHRASE; interactive TUI prompts before boot. Empty/wrong passphrase fails closed.
  • First unlock with a new passphrase re-encrypts legacy plaintext rows in one transaction.
  • Ctrl-Q opens a confirm screen: type CLEAR then Enter to wipe_messages and quit; QUIT then Enter to quit without clearing; Esc stays in the app.

Proof

  • cargo test --offline --locked: 101 passed / 3 ignored (live Tor).
  • cargo clippy --offline --locked --all-targets -- -D warnings: clean.
  • Do not merge; Lance merges. Not pushed to main.
## Summary - Chat bodies encrypted at rest: random 32-byte data key wrapped with Argon2id (same params as backup) + ChaCha20-Poly1305. `messages.plaintext` on disk is `nonce || ciphertext`. Identity keys stay plaintext in sqlite (not sqlcipher; not wrapped with identity_sk). - Unlock at `Store::open_at` / `Node::start` via `ONIONWIRE_STORE_PASSPHRASE`; interactive TUI prompts before boot. Empty/wrong passphrase fails closed. - First unlock with a new passphrase re-encrypts legacy plaintext rows in one transaction. - Ctrl-Q opens a confirm screen: type `CLEAR` then Enter to `wipe_messages` and quit; `QUIT` then Enter to quit without clearing; Esc stays in the app. ## Proof - `cargo test --offline --locked`: 101 passed / 3 ignored (live Tor). - `cargo clippy --offline --locked --all-targets -- -D warnings`: clean. - Do not merge; Lance merges. Not pushed to `main`.
sirius added 1 commit 2026-09-10 21:18:07 +00:00
feat(store): encrypt chat bodies at rest; Ctrl-Q CLEAR/QUIT
All checks were successful
ci / test (pull_request) Successful in 3m13s
6323619d80
Wrap a random 32-byte message key with Argon2id+ChaCha20-Poly1305.
sqlite messages.plaintext is nonce||ciphertext; identity keys stay
plaintext. Empty/wrong passphrase fails closed. Ctrl-Q types CLEAR or
QUIT then Enter (Esc cancels).
sirius merged commit 2b42864eba into main 2026-09-10 21:29:46 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: sirius/onionwire#1
No description provided.