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>
This commit is contained in:
332
docs/src/cryptography/threat-model.md
Normal file
332
docs/src/cryptography/threat-model.md
Normal file
@@ -0,0 +1,332 @@
|
||||
# Threat Model
|
||||
|
||||
This page defines the attacker models quicnprotochat is designed to resist,
|
||||
catalogues what is and is not protected, identifies known gaps in the current
|
||||
implementation, and outlines future mitigations.
|
||||
|
||||
## Attacker Models
|
||||
|
||||
### 1. Passive Eavesdropper
|
||||
|
||||
**Capabilities:** Records all network traffic between clients and the server.
|
||||
Can observe IP addresses, connection timing, message sizes, and encrypted
|
||||
payloads. Cannot modify traffic.
|
||||
|
||||
**What they learn:**
|
||||
|
||||
- Connection metadata: which IP addresses connect to the server and when.
|
||||
- Message timing and sizes: observable patterns (e.g., message frequency,
|
||||
payload lengths) that could reveal communication patterns.
|
||||
- Encrypted payloads: TLS 1.3 ciphertext containing Noise ciphertext containing
|
||||
MLS ciphertext. Three layers of encryption must be broken to access content.
|
||||
|
||||
**What they cannot learn:**
|
||||
|
||||
- Message content: protected by MLS encryption inside Noise inside TLS.
|
||||
- Group membership details: MLS Commits are encrypted.
|
||||
- Which specific recipient a message is destined for (from the network
|
||||
perspective, all messages go to the server).
|
||||
|
||||
**Residual risk:** Traffic analysis. Even without decryption, the timing and
|
||||
size of messages can reveal communication patterns. For example, a message sent
|
||||
by Alice followed shortly by a message to Bob may indicate they are in the same
|
||||
group. See [Future Mitigations](#future-mitigations) for countermeasures.
|
||||
|
||||
### 2. Active Network Attacker (MITM)
|
||||
|
||||
**Capabilities:** Can intercept, modify, drop, and inject network traffic.
|
||||
Positioned between the client and server (e.g., compromised router, ISP, or
|
||||
state-level adversary).
|
||||
|
||||
**What they can do:**
|
||||
|
||||
- Attempt TLS 1.3 MITM: TLS 1.3 prevents this if the client validates the
|
||||
server's certificate. However, quicnprotochat currently uses **self-signed
|
||||
certificates**, which means the client has no CA chain to verify. On the first
|
||||
connection, a MITM could present their own certificate and intercept the
|
||||
session (trust-on-first-use vulnerability).
|
||||
- Denial of service: drop or delay packets.
|
||||
- Traffic analysis: same as passive eavesdropper, with the added ability to
|
||||
inject timing perturbations.
|
||||
|
||||
**What they cannot do (assuming no cert MITM):**
|
||||
|
||||
- Decrypt TLS/Noise traffic: both use authenticated ephemeral key exchange.
|
||||
- Forge MLS messages: MLS Commits and application messages are signed by the
|
||||
sender's Ed25519 identity key. The attacker does not possess any member's
|
||||
signing key.
|
||||
- Inject members into MLS groups: adding a member requires a valid KeyPackage
|
||||
signed by the new member's identity key.
|
||||
|
||||
**Current weakness:** Self-signed TLS certificates. See
|
||||
[Known Gaps](#known-gaps).
|
||||
|
||||
### 3. Compromised Server
|
||||
|
||||
**Capabilities:** Full access to the server's memory, disk, and network
|
||||
interfaces. Can read all data stored on the server, modify server behavior,
|
||||
and observe all client connections.
|
||||
|
||||
**What the server sees:**
|
||||
|
||||
- Connection metadata: which clients connect, when, how often, from which IPs.
|
||||
- Ed25519 public keys: used as delivery queue indices. The server knows the
|
||||
public identity key of every registered client.
|
||||
- Message sizes and timing: the server forwards MLS messages and can observe
|
||||
their sizes and the timing of enqueue/fetch operations.
|
||||
- Encrypted MLS blobs: the server stores and forwards MLS ciphertext but cannot
|
||||
decrypt it (the server is MLS-unaware by design, per ADR-004).
|
||||
|
||||
**What the server cannot do:**
|
||||
|
||||
- **Decrypt message content:** The server does not hold any MLS group keys. MLS
|
||||
application messages are encrypted end-to-end between group members. The
|
||||
server sees only opaque ciphertext.
|
||||
- **Forge MLS messages:** MLS messages are signed by the sender's Ed25519 key.
|
||||
The server does not possess any member's signing key and cannot produce valid
|
||||
MLS signatures.
|
||||
- **Read past messages:** Even if the server stored old MLS ciphertext, it
|
||||
cannot decrypt it. Forward secrecy at the MLS layer (epoch key deletion)
|
||||
ensures that even compromising a member's state in the future does not reveal
|
||||
past epoch keys.
|
||||
|
||||
**What the server can do maliciously:**
|
||||
|
||||
- **Traffic analysis:** Correlate senders and recipients based on timing,
|
||||
message sizes, and queue access patterns.
|
||||
- **Selective denial of service:** Drop or delay specific messages or refuse
|
||||
service to specific clients.
|
||||
- **Metadata correlation:** Link Ed25519 public keys to IP addresses and
|
||||
connection patterns.
|
||||
- **Replay (limited):** Re-deliver an MLS message. MLS has replay protection
|
||||
via epoch numbers and message counters, so the recipient will reject the
|
||||
duplicate.
|
||||
- **KeyPackage manipulation:** Withhold or substitute KeyPackages during the
|
||||
join flow. If the server substitutes a KeyPackage, the resulting MLS group
|
||||
would include the attacker's key, but the legitimate member would not be able
|
||||
to join (they would not receive a matching Welcome). This is detectable.
|
||||
|
||||
### 4. Compromised Client
|
||||
|
||||
**Capabilities:** Full access to a group member's device, including the MLS
|
||||
group state, Ed25519 identity key, and any stored messages.
|
||||
|
||||
**What the attacker learns:**
|
||||
|
||||
- **Current epoch messages:** The attacker can decrypt all messages in the
|
||||
current MLS epoch from all group members (epoch keys are shared group secrets).
|
||||
- **Identity key:** The attacker obtains the member's Ed25519 signing key and
|
||||
can impersonate the member (sign messages, create KeyPackages).
|
||||
|
||||
**What the attacker cannot learn:**
|
||||
|
||||
- **Past epoch messages:** Protected by [forward secrecy](forward-secrecy.md).
|
||||
Old epoch keys have been deleted by openmls.
|
||||
- **Future epoch messages (after healing):** Protected by
|
||||
[post-compromise security](post-compromise-security.md). After the next
|
||||
Commit or Update, the ratchet tree is re-randomized and the attacker is
|
||||
locked out.
|
||||
|
||||
**Healing mechanism:**
|
||||
|
||||
1. The compromised member (or any other member) issues a Commit.
|
||||
2. The ratchet tree is updated with fresh key material.
|
||||
3. The attacker's stale state cannot derive the new epoch keys.
|
||||
4. The attacker is locked out of future epochs.
|
||||
|
||||
The healing window is the time between the compromise and the next Commit. See
|
||||
[Post-Compromise Security](post-compromise-security.md) for details.
|
||||
|
||||
## What Is Protected
|
||||
|
||||
| Asset | Protection Mechanism | Against |
|
||||
|-------|---------------------|---------|
|
||||
| Message content | MLS end-to-end encryption (AES-128-GCM) | All attacker models |
|
||||
| Message integrity | MLS signing (Ed25519) | Forgery by server or network |
|
||||
| Group membership changes | MLS Commits (signed, authenticated) | Unauthorized modification |
|
||||
| Key exchange material | Single-use HPKE init keys | Replay, forward compromise |
|
||||
| Transport confidentiality | TLS 1.3 + Noise\_XX (double encryption) | Passive eavesdropper |
|
||||
| Transport integrity | TLS 1.3 AEAD + Noise AEAD | Active network attacker |
|
||||
| Past messages | Forward secrecy (epoch key deletion) | Future client compromise |
|
||||
| Future messages | Post-compromise security (ratchet tree update) | Past client compromise |
|
||||
|
||||
## What Is NOT Protected (Current State)
|
||||
|
||||
| Asset | Visibility | Observer |
|
||||
|-------|-----------|----------|
|
||||
| Transport metadata (who connects, when) | IP addresses, connection timing | Network adversary, server |
|
||||
| Message timing and sizes | Observable in TLS records | Network adversary, server |
|
||||
| Recipient identity | Server routes by Ed25519 public key | Server |
|
||||
| Sender identity (partial) | Server can correlate connections to senders | Server |
|
||||
| Number of groups a client belongs to | Observable via message patterns | Server (with analysis) |
|
||||
| Client IP address | Visible in TCP/QUIC connection | Server, network adversary |
|
||||
|
||||
## Known Gaps
|
||||
|
||||
### Self-Signed TLS Certificates
|
||||
|
||||
The server uses self-signed TLS certificates generated at startup via `rcgen`.
|
||||
Clients currently accept any server certificate without CA chain validation.
|
||||
This makes the system vulnerable to a man-in-the-middle attack on the first
|
||||
connection: an attacker positioned between the client and server can present
|
||||
their own certificate and intercept all traffic.
|
||||
|
||||
**Impact:** Complete loss of transport confidentiality and integrity for affected
|
||||
connections. MLS content remains protected (the MITM cannot decrypt MLS
|
||||
ciphertext or forge MLS signatures), but the attacker can observe encrypted MLS
|
||||
blobs, perform traffic analysis, and potentially block or delay messages.
|
||||
|
||||
**Mitigation path:** Implement certificate pinning (trust-on-first-use) or
|
||||
integrate with a public CA (e.g., Let's Encrypt). Certificate transparency logs
|
||||
could provide an additional detection mechanism.
|
||||
|
||||
### No Client Authentication on the Delivery Service
|
||||
|
||||
The Delivery Service does not currently authenticate clients. Anyone who knows
|
||||
a recipient's Ed25519 public key can enqueue messages for that recipient. This
|
||||
enables spam and potential denial-of-service by flooding a recipient's queue.
|
||||
|
||||
**Impact:** Queue flooding, spam delivery. MLS provides its own authentication
|
||||
(the recipient will reject messages not signed by a group member), so forged
|
||||
content will not be accepted, but the recipient must still download and attempt
|
||||
to process the spam.
|
||||
|
||||
**Mitigation path:** The AUTHZ\_PLAN introduces token-based authentication,
|
||||
binding identityKey to accounts and requiring valid access tokens for all
|
||||
DS operations.
|
||||
|
||||
### No Rate Limiting
|
||||
|
||||
The server does not currently enforce per-client or per-IP rate limits. A
|
||||
malicious client could flood the server with requests, consuming resources and
|
||||
degrading service for other users.
|
||||
|
||||
**Impact:** Denial of service.
|
||||
|
||||
**Mitigation path:** The AUTHZ\_PLAN specifies per-IP and per-account/device
|
||||
rate limits (e.g., 50 requests/second, 5 MB payload cap).
|
||||
|
||||
### BasicCredential Only
|
||||
|
||||
MLS `BasicCredential` contains only the raw Ed25519 public key bytes. There is
|
||||
no certificate authority chain, no credential revocation mechanism, and no
|
||||
binding to a human-readable identity (e.g., phone number, email).
|
||||
|
||||
**Impact:** No way to verify that a public key belongs to a specific person
|
||||
without out-of-band verification (e.g., comparing fingerprints in person). An
|
||||
attacker who compromises the Authentication Service could substitute public keys.
|
||||
|
||||
**Mitigation path:** Implement X.509-based MLS credentials with a certificate
|
||||
chain, or integrate with a Key Transparency system that provides a verifiable
|
||||
log of public key bindings.
|
||||
|
||||
### Classical-Only Transport
|
||||
|
||||
As discussed in [Post-Quantum Readiness](post-quantum-readiness.md), the
|
||||
transport layer (TLS 1.3, Noise\_XX) uses classical-only cryptography. An
|
||||
adversary performing harvest-now-decrypt-later (HNDL) could record transport
|
||||
traffic today and decrypt it with a future quantum computer, revealing transport
|
||||
metadata.
|
||||
|
||||
**Impact:** Future exposure of transport metadata (not content, assuming
|
||||
hybrid KEM is active for MLS).
|
||||
|
||||
**Mitigation path:** Adopt post-quantum TLS (ML-KEM in TLS 1.3 handshake) when
|
||||
`rustls` supports it. Investigate post-quantum Noise patterns.
|
||||
|
||||
## Future Mitigations
|
||||
|
||||
### Sealed Sender
|
||||
|
||||
**Goal:** Hide the sender's identity from the server.
|
||||
|
||||
**Approach:** Encrypt the sender's identity inside the MLS ciphertext. The
|
||||
server cannot determine who sent a message -- it only knows the recipient
|
||||
(delivery queue index). Signal implements a version of this as "Sealed Sender."
|
||||
|
||||
**Benefit:** Reduces the server's metadata visibility from "who sent to whom"
|
||||
to "someone sent to this recipient."
|
||||
|
||||
### Private Information Retrieval (PIR)
|
||||
|
||||
**Goal:** Fetch messages without revealing the recipient's identity to the
|
||||
server.
|
||||
|
||||
**Approach:** Use PIR protocols (e.g., SealPIR, SimplePIR) to query the
|
||||
delivery queue without the server learning which queue was accessed.
|
||||
|
||||
**Benefit:** Combined with Sealed Sender, this would make the server metadata-blind:
|
||||
it would know only that "someone sent something to someone."
|
||||
|
||||
**Trade-off:** PIR is computationally expensive and may increase latency
|
||||
significantly, especially for large mailboxes.
|
||||
|
||||
### Key Transparency
|
||||
|
||||
**Goal:** Detect public key substitution attacks.
|
||||
|
||||
**Approach:** Publish all Ed25519 public keys in a verifiable, append-only log
|
||||
(similar to Certificate Transparency for TLS). Clients can audit the log to
|
||||
verify that their public key has not been replaced by an attacker.
|
||||
|
||||
**Benefit:** Detects attacks where the server (or an attacker who compromised
|
||||
the server) substitutes a victim's public key with the attacker's key.
|
||||
|
||||
### OPAQUE Authentication
|
||||
|
||||
**Goal:** Zero-knowledge password authentication.
|
||||
|
||||
**Approach:** Use the OPAQUE protocol (RFC 9497) for client-server
|
||||
authentication. OPAQUE allows the client to prove knowledge of a password
|
||||
without revealing it to the server, even during registration.
|
||||
|
||||
**Benefit:** The server never learns the client's password, preventing
|
||||
credential theft in a server compromise.
|
||||
|
||||
### Tor/I2P Integration
|
||||
|
||||
**Goal:** Hide client IP addresses from the server and network adversaries.
|
||||
|
||||
**Approach:** Route QUIC connections through the Tor network or I2P. The server
|
||||
sees only the Tor exit node's IP, not the client's real IP.
|
||||
|
||||
**Benefit:** Prevents the server and network adversaries from linking
|
||||
connections to physical locations or ISP accounts.
|
||||
|
||||
**Trade-off:** Significant latency increase. QUIC over Tor requires careful
|
||||
configuration to avoid leaking the real IP through WebRTC-style mechanisms.
|
||||
|
||||
### Padding and Traffic Shaping
|
||||
|
||||
**Goal:** Defeat traffic analysis based on message sizes and timing.
|
||||
|
||||
**Approach:** Pad all messages to fixed sizes (or random sizes from a
|
||||
distribution) and send dummy messages at regular intervals to mask real
|
||||
communication patterns.
|
||||
|
||||
**Benefit:** Makes it harder for network adversaries and the server to infer
|
||||
communication patterns from traffic analysis.
|
||||
|
||||
**Trade-off:** Increased bandwidth usage.
|
||||
|
||||
## Summary Table
|
||||
|
||||
| Threat | Current Protection | Gap | Planned Fix |
|
||||
|--------|-------------------|-----|-------------|
|
||||
| Passive eavesdropper | TLS + Noise + MLS (3 layers) | Traffic analysis | Padding, Tor |
|
||||
| Active MITM | TLS 1.3 + Noise\_XX | Self-signed certs | Cert pinning, CA |
|
||||
| Compromised server | MLS E2E encryption | Metadata visible | Sealed Sender, PIR |
|
||||
| Compromised client | FS + PCS | Current epoch exposed | Periodic Updates |
|
||||
| Spam/flooding | None | No auth on DS | AUTHZ\_PLAN |
|
||||
| Key substitution | None | BasicCredential only | Key Transparency |
|
||||
| Quantum adversary (content) | Hybrid KEM (M5+) | Pre-M5 messages | Deploy hybrid ASAP |
|
||||
| Quantum adversary (transport) | None | Classical TLS/Noise | PQ TLS, PQ Noise |
|
||||
|
||||
## Related Pages
|
||||
|
||||
- [Cryptography Overview](overview.md) -- algorithm inventory and security levels
|
||||
- [Forward Secrecy](forward-secrecy.md) -- protecting past messages
|
||||
- [Post-Compromise Security](post-compromise-security.md) -- protecting future messages
|
||||
- [Post-Quantum Readiness](post-quantum-readiness.md) -- ML-KEM-768 and the PQ gap
|
||||
- [Ed25519 Identity Keys](identity-keys.md) -- identity key used for MLS credentials
|
||||
- [Key Lifecycle and Zeroization](key-lifecycle.md) -- key destruction guarantees
|
||||
Reference in New Issue
Block a user