Security & audit-readiness materials for Keychat — a sovereign messaging stack that composes Signal (PQXDH + Double Ratchet), MLS, Nostr, and Cashu on an iOS Swift client over a Rust protocol workspace. Prepared to support a Trail of Bits "Patch the Planet"–style review.
This is audit-readiness material, not a full audit. Every claim is tied to a
file:linein the reviewed source and cross-checked by independent review. Drafted with AI assistance; see each document's provenance note.Open findings (unpatched at the pinned commit):
- Medium: the 64 KB
KCMessagesize cap is specified but not enforced.
| Path | What it is |
|---|---|
deliverables/SECURITY.md |
Centerpiece — threat model, trust model, 12 attack surfaces, severity criteria, coordinated-disclosure policy, crypto inventory. |
deliverables/agents/rust-workspace-AGENTS.md |
Orientation for reviewers/AI tools on the Rust workspace + a false-positive list (drop at rust/AGENTS.md). |
deliverables/agents/ios-app-AGENTS.md |
Same, for the iOS Swift client (drop at apps/ios/Keychat/AGENTS.md). |
deliverables/libsignal-fork-diff.md |
Provenance + diff + security analysis of the vendored libsignal fork (kc-x3dh-compat, an X3DH interop delta over upstream v0.88.3). |
deliverables/fuzz/ |
cargo-fuzz harness targeting the highest-risk parsers (SessionRecord byte extraction, address derivation, NIP-17 Gift Wrap, KCMessage). Wiring steps in its README. |
deliverables/BUILD-AND-FUZZ.md |
How to build, test, and run the fuzz harness. |
deliverables/ci/patch-the-planet-ci.yml |
Minimal CI: Rust checks + a time-boxed fuzz smoke. |
deliverables/TARGET-VERSION.md |
Pins the exact code revision this package reviews (commit 55f8c24c, branch dev). |
deliverables/README.md |
Detailed English index + the corrections made vs. the original handoff notes. |
All citations are pinned to commit
55f8c24cb1d72de31d69de64ba20e8216098f1d2 (branch dev) — see
deliverables/TARGET-VERSION.md. Key markers:
app 1.51.1 (build 7016), protocol spec v2.0 Draft (2026-03-13), 14-crate Rust
workspace, iOS client at apps/ios/Keychat/, vendored libsignal fork
kc-x3dh-compat over upstream v0.88.3.
Scope note:
keychat-cli(the standalone terminal client) is out of scope — it is a separate binary, not part of the iOS app.The iOS 1.5 repository is currently private and planned to be opened. The protocol core and NIP specifications are already public at
keychat-io/keychat-protocol.
-
Corrected the record against the original notes: the libsignal fork is a build dependency (via Cargo
[patch]) and carries an X3DH delta;SessionRecordextraction is hand-written byte parsing (notprost); the client is iOS Swift (not Flutter); SPQR post-quantum ratchet is active for PQXDH sessions; the PQXDH KDF is HKDF-SHA256. -
De-risked overstated concerns honestly (source-grounded): a forced X3DH downgrade of an honest pair is not reachable (Attack Surface 9); the dapp browser gates signing behind per-origin/per-identity approval (Attack Surface 10); the file-encryption padding-oracle is not exploitable (hash verified before unpad). Session-reset and PrekeyMessage-type-detection concerns are Informational (correctly handled).
-
Concrete findings, each with a patch proposed upstream. All five are open against the pinned commit; fixes have been submitted as pull requests but are not merged, so the findings below still describe the code as audited.
Finding Severity Status Unenforced 64 KB KCMessagecap → unbounded allocationMedium PR open A token's sender-supplied mint URL is registered without confirmation; reachable via red packets Low–Medium PR open No friend-request freshness or replay guard (feeds the AS9 replay residual) Low PR open Legacy V2 backup format is unauthenticated; a damaged secure_storage.jsonis silently ignoredLow PR open Diagnostics redaction scrubs the label instead of the secret Informational PR open -
Severities reflect reachability, not just defect class. Diagnostics redaction is inverted but no live call site can reach it, so it is Informational. Tampering with an unauthenticated V2 backup requires write access to the victim's file — a capability that permits the same damage without any cryptographic weakness — so it is Low. Each finding states what it lets someone do that they could not do already.
Vulnerability reporting policy is in deliverables/SECURITY.md
(email dev@keychat.io; 90-day coordinated disclosure).