Commit Graph

11 Commits

Author SHA1 Message Date
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