Add purpose, architecture, and public API summary to each crate README following chanora_resolver pattern. Update verification master plan with new evidence sources and entry/exit criteria.
3.3 KiB
3.3 KiB
chanora_storage
Two strictly separated storage concerns per SAD-067:
BookmarkRepository— non-secret bookmark state via SQLite with optional encrypted password fields (rusqlitebundled, DEC-013.1).IdentityFileStore— Beta fallback storage for identity material while platform secure-storage backends mature.
Architecture
IdentityFileStore
- Persists a single TS3 identity to
<dir>/identity.tskeyencrypted with ChaCha20-Poly1305. - The Data Encryption Key (DEK) is 32 random bytes stored in the platform keyring (Linux Secret Service, macOS Keychain, Windows Credential Manager, iOS Keychain) when available, with a best-effort file fallback at
identity.dek(mode 0600 on Unix). - Legacy plaintext files from pre-Beta are still readable; the next
save()upgrades them to encrypted form. - Audio metadata (
transmit_mode,release_tail_ms, PTT binding) is persisted alongside asaudio_meta.json(plaintext, non-secret).
BookmarkRepository
- SQLite-backed store at
<dir>/chanora.db. - Schema v1: basic bookmark columns. Schema v2: adds
password_blobfor encrypted passwords. - When constructed via
with_crypto(), thepasswordcolumn is replaced by a ChaCha20-Poly1305 envelope under the same per-install DEK. - Legacy plaintext passwords are transparently read and upgraded on the next
update().
Crypto abstraction
Cryptotrait:encrypt(plaintext)/decrypt(blob)— callers see only the encrypt/decrypt pair.DekCrypto— concrete implementation sharing the same per-install DEK withIdentityFileStore.
Public API Summary
Types
| Type | Role |
|---|---|
IdentityFileStore |
Encrypted identity file store |
BookmarkRepository |
SQLite bookmark store with optional password encryption |
Bookmark |
Bookmark DTO: id, display_name, host, nickname, password |
PttBindingMeta |
Persisted PTT binding metadata |
StorageError |
NotFound, Migration, Sqlite, SecureStore, Io, Crypto |
Crypto trait |
Encrypt/decrypt abstraction |
IdentityFileStore methods
new(dir)— create or open store, ensure DEK existsload()→Option<String>— read identity (handles legacy plaintext)save(identity)— persist encrypted (ChaCha20-Poly1305, atomic write)clear()— remove identity filecrypto()— obtain aCryptohandle sharing the DEKset_transmit_mode(mode)/get_transmit_mode()— audio settings persistenceset_release_tail_ms(ms)/get_release_tail_ms()— release-tail persistenceset_ptt_binding(...)/get_ptt_binding()— PTT binding persistence
BookmarkRepository methods
new(dir)/with_crypto(dir, crypto)— open (plain or encrypted)add(bookmark)→i64— insert, return idupdate(bookmark)— replace by iddelete(id)— remove by idlist()→Vec<Bookmark>— all bookmarks ordered by idupsert_or_add(bookmark)— insert or update by host, preserves user's display nameencrypts_passwords()— whether password encryption is active
Platform notes
- Unix: files written with mode 0600.
- Keyring access can be disabled via
CHANORA_DISABLE_KEYRING=1for tests/headless environments. - Android: file in app-private storage (not encrypted at rest — documented Beta gap).
- iOS/Windows/macOS: caller provides the storage directory; platform sandbox handles access control.