daef7ea190
Helper functions (matrix-mas capability group): - mas_client_register_bash_infra: register/sync OAuth clients via mas-cli - mas_syn2mas_migration_bash_infra: dry-run + apply user migration to MAS - synapse_msc3861_enable_go_infra: edit homeserver.yaml MSC3861 block (with diff) - wellknown_oidc_patch_go_infra: patch well-known JSON with msc2965.authentication - synapse_login_flows_check_go_infra: health-check post-migration login flows Flows + issues for custom Matrix clients (PC + Android): - 0010 matrix-client-pc: Wails + React+Mantine (issues 0147-0153) - 0011 matrix-client-android: Kotlin + Compose (issues 0154-0161) - 0162 enable MAS as auth provider (Synapse delegate) — EXECUTED on VPS - 0163 custom admin panel propio (sustituye synapse-admin) Production state (organic-machine.com): - Synapse migrated SQLite -> Postgres - MSC3861 active, password_config disabled - 21 users + 41 access_tokens migrated via syn2mas - 4 MAS clients registered (element, matrix_pc, matrix_android, admin_panel) - synapse-admin container removed + Coolify route deleted - well-known patched with org.matrix.msc2965.authentication Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
74 lines
3.8 KiB
Markdown
74 lines
3.8 KiB
Markdown
---
|
|
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.
|