--- id: "0150" title: "matrix-client-pc E2EE: cross-signing, SAS verification, recovery" status: pending priority: critical created: 2026-05-24 related_flows: ["0010"] related_issues: ["0149", "0151"] dependencies: ["0149"] tags: [matrix, e2ee, olm, megolm, cross-signing, recovery, security] --- ## Objetivo Encriptacion end-to-end con `mautrix-go` (Olm/Megolm). Cross-signing keys (master/self-signing/user-signing), SAS verification de devices (emoji + decimal), recovery passphrase + key backup en Synapse, manejo de devices no verificados con warning visible. Mensajes en rooms encriptados se envian y descifran correctamente. ## Tareas 1. Backend Go: - `MatrixService.BootstrapCrossSigning(passphrase)` — genera master/self/user keys, sube a Synapse cifradas con passphrase-derived key. - `MatrixService.RecoverFromPassphrase(passphrase)` — descarga keys de Synapse y descifra. - `MatrixService.StartVerification(userID, deviceID) -> *VerificationSession`. - `MatrixService.VerifyEmoji(sessionID, accepted bool)`. - `MatrixService.ListDevices() -> []Device` (con verified flag). - `MatrixService.BackupMegolmKeys()` — key backup server-side. - Crypto store SQLite separado del state store (mejor para integridad). 2. Frontend React: - Wizard onboarding E2EE: pasos (1) generar passphrase, (2) backup, (3) verificar device. - Panel `Settings > Security & Privacy`: - Lista devices propios con verified state. - Boton "Verify new device" + dialog SAS con emoji grid. - "Reset cross-signing" (destructive, requiere confirmacion). - "Restore from passphrase" (login en device nuevo). - `EventBubble` muestra shield: green (verified), amber (encrypted, device unverified), red (decryption failed). - Banner room: "X devices are not verified" si algun miembro tiene devices unverified. 3. Tests: - `e2e/test_e2ee_send_receive.sh` — msg enviado en room encriptado se descifra en Element Web. - `e2e/test_cross_signing.sh` — bootstrap + verificar device desde Element Web. - `e2e/test_recovery.sh` — login en device nuevo + recover keys con passphrase. - `e2e/test_unverified_warning.sh` — device nuevo aparece como warning en otros clientes. ## Funciones del registry a crear - `matrix_e2ee_bootstrap_go_infra` — wrapper cross-signing bootstrap. - `matrix_device_verify_go_infra` — SAS verification flow. - `matrix_key_backup_go_infra` — server-side key backup wrapper. - `passphrase_derive_key_go_infra` — PBKDF2/scrypt para derivar key de passphrase. - `VerificationDialog_ts_ui` — componente emoji grid SAS. ## Acceptance - [ ] Bootstrap cross-signing crea 3 keys + las sube a Synapse cifradas. - [ ] Msg enviado a room encriptado se descifra en Element Web (y al reves). - [ ] SAS verification con emoji grid funciona contra Element Web (ambos lados muestran 7 emojis iguales). - [ ] Login en device nuevo + restore con passphrase recupera msgs historicos. - [ ] Device no verificado dispara shield amber en EventBubble. - [ ] Decryption failure (key no disponible) muestra shield rojo + boton "Request key". ## Notas **Critico — anti-criterio:** - NO marcar done si E2EE silent-falla (msg muestra "** Unable to decrypt **" sin shield rojo claro). - NO marcar done si recovery passphrase queda en plain text en disco (debe vivir solo en keyring/memoria). **Decisiones:** - Olm/Megolm via `mautrix-go/crypto` (Go port estable de libolm). - Alternativa rust-crypto via CGo: descartada, mantiene complejidad build. - Passphrase format: 4 palabras Diceware o 12-byte base32. Usuario elige al bootstrap. **Gotchas:** - Key rotation: rooms encriptados rotan megolm cada 1 semana o 100 msgs (default). Manejar refresh. - Olm sessions max 100 mensajes: rotar prekey bundles automaticamente. - Cuando arrancas device nuevo sin passphrase, los msgs pre-existentes NO se descifran — UI debe ser clara.