95ce8898fd
feat: add mesh network visualizer
...
- D3.js force-directed graph for real-time mesh visualization
- WebSocket server (mesh-viz-bridge crate) for live updates
- Demo mode with simulated topology
- JSONL file upload for offline analysis
- Optional viz logging in mesh_node forwarding
2026-04-06 21:43:28 +02:00
150f30b0d6
feat(p2p): add MeshNode integrating all production modules
...
New mesh_node.rs providing a production-ready node:
- MeshNodeBuilder for fluent configuration
- MeshConfig integration for all settings
- MeshMetrics tracking for all operations
- Rate limiting on incoming messages
- Backpressure controller
- Graceful shutdown via ShutdownCoordinator
- Optional FappRouter based on capabilities
- MeshRouter for envelope routing
- TransportManager for multi-transport support
Key APIs:
- MeshNodeBuilder::new().fapp_relay().build()
- node.process_incoming() with rate limiting + metrics
- node.gc() for store/routing table cleanup
- node.shutdown() for graceful termination
222 tests passing (203 lib + 3 fapp_flow + 16 multi_node)
2026-04-01 18:45:41 +02:00
a05da9b751
feat: upgrade OpenMLS 0.5 → 0.8 for security patches and GREASE support
...
Migrates all MLS code in quicprochat-core from OpenMLS 0.5 to 0.8:
- StorageProvider replaces OpenMlsKeyStore (keystore.rs full rewrite)
- HybridCryptoProvider updated for new OpenMlsProvider trait
- Group operations updated for new API signatures
- MLS state persistence via MemoryStorage serialization
- tls_codec 0.3 → 0.4, openmls_traits/rust_crypto 0.2 → 0.5
2026-03-21 19:14:06 +01:00
a710037dde
chore: rename quicproquo → quicprochat in Rust workspace
...
Rename all crate directories, package names, binary names, proto
package/module paths, ALPN strings, env var prefixes, config filenames,
mDNS service names, and plugin ABI symbols from quicproquo/qpq to
quicprochat/qpc.
2026-03-21 19:14:06 +01:00
a9d1f535aa
chore: prepare repository for public release
...
- Add split licensing: AGPL-3.0 for server, Apache-2.0/MIT for all
other crates and SDKs (Signal-style)
- Add SECURITY.md with vulnerability disclosure policy
- Add CONTRIBUTING.md with build, test, and code standards
- Add "not audited" security disclaimer to README
- Add workspace package metadata (license, repository, keywords)
- Move internal planning docs to docs/internal/ (gitignored)
2026-03-21 19:14:05 +01:00
cab03bd3f7
feat(client): v2 REPL over SDK with categorized help and tab-completion
...
925-line REPL replacing the 3317-line monolith — delegates all crypto,
MLS, and RPC to quicproquo-sdk. 20 commands across 6 categories
(messaging, groups, account, keys, utility, debug), rustyline tab
completion, background event listener, auto-server-launch.
Also adds SDK accessor methods (server_addr_string, config_state_path),
WS bridge register handler, and README table formatting cleanup.
2026-03-04 13:02:54 +01:00
a5864127d1
feat: v2 Phase 1 — foundation, proto schemas, RPC framework, SDK skeleton
...
New workspace structure with 9 crates. Adds:
- proto/qpq/v1/*.proto: 11 protobuf schemas covering all 33 RPC methods
- quicproquo-proto: dual codegen (capnp legacy + prost v2)
- quicproquo-rpc: QUIC RPC framework (framing, server, client, middleware)
- quicproquo-sdk: client SDK (QpqClient, events, conversation store)
- quicproquo-server/domain/: protocol-agnostic domain types and services
- justfile: build commands
Wire format: [method_id:u16][req_id:u32][len:u32][protobuf] per QUIC stream.
All 151 existing tests pass. Backward compatible with v1 capnp code.
2026-03-04 12:02:07 +01:00
394199b19b
fix: security hardening — 40 findings from full codebase review
...
Full codebase review by 4 independent agents (security, architecture,
code quality, correctness) identified ~80 findings. This commit fixes 40
of them across all workspace crates.
Critical fixes:
- Federation service: validate origin against mTLS cert CN/SAN (C1)
- WS bridge: add DM channel auth, size limits, rate limiting (C2)
- hpke_seal: panic on error instead of silent empty ciphertext (C3)
- hpke_setup_sender_and_export: error on parse fail, no PQ downgrade (C7)
Security fixes:
- Zeroize: seed_bytes() returns Zeroizing<[u8;32]>, private_to_bytes()
returns Zeroizing<Vec<u8>>, ClientAuth.access_token, SessionState.password,
conversation hex_key all wrapped in Zeroizing
- Keystore: 0o600 file permissions on Unix
- MeshIdentity: 0o600 file permissions on Unix
- Timing floors: resolveIdentity + WS bridge resolve_user get 5ms floor
- Mobile: TLS verification gated behind insecure-dev feature flag
- Proto: from_bytes default limit tightened from 64 MiB to 8 MiB
Correctness fixes:
- fetch_wait: register waiter before fetch to close TOCTOU window
- MeshEnvelope: exclude hop_count from signature (forwarding no longer
invalidates sender signature)
- BroadcastChannel: encrypt returns Result instead of panicking
- transcript: rename verify_transcript_chain → validate_transcript_structure
- group.rs: extract shared process_incoming() for receive_message variants
- auth_ops: remove spurious RegistrationRequest deserialization
- MeshStore.seen: bounded to 100K with FIFO eviction
Quality fixes:
- FFI error classification: typed downcast instead of string matching
- Plugin HookVTable: SAFETY documentation for unsafe Send+Sync
- clippy::unwrap_used: warn → deny workspace-wide
- Various .unwrap_or("") → proper error returns
Review report: docs/REVIEW-2026-03-04.md
152 tests passing (72 core + 35 server + 14 E2E + 1 doctest + 30 P2P)
2026-03-04 07:52:12 +01:00
db46b72f58
feat: Sprint 3 — C FFI bindings, WASM compilation, Python example, SDK docs
...
- Create quicproquo-ffi crate with 7 extern "C" functions: connect,
login, send, receive, disconnect, last_error, free_string
(produces libquicproquo_ffi.so and .a)
- Feature-gate quicproquo-core for WASM: identity, hybrid_kem,
safety_numbers, sealed_sender, app_message, padding, transcript
all compile to wasm32-unknown-unknown
- Add Python ctypes example (examples/python/qpq_client.py) with
QpqClient wrapper class and CLI
- Add SDK documentation: FFI reference, WASM guide, qpq-gen generators
- Update Dockerfile for quicproquo-ffi workspace member
2026-03-03 23:47:40 +01:00
612b06aa8e
feat: Sprint 1 — production hardening, TLS lifecycle, CI coverage, lint cleanup
...
- Fix 3 client panics: replace .unwrap()/.expect() with proper error
handling in rpc.rs (AUTH_CONTEXT lock), repl.rs (pending_member),
and retry.rs (last_err)
- Add --danger-accept-invalid-certs flag with InsecureServerCertVerifier
for development TLS bypass, plus mdBook TLS documentation
- Add CI coverage job (cargo-tarpaulin) and Docker build validation
to GitHub Actions workflow, plus README CI badge
- Add [workspace.lints] config, fix 46 clippy warnings across 8 crates,
zero warnings on all buildable crates
- Update Dockerfile for all 11 workspace members
2026-03-03 23:19:11 +01:00
dc4e4e49a0
feat: Phase 9 — developer experience, extensibility, and community growth
...
New crates:
- quicproquo-bot: Bot SDK with polling API + JSON pipe mode
- quicproquo-kt: Key Transparency Merkle log (RFC 9162 subset)
- quicproquo-plugin-api: no_std C-compatible plugin vtable API
- quicproquo-gen: scaffolding tool (qpq-gen plugin/bot/rpc/hook)
Server features:
- ServerHooks trait wired into all RPC handlers (enqueue, fetch, auth,
channel, registration) with plugin rejection support
- Dynamic plugin loader (libloading) with --plugin-dir config
- Delivery proof canary tokens (Ed25519 server signatures on enqueue)
- Key Transparency Merkle log with inclusion proofs on resolveUser
Core library:
- Safety numbers (60-digit HMAC-SHA256 key verification codes)
- Verifiable transcript archive (CBOR + ChaCha20-Poly1305 + hash chain)
- Delivery proof verification utility
- Criterion benchmarks (hybrid KEM, MLS, identity, sealed sender, padding)
Client:
- /verify REPL command for out-of-band key verification
- Full-screen TUI via Ratatui (feature-gated --features tui)
- qpq export / qpq export-verify CLI subcommands
- KT inclusion proof verification on user resolution
Also: ROADMAP Phase 9 added, bot SDK docs, server hooks docs,
crate-responsibilities updated, example plugins (rate_limit, logging).
2026-03-03 22:47:38 +01:00
c8398d6cb7
feat: DM epoch fix, federation relay, and mDNS mesh discovery
...
- schema: createChannel returns wasNew :Bool to elect the MLS initiator
unambiguously; prevents duplicate group creation on concurrent /dm calls
- core: group helpers for epoch tracking and key-package lifecycle
- server: federation subsystem — mTLS QUIC server-to-server relay with
Cap'n Proto RPC; enqueue/batchEnqueue relay unknown recipients to their
home domain via FederationClient
- server: mDNS _quicproquo._udp.local. service announcement on startup
- server: storage + sql_store — identity_exists, peek/ack, federation
home-server lookup helpers
- client: /mesh peers REPL command (mDNS discovery, feature = "mesh")
- client: MeshDiscovery — background mDNS browse with ServiceDaemon
- client: was_new=false path in cmd_dm waits for peer Welcome instead of
creating a duplicate initiator group
- p2p: fix ALPN from quicnprotochat/p2p/1 → quicproquo/p2p/1
- workspace: re-include quicproquo-p2p in members
2026-03-03 14:41:56 +01:00
853ca4fec0
chore: rename project quicnprotochat -> quicproquo (binaries: qpq)
...
Rename the entire workspace:
- Crate packages: quicnprotochat-{core,proto,server,client,gui,p2p,mobile} -> quicproquo-*
- Binary names: quicnprotochat -> qpq, quicnprotochat-server -> qpq-server,
quicnprotochat-gui -> qpq-gui
- Default files: *-state.bin -> qpq-state.bin, *-server.toml -> qpq-server.toml,
*.db -> qpq.db
- Environment variable prefix: QUICNPROTOCHAT_* -> QPQ_*
- App identifier: chat.quicnproto.gui -> chat.quicproquo.gui
- Proto package: quicnprotochat.bench -> quicproquo.bench
- All documentation, Docker, CI, and script references updated
HKDF domain-separation strings and P2P ALPN remain unchanged for
backward compatibility with existing encrypted state and wire protocol.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-03-01 20:11:51 +01:00
4c1e4683e3
chore: exclude p2p crate from workspace, slim tokio features
...
Move quicnprotochat-p2p to workspace.exclude so ~90 iroh-only
dependencies are not compiled in the default build. Narrow tokio
features from "full" to the subset actually used. The p2p crate
now pins its own dependency versions since it is outside the workspace.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-02-23 23:10:23 +01:00
b5b361e2ff
chore: move Python/Ruby/bindings crates to quicnprotochat-lang-clients repo
...
The three crates (quicnprotochat-bindings, quicnprotochat-python,
quicnprotochat-ruby) are developed in a separate feature repository
at git.xorwell.de:c/quicnprotochat-lang-clients.
2026-02-22 18:58:45 +01:00
0bdc222724
fix: address 16 architecture design flaws across all crates
...
Phase 1 — Foundation:
- Constant-time token comparison via subtle::ConstantTimeEq (Fix 11)
- Structured error codes E001–E020 in new error_codes.rs (Fix 15)
- Remove dead envelope.capnp code and related types (Fix 16)
Phase 2 — Auth Hardening:
- Registration collision check via has_user_record() (Fix 5)
- Auth required on uploadHybridKey/fetchHybridKey RPCs (Fix 1)
- Identity-token binding at registration and login (Fix 2)
- Session token expiry with 24h TTL and background reaper (Fix 3)
- Bounded pending logins with 5-minute timeout (Fix 4)
Phase 3 — Resource Limits:
- Rate limiting: 100 enqueues/60s per token (Fix 6)
- Queue depth cap at 1000 + 7-day message TTL/GC (Fix 7)
- Partial queue drain via limit param on fetch/fetchWait (Fix 8)
Phase 4 — Crypto Fixes:
- OPAQUE KSF switched from Identity to Argon2id (Fix 10)
- Random AEAD nonce in hybrid KEM instead of HKDF-derived (Fix 12)
- Zeroize secret fields in HybridKeypairBytes (Fix 13)
- Encrypted client state files via QPCE format (Fix 9)
Phase 5 — Protocol:
- Commit fan-out to all existing members on invite (Fix 14)
- Add member_identities() to GroupMember
Breaking: existing OPAQUE registrations invalidated (Argon2 KSF).
Schema: added auth to hybrid key ops, identityKey to OPAQUE finish
RPCs, limit to fetch/fetchWait.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-02-22 10:51:09 +01:00
8d5c1b3b9b
WIP: add OPAQUE password-authenticated key exchange
...
Add opaque-ke (v4, ristretto255) for password-based registration and
login. Extend NodeService schema with opaqueRegisterStart/Finish and
opaqueLoginStart/Finish RPCs. Add Store trait methods for OPAQUE server
setup and user records. Initial e2e integration test scaffolding.
Note: FileBackedStore does not yet implement the new Store trait
methods — server compilation is temporarily broken.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-02-22 08:25:34 +01:00
f334ed3d43
feat: add post-quantum hybrid KEM + SQLCipher persistence
...
Feature 1 — Post-Quantum Hybrid KEM (X25519 + ML-KEM-768):
- Create hybrid_kem.rs with keygen, encrypt, decrypt + 11 unit tests
- Wire format: version(1) | x25519_eph_pk(32) | mlkem_ct(1088) | nonce(12) | ct
- Add uploadHybridKey/fetchHybridKey RPCs to node.capnp schema
- Server: hybrid key storage in FileBackedStore + RPC handlers
- Client: hybrid keypair in StoredState, auto-wrap/unwrap in send/recv/invite/join
- demo-group runs full hybrid PQ envelope round-trip
Feature 2 — SQLCipher Persistence:
- Extract Store trait from FileBackedStore API
- Create SqlStore (rusqlite + bundled-sqlcipher) with encrypted-at-rest SQLite
- Schema: key_packages, deliveries, hybrid_keys tables with indexes
- Server CLI: --store-backend=sql, --db-path, --db-key flags
- 5 unit tests for SqlStore (FIFO, round-trip, upsert, channel isolation)
Also includes: client lib.rs refactor, auth config, TOML config file support,
mdBook documentation, and various cleanups by user.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com >
2026-02-22 08:07:48 +01:00
3bf3ab23e2
Rename project to quicnprotochat
2026-02-21 23:37:40 +01:00
9a0b02a012
feat: M2 + M3 — AuthService, MLS group lifecycle, Delivery Service
...
M2:
- schemas/auth.capnp: AuthenticationService (upload/fetch KeyPackage)
- noiseml-core: IdentityKeypair (Ed25519), generate_key_package, NoiseTransport
with send_envelope/recv_envelope, Noise_XX handshake (initiator + responder)
- noiseml-proto: auth_capnp module, ParsedEnvelope helpers
- noiseml-server: AuthServiceImpl backed by DashMap queue (single-use KPs)
- noiseml-client: register + fetch-key subcommands, ping over Noise_XX
- tests: auth_service integration test (upload → fetch round-trip)
M3:
- schemas/delivery.capnp: DeliveryService (enqueue/fetch opaque payloads)
- noiseml-core/group.rs: GroupMember — MLS group lifecycle
create_group, add_member (→ Commit+Welcome), join_group, send_message,
receive_message; uses openmls 0.5 public API (extract() not into_welcome,
KeyPackageIn::validate() not From<KeyPackageIn>)
- noiseml-server: DeliveryServiceImpl on port 7001 alongside AS on 7000
- noiseml-proto: delivery_capnp module
TODO (see M3_STATUS.md):
- noiseml-client: group subcommands (create-group, invite, join, send, recv)
- noiseml-client/tests/mls_group.rs: full MLS round-trip integration test
2026-02-19 23:39:49 +01:00
9fa3873bd7
feat: M1 — Noise transport, Cap'n Proto framing, Ping/Pong
...
Establishes the foundational transport layer for noiseml:
- Noise_XX_25519_ChaChaPoly_BLAKE2s handshake (initiator + responder)
via `snow`; mutual authentication of static X25519 keys guaranteed
before any application data flows.
- Length-prefixed frame codec (4-byte LE u32, max 65 535 B per Noise
spec) implemented as a Tokio Encoder/Decoder pair.
- Cap'n Proto Envelope schema with MsgType enum (Ping, Pong, and
future MLS message types defined but not yet dispatched).
- Server: TCP listener, one Tokio task per connection, Ping→Pong
handler, fresh X25519 keypair logged at startup.
- Client: `ping` subcommand — handshake, send Ping, receive Pong,
print RTT, exit 0.
- Integration tests: bidirectional Ping/Pong with mutual-auth
verification; server keypair reuse across sequential connections.
- Docker multi-stage build (rust:bookworm → debian:bookworm-slim,
non-root) and docker-compose with TCP healthcheck.
No MLS group state, no AS/DS, no persistence — out of scope for M1.
2026-02-19 21:58:51 +01:00