chore: rename quicproquo → quicprochat in docs, Docker, CI, and packaging
Rename all project references from quicproquo/qpq to quicprochat/qpc across documentation, Docker configuration, CI workflows, packaging scripts, operational configs, and build tooling. - Docker: crate paths, binary names, user/group, data dirs, env vars - CI: workflow crate references, binary names, artifact names - Docs: all markdown files under docs/, SDK READMEs, book.toml - Packaging: OpenWrt Makefile, init script, UCI config (file renames) - Scripts: justfile, dev-shell, screenshot, cross-compile, ai_team - Operations: Prometheus config, alert rules, Grafana dashboard - Config: .env.example (QPQ_* → QPC_*), CODEOWNERS paths - Top-level: README, CONTRIBUTING, ROADMAP, CLAUDE.md
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# Security Audit
|
||||
|
||||
This document is a security audit of the quicproquo codebase as of the audit date. It aligns with the [Threat Model](src/cryptography/threat-model.md) and [Production Readiness Audit](PRODUCTION-READINESS-AUDIT.md). The project has **not** undergone a formal third-party audit; this is an internal review.
|
||||
This document is a security audit of the quicprochat codebase as of the audit date. It aligns with the [Threat Model](src/cryptography/threat-model.md) and [Production Readiness Audit](PRODUCTION-READINESS-AUDIT.md). The project has **not** undergone a formal third-party audit; this is an internal review.
|
||||
|
||||
---
|
||||
|
||||
@@ -24,19 +24,19 @@ This document is a security audit of the quicproquo codebase as of the audit dat
|
||||
|
||||
### 1.1 Token comparison
|
||||
|
||||
- **Location:** `crates/quicproquo-server/src/auth.rs`
|
||||
- **Location:** `crates/quicprochat-server/src/auth.rs`
|
||||
- **Finding:** Bearer token and identity key comparisons use `subtle::ConstantTimeEq` (`ct_eq`). Length is checked before comparison where applicable.
|
||||
- **Status:** ✅ No timing leakage from token or identity comparison.
|
||||
|
||||
### 1.2 Session token generation
|
||||
|
||||
- **Location:** `crates/quicproquo-server/src/node_service/auth_ops.rs` (login finish)
|
||||
- **Location:** `crates/quicprochat-server/src/node_service/auth_ops.rs` (login finish)
|
||||
- **Finding:** Session tokens are 32 bytes from `rand::RngCore::fill_bytes(&mut rand::rngs::OsRng, &mut token)`. Stored in `sessions` with TTL (24h). Expired sessions are removed on next use.
|
||||
- **Status:** ✅ Cryptographically strong, single-use style (opaque 32-byte token).
|
||||
|
||||
### 1.3 OPAQUE (RFC 9497)
|
||||
|
||||
- **Location:** `crates/quicproquo-core/src/opaque_auth.rs`, server `auth_ops.rs`
|
||||
- **Location:** `crates/quicprochat-core/src/opaque_auth.rs`, server `auth_ops.rs`
|
||||
- **Finding:** Shared `OpaqueSuite` (Ristretto255, Triple-DH, Argon2id). Server never sees password. Registration and login flows use `ServerRegistration`/`ServerLogin` correctly. Pending login state is stored server-side and removed on consume. Identity key is bound at login finish; mismatch returns E016 and is not logged with secrets.
|
||||
- **DoS:** Pending-login check runs **before** expensive OPAQUE work (login start); repeated attempts for the same username within 60s are rejected early.
|
||||
- **Status:** ✅ Correct usage; DoS mitigation in place.
|
||||
@@ -52,19 +52,19 @@ This document is a security audit of the quicproquo codebase as of the audit dat
|
||||
|
||||
### 2.1 MLS and identity
|
||||
|
||||
- **Location:** `quicproquo-core` (group, identity, keypackage)
|
||||
- **Location:** `quicprochat-core` (group, identity, keypackage)
|
||||
- **Finding:** MLS ciphersuite `MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519` (RFC 9420). Ed25519 identity seed stored in `Zeroizing<[u8; 32]>`; zeroize-on-drop. KeyPackages validated for ciphersuite before server stores. Single-use KeyPackage semantics enforced (consume-on-fetch).
|
||||
- **Status:** ✅ Aligns with key lifecycle and zeroization goals.
|
||||
|
||||
### 2.2 Hybrid KEM (X25519 + ML-KEM-768)
|
||||
|
||||
- **Location:** `crates/quicproquo-core/src/hybrid_kem.rs`
|
||||
- **Finding:** Hybrid keypair and shared secrets use `Zeroizing` where appropriate. HKDF domain separation (`quicproquo-hybrid-v1`). ChaCha20-Poly1305 for AEAD. Versioned envelope.
|
||||
- **Location:** `crates/quicprochat-core/src/hybrid_kem.rs`
|
||||
- **Finding:** Hybrid keypair and shared secrets use `Zeroizing` where appropriate. HKDF domain separation (`quicprochat-hybrid-v1`). ChaCha20-Poly1305 for AEAD. Versioned envelope.
|
||||
- **Status:** ✅ PQ-ready envelope layer; secret handling is careful.
|
||||
|
||||
### 2.3 Client state encryption (QPCE)
|
||||
|
||||
- **Location:** `crates/quicproquo-client/src/client/state.rs`
|
||||
- **Location:** `crates/quicprochat-client/src/client/state.rs`
|
||||
- **Finding:** Optional password protection: Argon2id (default params) for key derivation, ChaCha20-Poly1305, random salt and nonce. Derived key held in `Zeroizing` during use. Unencrypted state is a documented option (e.g. dev).
|
||||
- **Recommendation:** Document Argon2 params (memory, iterations) for auditability; consider explicit `Argon2::new()` with named params in a future revision.
|
||||
- **Status:** ✅ Appropriate for optional at-rest protection.
|
||||
@@ -75,13 +75,13 @@ This document is a security audit of the quicproquo codebase as of the audit dat
|
||||
|
||||
### 3.1 Server TLS
|
||||
|
||||
- **Location:** `crates/quicproquo-server/src/tls.rs`
|
||||
- **Location:** `crates/quicprochat-server/src/tls.rs`
|
||||
- **Finding:** TLS 1.3 only. No client cert. ALPN `capnp`. When not in production, missing cert/key triggers self-signed generation; key file permissions set to `0o600` on Unix. Production mode requires existing cert/key (no auto-generation).
|
||||
- **Status:** ✅ Matches documented design; self-signed limitation is documented in threat model.
|
||||
|
||||
### 3.2 Client TLS
|
||||
|
||||
- **Location:** `crates/quicproquo-client/src/client/rpc.rs`
|
||||
- **Location:** `crates/quicprochat-client/src/client/rpc.rs`
|
||||
- **Finding:** Client loads CA cert from file, builds `RootCertStore` with that single cert, uses it for server verification. Server name from CLI/env is used for connection (SNI and cert verification). No custom bypass.
|
||||
- **Status:** ✅ Proper verification against provided CA; trust-on-first-use / self-signed caveat is documented.
|
||||
|
||||
@@ -106,7 +106,7 @@ This document is a security audit of the quicproquo codebase as of the audit dat
|
||||
|
||||
### 4.2 Rate limiting
|
||||
|
||||
- **Location:** `crates/quicproquo-server/src/auth.rs`, `delivery.rs`
|
||||
- **Location:** `crates/quicprochat-server/src/auth.rs`, `delivery.rs`
|
||||
- **Finding:** Per-token rate limit (e.g. 100 enqueues per 60s). Enqueue path checks before storage. Queue depth and payload size caps (1000 messages, 5 MB) enforced.
|
||||
- **Status:** ✅ Limits in place to curb abuse and DoS.
|
||||
|
||||
@@ -156,11 +156,11 @@ These remain as documented, not new findings:
|
||||
### 8.1 High value
|
||||
|
||||
- **Dependency audit:** Run `cargo install cargo-audit` then `cargo audit` locally (and in CI if available) to check for known-vulnerable dependencies. Fix or document any findings. See [Checking dependencies](#checking-dependencies) below.
|
||||
- **Argon2 params:** Implemented: client state KDF now uses explicit Argon2id parameters (19 MiB memory, 2 iterations, 1 lane) in `quicproquo-client` so they are auditable.
|
||||
- **Argon2 params:** Implemented: client state KDF now uses explicit Argon2id parameters (19 MiB memory, 2 iterations, 1 lane) in `quicprochat-client` so they are auditable.
|
||||
|
||||
### 8.2 Medium value
|
||||
|
||||
- **Certificate pinning:** To pin the server, use the server's certificate as the client's `ca_cert` (e.g. copy `server-cert.der` from the server and pass it via `--ca-cert` or `QPQ_CA_CERT`). Do not use a general CA unless you intend to trust that CA for all servers. See [Certificate pinning](#certificate-pinning) below.
|
||||
- **Certificate pinning:** To pin the server, use the server's certificate as the client's `ca_cert` (e.g. copy `server-cert.der` from the server and pass it via `--ca-cert` or `QPC_CA_CERT`). Do not use a general CA unless you intend to trust that CA for all servers. See [Certificate pinning](#certificate-pinning) below.
|
||||
- **Health endpoint:** The `health` RPC is unauthenticated by design for liveness probes and load balancers; this is documented in code and in this audit.
|
||||
|
||||
### 8.3 Lower priority
|
||||
@@ -208,7 +208,7 @@ Fix or document any reported issues. Running `cargo audit` in CI (e.g. GitHub Ac
|
||||
|
||||
## Certificate pinning
|
||||
|
||||
The client trusts the server certificate(s) in the file given by `--ca-cert` (or `QPQ_CA_CERT`). To **pin** a specific server:
|
||||
The client trusts the server certificate(s) in the file given by `--ca-cert` (or `QPC_CA_CERT`). To **pin** a specific server:
|
||||
|
||||
1. Obtain the server's certificate (e.g. copy `data/server-cert.der` from the server, or export from your deployment).
|
||||
2. Use that file as the client's `ca_cert`. The client will only connect to a server that presents that exact certificate (or chain).
|
||||
|
||||
Reference in New Issue
Block a user