ios_client

This commit is contained in:
Filip
2026-03-14 12:43:56 +01:00
parent 5fd80e6dd6
commit 214da18779
74 changed files with 13136 additions and 284 deletions

441
README.md
View File

@@ -1,333 +1,246 @@
<<<<<<< HEAD
# Kecalek_python
=======
# Encrypted Chat
End-to-end encrypted chat s forward secrecy (X3DH + Double Ratchet, Signal Protocol).
Server ukládá a přeposílá šifrované bloby — nikdy nevidí plaintext.
## Architektura
```
┌─────────────┐ TLS/TCP ┌─────────────┐ MySQL ┌─────────┐
│ GUI/CLI │◄───────────────►│ Server │◄──────────────►│ DB │
│ klient │ JSON + base64 │ (asyncio) │ │ │
└─────────────┘ └─────────────┘ └─────────┘
│ │
│ X3DH + Double Ratchet │ Opaque blobs
│ Sender Keys (skupiny) │ (server nevidí plaintext)
▼ ▼
Lokální klíče Šifrované zprávy
(~/.encrypted_chat/) + metadata
```
## Soubory
### Server
| Soubor | Účel |
|--------|------|
| `server.py` | Asyncio TCP server, handler dispatch, rate limiting, notifikace |
| `db.py` | MySQL CRUD, jedna connection na volání |
| `schema.sql` | MySQL schéma (users, conversations, messages, ...) |
| Soubor | Řádky | Účel |
|--------|-------|------|
| `server.py` | ~2 900 | Asyncio TCP server, 45 handlerů, rate limiting, 5 asyncio.Lock guardů, real-time notifikace |
| `db.py` | ~1 700 | MySQL CRUD, connection pooling (pool_size=10), phantom users, reactions/pins CRUD |
| `schema.sql` | ~190 | MySQL schéma (14 tabulek) |
### Klient
| Soubor | Účel |
|--------|------|
| `gui_client.py` | PyQt6 GUI |
| `client.py` | CLI klient |
| `chat_core.py` | Logika klienta — session management, šifrování, lokální klíče |
| Soubor | Řádky | Účel |
|--------|-------|------|
| `gui_client.py` | ~6 300 | PyQt6 GUI — dark/light téma, widget-based message bubbles, verifikace kontaktů, privacy overlay |
| `client.py` | ~900 | CLI klient — 23 menu opcí |
| `chat_core.py` | ~3 500 | Sdílená logika — session management, X3DH/ratchet šifrování, lokální klíče, multi-device |
| `theme.py` | ~540 | Catppuccin dark + Signal-inspired light téma, live switching |
### Sdílené (server + klient)
| Soubor | Účel |
|--------|------|
| `crypto_utils.py` | Ed25519, X25519, AES-256-GCM, HKDF, PBKDF2, X3DH, Double Ratchet (state rollback), Sender Keys (state rollback), ECP1 key encryption |
| `protocol.py` | Newline-delimited JSON protokol, base64 encoding |
| `crypto_utils.py` (~935 ř.) | Ed25519, X25519, AES-256-GCM, HKDF, PBKDF2, X3DH, Double Ratchet (state rollback), Sender Keys (state rollback), ECP1 key encryption, contact verification (fingerprints, safety numbers, QR), message padding |
| `protocol.py` (~140 ř.) | Newline-delimited JSON protokol, base64 encoding, verze (0.8.4) |
### iOS klient
| Složka | Účel |
|--------|------|
| `ios_client/` (47 Swift souborů, ~5 000 ř.) | Nativní iOS port — CryptoKit + pure Swift GF(2^255-19) + Security.framework RSA, SwiftUI views, wire-kompatibilní s Python serverem |
### Testy
| Soubor | Účel |
|--------|------|
| `tests/pentest_client.py` (~340 ř.) | Automatizované security regresní testy (AuthZ, malformed headers, session reset, rate limits) |
## Quick Start
1. `pip install -r requirements.txt`
2. Spustit `schema.sql` v MySQL (kompletní clean start). Pro migraci existující DB: `migration_multi_device.sql`.
2. Spustit `schema.sql` v MySQL
3. `python server.py`
4. Klient: `python client.py` (CLI) nebo `python gui_client.py` (GUI, PyQt6)
4. Klient: `python gui_client.py` (GUI) nebo `python client.py` (CLI)
## Jak funguje šifrování
### Klíče na uživatele
| Klíč | Typ | Účel |
|------|-----|------|
| RSA-4096 | Asymetrický | Pouze login challenge-response. Šifrovaný PBKDF2 (600k iterací) + AES-256-GCM. |
| Identity Key (IK) | Ed25519 | Podpisy, konverze na X25519 pro X3DH. Šifrovaný PBKDF2 (600k iterací) + AES-256-GCM. |
| Signed Pre-Key (SPK) | X25519 | DH v X3DH, podepsaný IK. **Rotuje se každých 7 dní** s grace periodem pro in-flight X3DH. |
| One-Time Pre-Keys (OPK) | X25519 | Jednorázové, spotřebuje se při X3DH, automaticky doplňované (< 20 → +50) |
| RSA-4096 | Asymetrický | Pouze login challenge-response. Šifrovaný ECP1 (PBKDF2 600k + AES-256-GCM). |
| Identity Key (IK) | Ed25519 | Podpisy, konverze na X25519 pro X3DH. Šifrovaný ECP1. |
| Signed Pre-Key (SPK) | X25519 | DH v X3DH, podepsaný IK. **Rotuje se každých 7 dní** s grace periodem. |
| One-Time Pre-Keys (OPK) | X25519 | Jednorázové, spotřebuje se při X3DH, automaticky doplňované (< 20 → +50). |
### DM (1:1 zprávy) — X3DH + Double Ratchet
1. Alice chce napsat Bobovi poprvé → stáhne jeho key bundle (IK, SPK, OPK) ze serveru.
2. X3DH: 4 DH výpočty → shared secret.
3. Double Ratchet inicializován ze shared secret.
4. Každá zpráva: symmetric ratchet (HMAC chain) → message key → AES-256-GCM.
5. Každá odpověď: DH ratchet (nový X25519 keypair) → nový root key + chain key.
6. Per-recipient ciphertext — každý recipient má vlastní šifrovaný blob.
7. Při selhání dešifrování: automatický rollback stavu ratchetu (snapshot/restore).
1. Alice stáhne Bobovy per-device key bundles (IK, SPK, OPK) → X3DH per device → shared secret per device.
2. Double Ratchet inicializován ze shared secret — jedna session per (user, device).
3. Každá zpráva: symmetric ratchet (HMAC chain) → message key → AES-256-GCM.
4. Každá odpověď: DH ratchet (nový X25519 keypair) → nový root key + chain key.
5. Per-device ciphertext — každé zařízení příjemce dostane individuálně šifrovaný blob.
6. Self-encrypted kopie s SELF_DEVICE_ID sentinel, čitelná všemi vlastními zařízeními.
### Skupiny — Sender Keys
1. Každý člen má vlastní sender key chain pro skupinu.
2. Sender key se distribuuje ostatním členům přes pairwise Double Ratchet (jako DM).
1. Každý odesílatel má vlastní SenderKeyState per group.
2. Sender key distribuován členům přes pairwise Double Ratchet (jako control DM).
3. Skupinové zprávy: symmetric ratchet na sender key → AES-256-GCM.
4. Jeden ciphertext pro celou skupinu (efektivní).
4. Stejný ciphertext pro všechny příjemce (efektivní).
### Kontaktní verifikace (Signal-style)
- **Safety numbers** — 60-digit číslo (12 skupin × 5 číslic), deterministické pro každý pár.
- **QR kódy** — binární payload zakódovaný jako base64.
- **Fingerprints** — 30-digit per-user číslo.
- **TOFU** — Trust On First Use + explicit verification + key change warning.
### Lokální úložiště klíčů
```
~/.encrypted_chat/{email}/
private.pem # RSA (login) — ECP1 formát s heslem, PEM bez hesla
public.pem # RSA (login)
identity_private.bin # Ed25519 — ECP1 formát s heslem, 32B raw bez hesla
identity_public.bin # Ed25519
device_id.txt # UUID tohoto zařízení
spk_private.bin # Aktuální signed prekey (šifrovaný AES-256-GCM)
spk_id.txt
prev_spk_private.bin # Předchozí SPK, grace period (šifrovaný AES-256-GCM)
prev_spk_id.txt
opk_private/ # One-time prekeys (šifrované AES-256-GCM)
{opk_id}.bin
login_lockout.json # Brute-force lockout stav (failed_attempts, locked_until)
sessions/ # Double Ratchet stavy (šifrované AES-256-GCM)
{user_id}_{device_id}.bin
sender_keys/ # Vlastní sender keys pro skupiny
{conv_id}.bin
sender_keys_recv/ # Přijaté sender keys od ostatních
{conv_id}_{sender_id}_{device_id}.bin
private.pem / public.pem RSA (login, ECP1 formát)
identity_private.bin / _public.bin — Ed25519 (ECP1 formát)
device_id.txt — UUID tohoto zařízení
spk_private.bin / spk_id.txt — Aktuální SPK (AES-256-GCM)
prev_spk_private.bin / prev_spk_id.txt — Předchozí SPK, grace period
opk_private/{opk_id}.bin — One-time prekeys (AES-256-GCM)
sessions/{uid}_{did}.bin — Double Ratchet stavy (AES-256-GCM)
sender_keys/{conv_id}.bin — Vlastní sender keys
sender_keys_recv/{conv}_{uid}_{did}.bin — Přijaté sender keys
known_identity_keys.bin — TOFU registr (AES-256-GCM)
verified_contacts.bin — Explicitní verifikace (AES-256-GCM)
message_cache/{conv_id}.bin — Šifrovaný message cache
login_lockout.json — Brute-force lockout stav
```
## Bezpečnostní hardening
### Šifrování privátních klíčů na disku (ECP1 formát)
RSA a Ed25519 privátní klíče šifrované heslem používají vlastní formát ECP1 (Encrypted Chat PBKDF v1):
- **PBKDF2-HMAC-SHA256** s 600 000 iteracemi (OWASP 2023 doporučuje 480k+)
- **AES-256-GCM** pro šifrování, magic bytes "ECP1" jako AAD
### Šifrování privátních klíčů (ECP1 formát)
- **PBKDF2-HMAC-SHA256** s 600 000 iteracemi (OWASP 2023)
- **AES-256-GCM**, magic bytes "ECP1" jako AAD
- **Formát:** `ECP1(4B) + salt(16B) + nonce(12B) + ciphertext+tag`
- **Zpětná kompatibilita:** Staré PEM soubory (z `BestAvailableEncryption`) se načtou automaticky a při dalším uložení se přešifrují do ECP1.
- Zpětná kompatibilita: staré PEM se migrují automaticky
### Šifrování SPK/OPK na disku
SPK a OPK privátní klíče jsou šifrované AES-256-GCM klíčem `_local_key` (HKDF z Ed25519 identity key):
- Při save: `_encrypt_local(raw, local_key)``nonce(12B) + tag(16B) + ciphertext`
- Při load: `_decrypt_local()` s transparentní migrací — pokud dešifrování selže, načte jako plaintext a uloží šifrovaně
- Aplikováno na `spk_private.bin`, `prev_spk_private.bin`, `opk_private/*.bin`
### Lokální šifrování dat
- Session/sender key soubory, OPK, SPK, message cache, verifikační soubory — AES-256-GCM klíčem z HKDF(identity_key)
- `chmod 0o700` na adresáře, `0o600` na soubory
### Brute-force ochrana (client-side lockout)
Po chybném zadání hesla se prodlužuje čas do dalšího pokusu:
- **Vzorec:** `min(2^N, 300)` sekund, kde N = počet neúspěšných pokusů (2s, 4s, 8s, ... až 5 min)
- **Stav:** `login_lockout.json` v adresáři klíčů (`failed_attempts`, `locked_until`)
- **Aplikováno na:** `ChatClient.login()` (síťový login) + GUI privacy overlay unlock (`_on_unlock_attempt`)
- **Reset:** Úspěšné přihlášení smaže lockout soubor
- **Defense-in-depth:** Smazání souboru resetuje počítadlo, ale PBKDF2-600k stále zpomaluje každý pokus (~0.5s/pokus)
### Brute-force ochrana
- Exponenciální backoff: `min(2^N, 300)` sekund po N chybných pokusech
- Aplikováno na login + privacy overlay unlock
### SPK rotace (7 dní)
Signed Pre-Key se rotuje periodicky:
- Po přihlášení `_ensure_prekeys()` zjistí stáří SPK ze serveru (`spk_created_at`)
- Pokud je SPK starší než 7 dní → vygeneruje nový, starý uloží jako grace period
- **Grace period:** `prev_spk_private.bin` — pokud příchozí X3DH selže s aktuálním SPK, zkusí předchozí
- Omezuje dopad kompromitace SPK — útočník může vytvářet nové sessions max 7 dní
- Automatická rotace s grace periodem pro in-flight X3DH
- Omezuje dopad kompromitace SPK
### Odolnost ratchetu (state rollback)
Double Ratchet i Sender Keys automaticky rollbackují stav při selhání dešifrování:
- Před modifikací chain keys/counters se vytvoří snapshot
- Pokud AES-GCM dešifrování selže (corrupted data, wrong key), stav se obnoví
- Session zůstane funkční i po zpracování poškozené zprávy
### Ratchet state rollback
- Snapshot/restore při selhání dešifrování (DoubleRatchet + SenderKeyState)
## Registrace
### Secure deletion
- Overwrite `os.urandom()` + `fsync` + `unlink` na smazané citlivé soubory
1. `register` → server pošle 6-místný kód na email (nebo vrátí přímo v dev módu bez SMTP).
2. `register_confirm` → potvrzení kódu.
3. Automaticky se vygenerují a uploadnou prekeys (1 SPK + 50 OPKs).
4. Login.
### Message padding
- Bucketed padding (64B64KB) maskuje délku zpráv
### Metadata privacy
- Log sanitizace (žádná PII), metadata retention (90 dní), sender chain minimalizace
### Anti-enumeration
- Phantom users pro neregistrované emaily
- Generické odpovědi na register/login/get_user_info
## Multi-Device Support
Pravý multi-device (Signal-like) — každé zařízení má nezávislé Double Ratchet sessions.
Při posílání DM se zpráva šifruje zvlášť pro každé zařízení příjemce.
Všechna zařízení uživatele sdílejí Ed25519 identity key (pro self-encryption kompatibilitu).
### Architektura
- **Devices tabulka** — každé přihlášení registruje device (UUID), server mapuje writer→device
- **Per-device prekeys** — každé zařízení má vlastní SPK + OPKs, server vrací `device_bundles` pole
- **Per-device sessions** — sessions klíčované `"user_id:device_id"`, nezávislé Double Ratchet instance
- **Self-encryption** — odesílatel šifruje vlastní kopii statickým klíčem z identity key (čitelné všemi vlastními zařízeními)
- **Notifikace** — `device_entries` pole, klient vybere záznam odpovídající svému device_id
- **Devices tabulka** — každé přihlášení registruje device (UUID)
- **Per-device prekeys** — každé zařízení má vlastní SPK + OPKs
- **Per-device sessions** — klíčované `"user_id:device_id"`
- **Self-encryption** — statický klíč z identity key (čitelné všemi vlastními zařízeními)
- **Pairing** — přenos RSA + Ed25519, nové zařízení generuje vlastní SPK + OPKs
### Device Pairing (zjednodušený)
## Features
Nové zařízení získá RSA + Ed25519 identity klíče od existujícího zařízení.
Přenos šifrovaný RSA-OAEP + AES-GCM přes server (server nevidí klíče).
Nové zařízení si po přihlášení automaticky vygeneruje vlastní SPK + OPKs.
### Protokol & šifrování
- X3DH + Double Ratchet (DM) s forward secrecy
- Sender Keys (skupiny) s distribucí přes pairwise ratchet
- Per-device šifrování (multi-device)
- SPK rotace (7 dní) + grace period
- Ratchet state rollback při selhání
- ECP1 šifrování klíčů (PBKDF2 600k)
- Message padding (bucketed 64B64KB)
- Kontaktní verifikace (safety numbers, fingerprints, QR kódy)
1. Nové zařízení: `Link Device` → dostane 8-místný kód.
2. Existující zařízení: `Authorize Device` → zadá kód → odešle RSA + identity klíče.
3. Nové zařízení importuje klíče, přihlásí se, vygeneruje vlastní prekeys.
### Komunikace
- DM + skupinové konverzace
- Reakce na zprávy (thumbsup, heart, laugh, surprised, sad, thumbsdown)
- Přeposílání zpráv (text, obrázky, soubory)
- Připnuté zprávy (pin/unpin + dialog)
- @Mentions s autocomplete
- Odpovědi na zprávy (reply_to)
- Hledání zpráv (client-side, Ctrl+F)
- Šifrované obrázky (AES-256-GCM, chunked upload, thumbnail)
- Šifrované soubory (až 50 MB, chunked upload)
- Read receipts (real-time)
### Migrace
- Existující DB: spustit `migration_multi_device.sql` (nebo `migration_multi_device_resume.sql` pro idempotentní re-run)
- Čistá DB: `schema.sql` již obsahuje všechny multi-device sloupce
### Skupiny
- Skupinové pozvánky (accept/decline)
- Leave group + přenos creatora
- Rename group (creator only)
- Delete conversation (DMs per-user, groups creator-only)
- Group avatar
## Device Revocation (Key Rotation)
### Správa
- Multi-device support (per-device sessions, pairing)
- User profily (telefon, lokace, avatar, viditelnost)
- Online/offline status
- Session reset (při poškození ratchetu)
- Key rotation (revokace zařízení)
- Brute-force lockout
Rotuje RSA login klíč. Odpojí ostatní sessions. Forward secrecy zajišťuje, že kompromitace
jednoho session klíče neodhalí historii — není potřeba re-encryption.
### GUI (PyQt6)
- Dark (Catppuccin Mocha) + Light (Signal) téma s live switching
- Widget-based message bubbles s ConversationDelegate
- Cirkulární avatary + online zelená tečka
- Unread count badges
- Privacy overlay / lock screen (30s timeout + heslo)
- Drag & drop souborů
- Frameless dialogy
- Connection indicator (green/red/orange) + auto-reconnect
- VerificationDialog (safety numbers, QR, fingerprints)
- Key change warning dialog
### CLI
- 23 menu opcí (DM, skupiny, soubory, reakce, piny, forwarding, verifikace, zařízení, search)
### iOS (SwiftUI)
- Wire-kompatibilní s Python serverem
- Kompletní Signal Protocol (X3DH, Double Ratchet, Sender Keys)
- CryptoKit + pure Swift field arithmetic + Security.framework RSA
- SwiftUI views (login, chat, groups, profiles, search)
## Konfigurace
### Server + DB
- `SERVER_HOST` (default `127.0.0.1`), `SERVER_PORT` (default `9999`)
- `MYSQL_HOST`, `MYSQL_PORT`, `MYSQL_USER`, `MYSQL_PASSWORD`, `MYSQL_DATABASE`
- `DB_POOL_SIZE` (default `10`)
### TLS
- `TLS_ENABLED` — zapne TLS (default `false`)
- `TLS_REQUIRED` — vyžaduje TLS_ENABLED, jinak server odmítne start
- `TLS_CERT_FILE`, `TLS_KEY_FILE` — cesty k certifikátu a privátnímu klíči (PEM)
- `TLS_REQUIRED` — vyžaduje TLS_ENABLED
- `TLS_CERT_FILE`, `TLS_KEY_FILE` — cesty k certifikátu (PEM)
- `TLS_AUTOGEN` — auto-generuje self-signed cert (**jen s `ENVIRONMENT=dev`**)
- `TLS_CA_FILE` (klient) — vlastní CA certifikát pro ověření serveru
- `TLS_CA_FILE` (klient) — vlastní CA certifikát
- `TLS_INSECURE` (klient) — vypne ověření certifikátu (**jen s `ENVIRONMENT=dev`**)
- `ENVIRONMENT``dev`/`development` povolí TLS_INSECURE a TLS_AUTOGEN
#### Produkční nasazení s Let's Encrypt
```bash
# 1. Nainstalovat certbot
sudo apt install certbot
# 2. Získat certifikát (port 80 musí být volný pro ověření)
sudo certbot certonly --standalone -d chat.example.com
# 3. V .env nastavit:
TLS_ENABLED=true
TLS_CERT_FILE=/etc/letsencrypt/live/chat.example.com/fullchain.pem
TLS_KEY_FILE=/etc/letsencrypt/live/chat.example.com/privkey.pem
# 4. Klient — stačí zapnout TLS (Let's Encrypt je v systémovém trust store):
TLS_ENABLED=true
```
Certifikát funguje na jakémkoliv portu (9999, 443, ...) — je vázaný na doménu, ne port. Certbot automaticky obnovuje certifikát každých 90 dní.
#### Dev/testování (self-signed)
```bash
ENVIRONMENT=dev
TLS_ENABLED=true
TLS_AUTOGEN=true # server auto-generuje self-signed cert
TLS_INSECURE=true # klient přeskočí ověření certifikátu
```
### SMTP
- `SMTP_HOST`, `SMTP_PORT`, `SMTP_USER`, `SMTP_PASS`, `SMTP_FROM`
- Bez SMTP = dev mód (kód se vrací přímo klientovi).
### Obrázky
- `UPLOAD_DIR` (default `uploads`), `MAX_IMAGE_BYTES` (default 5 MB, `0` = bez limitu)
- Bez SMTP = dev mód (kód se vrací přímo klientovi)
### Limity
- `MAX_MESSAGE_BYTES` (default `65536`), `MAX_INPUT_CHARS` (GUI, default `2000`)
- Rate limity: register 3/min, login 10/min, send_message 20/min, pairing_poll 10/min
- Connection: 20 req/s per connection, max 10 per IP, 200 global
- Pairing TTL: 120s, max 5 failed poll pokusů
- `MAX_MESSAGE_BYTES` (default `65536`), `MAX_IMAGE_BYTES` (5 MB), `MAX_FILE_BYTES` (50 MB)
- `MAX_INPUT_CHARS` (GUI, default `2000`)
- `METADATA_RETENTION_DAYS` (default `90`)
- Rate limity: register 3/min, login 10/min, send_message 20/min
- Connection: 20 req/s, max 10/IP, 200 global
### Logging
- `LOG_LEVEL` (default `INFO`)
## Features
- Registrace (2-step, SMTP), login (RSA challenge-response), key rotation
- **Multi-device** — per-device sessions (Signal-like), device pairing (RSA + identity key transfer), automatické prekey generování na novém zařízení
- DM s forward secrecy (X3DH + Double Ratchet) — per-device šifrování
- Skupiny se Sender Keys (distribuované přes pairwise ratchet)
- Skupinové pozvánky — přidání do skupiny vyžaduje souhlas (accept/decline)
- Odpovědi na zprávy (reply_to)
- Mazání zpráv (soft-delete pro všechny, real-time notifikace)
- Mazání konverzací (pravý klik → smaže pro uživatele, pokud nezbývají členové smaže celou konverzaci)
- Šifrované obrázky (AES-256-GCM, chunked upload, thumbnail v bublině)
- Šifrované soubory (PDF, ZIP, atd. až 50 MB, chunked upload)
- Read receipts (real-time, client-side resoluce)
- Prekey replenishment (automatické doplňování OPKs po loginu + SPK rotace každých 7 dní)
- Silné šifrování klíčů na disku (PBKDF2 600k iterací + AES-256-GCM, ECP1 formát)
- Odolný ratchet — automatický rollback stavu při selhání dešifrování
- TLS (volitelný, auto-gen self-signed)
- Real-time notifikace konverzací — nové konverzace, přidání/odebrání členů se zobrazí okamžitě bez re-loginu
- Connection state indicator — zelená/červená/oranžová tečka, automatický reconnect s exponential backoff
- Online/offline status — zelená tečka na avataru v seznamu konverzací + v group info
- User profily — telefon, lokace, avatar, nastavení viditelnosti (email, telefon, lokace)
- Phantom users — anti user-enumeration: konverzace s neregistrovaným emailem funguje normálně (odesílatel vidí své zprávy), zprávy pro phantom příjemce se neukládají, phantom se smaže při skutečné registraci
- Clickable links — HTTPS modré, HTTP oranžové s ikonou zámku + potvrzovací dialog
### GUI (PyQt6)
- Dark theme (Catppuccin Mocha)
- Seznam konverzací s kulatými avatary a online indikátorem (zelená tečka)
- Unread count badge na konverzacích (číselný počet nepřečtených zpráv)
- Message bubliny s barevným left border, timestamp vedle jména
- Read receipts (checkmarks), group info dialog, add/remove member
- Context menu: reply, delete, view image, download file
- Attach button pro obrázky a soubory, thumbnail v bublině, full-size viewer + save
- Pagination ("Load older messages")
- Connection indicator (zelená=online, červená=offline, oranžová=reconnecting)
- Auto-reconnect s exponential backoff (1s → 2s → 4s → ... → max 30s)
- Tlačítko "My Profile" — editace vlastního profilu (telefon, lokace, avatar, viditelnost)
- User profil dialog — klik na info tlačítko v group info → read-only profil uživatele
- Avatar upload/download (JPEG/PNG, max 2 MB, kruhový výřez)
- Leave group (červené tlačítko v group info, přenos creatora)
- Pozvánky do skupin — seznam pending pozvánek nad konverzacemi, pravý klik → accept/decline
- Periodický refresh avatarů a pozvánek (každé 2 minuty)
### CLI
- Základní funkcionalita (DM, skupiny, šifrování). Profily a soubory pouze přes GUI.
## Závislosti
- `cryptography` — Ed25519, X25519, AES-GCM, RSA, HKDF, PBKDF2
- `mysql-connector-python` — MySQL
- `python-dotenv` — env vars
- `PyQt6` — GUI
- `Pillow` — resize/thumbnail obrázků
## Known Issues
- Sender Keys pro skupiny se nedistribuují znovu při přidání nového člena (nový člen neuvidí staré skupinové zprávy).
## TODO
### Security — Zbývající
- [ ] **H9: Self-encryption key** — statický/deterministický klíč (by-design pro cross-device, architektonické omezení)
- [ ] M1: Nekonzistentní Ed25519 serializace (částečně vyřešeno M3 — ECP1 formát, ale 3 legacy formáty)
- [ ] M6: TOCTOU race v membership checks
- [ ] M7: MySQL spojení bez TLS
- [ ] L1-L8: Low-priority hardening
- [ ] **Penetrační testy** — manuální + automatizované
### Features — High Priority
- [ ] Redistribuce sender keys při přidání nového člena do skupiny
- [ ] Typing indicators
### Features — Medium Priority
- [ ] Hledání zpráv v konverzacích
- [ ] Group admin roles (více adminů)
- [ ] Edit sent messages
### Features — Low Priority
- [ ] Dark/light theme toggle
- [ ] Desktop notifications (system tray)
- [ ] Database connection pooling
- [ ] Image gallery view
- [ ] Systemd + Docker deployment
### Monetizace
Oddělený platební server (Stripe, KYC/AML compliant) od chat serveru (anonymní). Platba → premium kód → aktivace na chat serveru. Žádný přímý link platba↔chat identita.
- **Free tier:** 5 konverzací, 10 MB soubory, 1 zařízení, 30 dní retence, max 10 členů/skupina
- **Premium:** neomezeno — aktivace jednorázovým kódem z platebního serveru
- **Enterprise:** self-hosted, LDAP/SSO, admin dashboard, SLA — faktura na firmu
- Detaily implementace viz `CLAUDE.md`
### Hotovo — Security
- [x] **C1-C6: Všechny CRITICAL opraveny** — readuntil DoS, sender key fast-forward, OPK permissions, upload size check, path traversal (UUID validace + is_relative_to)
- [x] **H1-H8, H10-H14: Většina HIGH opravena** — lokální šifrování dat (AES-256-GCM), TLS hardening (INSECURE/AUTOGEN jen v dev), anti-enumeration, race conditions (asyncio.Lock), protokol error handling, avatar path traversal, hesla v paměti (bytearray+zero), image validace, filename sanitizace, OPK race condition (SELECT FOR UPDATE)
- [x] **M2-M5+M8-M13: Většina MEDIUM opravena** — HKDF salt, PBKDF2 600k iterací (ECP1 formát), SPK rotace 7 dní s grace periodem, rate limit cleanup, UUID validace, ratchet state rollback, message_ids cap, pairing poll token, upload check, chmod 0o700/0o600
- [x] **SPK/OPK šifrování + brute-force lockout** — všechny privátní klíče na disku šifrované (ECP1 nebo AES-256-GCM), exponenciální backoff po chybném hesle (2^N s, max 5 min)
### Hotovo — Features
- [x] **Multi-device support** — per-device sessions (Signal-like), device pairing, automatické prekey generování
- [x] Unread counts pro offline uživatele
- [x] Clickable HTTP links — HTTPS modré, HTTP oranžové s varováním
- [x] User profily (telefon, lokace, avatar, viditelnost)
- [x] Connection state indicator + auto-reconnect
- [x] Encrypted file sharing (až 50 MB)
- [x] Leave group + přenos creatora
- [x] Unread count badge
- [x] User avatars (upload/download, kruhový výřez)
- [x] Online/offline status (zelená tečka na avataru)
- [x] Mazání konverzací
- [x] Skupinové pozvánky (accept/decline)
- [x] Graceful server shutdown
## Bezpečnostní audit
Dva bezpečnostní audity provedeny (kód review). Nalezeno 6 CRITICAL, 12 HIGH, 12 MEDIUM, 8 LOW nálezů.
@@ -336,8 +249,22 @@ Dva bezpečnostní audity provedeny (kód review). Nalezeno 6 CRITICAL, 12 HIGH,
|-----------|--------|----------|-------|
| CRITICAL | 6 | **6** | 0 |
| HIGH | 12 | **11** | 1 (H9 — by-design) |
| MEDIUM | 12 | **10** | 2 (M1 částečně, M6, M7) |
| LOW | 8 | 0 | 8 |
| MEDIUM | 12 | **11** | 1 (M7) |
| LOW | 8 | **1** | 7 |
Detaily viz `CLAUDE.md`.
>>>>>>> d506e65 (initial commit)
Detaily viz `SECURITY_AUDIT.md` a `CLAUDE.md`.
## Known Issues
- **Sender Key Redistribution:** Nový člen skupiny nedešifruje staré skupinové zprávy (sender keys se nedistribuují znovu při přidání).
- **iOS: Contact Key Verification** — safety numbers, QR kódy, TOFU zatím neimplementovány v iOS klientu.
## Závislosti
- `cryptography` — Ed25519, X25519, AES-GCM, RSA, HKDF, PBKDF2
- `mysql-connector-python` — MySQL s connection pooling
- `python-dotenv` — env vars
- `PyQt6` — GUI
- `Pillow` — resize/thumbnail obrázků
- `qrcode` — generování QR kódů
- `pyzbar` (volitelné) — skenování QR kódů