**Motivations:** - Partie connectée du skeleton accessible seulement si pairing satisfait + relais OK, avec page type skeleton (avatar, notifications). - Éviter « Aucun service disponible » : contrat présent en dur dans la page, transmis à l’iframe ; navigation évidente ou automatique vers login. - Sécuriser postMessage (origine UserWallet uniquement) ; déployer data sur le proxy et certificat data.certificator.4nkweb.com. - Vulgariser cryptographie (ECDH, AES-GCM, Schnorr, workflow, collecte signatures) ; documenter correctifs et architecture. **Root causes:** - Section connectée affichée sans vérifier pairing/relay ; possibilité de forger pairing-relay-status depuis la console. - Iframe masquée ou /login chargé avant réception du contrat → graphe vide, redirection vers /services. - Pas de contrôle d’origine sur les messages reçus ; pas de projet website-data ni config Nginx/certificat pour data. **Correctifs:** - Vérification msg.origin === USERWALLET_ORIGIN dans handleMessage (skeleton). - Si session mais pas pairingRelayStatus : afficher iframe pour réception du statut, message « Vérification du statut… ». - Contrat envoyé dès load iframe (init iframe.src = USERWALLET_ORIGIN) ; au clic « Se connecter », envoi contract + navigate-login (service, membre). - UserWallet : écoute navigate-login → navigation /login?service=&membre= ; LoginScreen avec service+membre en URL ne redirige plus vers /services, dispatch E_SELECT_SERVICE / E_SELECT_MEMBER. **Evolutions:** - Message pairing-relay-status (iframe → parent) ; canShowConnectedSection exige login + pairing OK + relay OK ; page connectée avec header avatar + icône notifications. - Skeleton : getLoginContext, sendNavigateLoginToIframe, onIframeLoad, loginRequested/iframeLoaded ; contrat envoyé avec serviceUuid, membreUuid. - UserWallet : PairingRelayStatusMessage, envoi depuis HomeScreen/LoginScreen ; type navigate-login, handleNavigateLogin dans useChannel. - Page cryptographie.html (workflow, algorithmes, collecte signatures) ; liens nav, build. - website-data (Vite, channel, config), start/service/install ; configure-nginx-proxy + Certbot pour data.certificator.4nkweb.com. - fixKnowledge (postmessage-origin, section-connectee-non-affichee) ; features (partie-connectee-pairing-relay, userwallet-iframe-key-isolation). **Pages affectées:** - website-skeleton (index, main, config, serviceContract, cryptographie, technique, membre, contrat, vite.config, README). - userwallet (HomeScreen, LoginScreen, useChannel, iframeChannel, relay, crypto, iframe, Pairing*, RelaySettings, WordInputGrid, syncUpdateGraph, specs/synthese). - website-data (nouveau), configure-nginx-proxy, docs DOMAINS_AND_PORTS README, features, fixKnowledge, userwallet features/docs.
35 lines
2.5 KiB
Markdown
35 lines
2.5 KiB
Markdown
# UserWallet iframe — cloisonnement des clés et du chiffrement
|
||
|
||
**Objectif**
|
||
|
||
Garantir qu’aucune clé secrète ne quitte l’iframe UserWallet et qu’aucune opération de signature ou de chiffrement n’est effectuée en dehors du domaine de l’iframe.
|
||
|
||
**Règles**
|
||
|
||
1. **Clés**
|
||
- Seules les **clés publiques** peuvent sortir de l’iframe (via postMessage vers le parent).
|
||
- Les clés privées (`privateKey`, `cle_privee`) ne doivent jamais être envoyées au parent ni à un autre domaine.
|
||
|
||
2. **Crypto**
|
||
- Toutes les opérations de **signature**, **chiffrement** et **déchiffrement** sont réalisées **uniquement dans l’iframe** (UserWallet).
|
||
- Le parent (site intégrateur, ex. skeleton) ne doit **jamais** signer, chiffrer ni déchiffrer. Il peut uniquement **vérifier** des signatures à l’aide des clés publiques (ex. `verifyLoginProof`).
|
||
|
||
**Implémentation**
|
||
|
||
- **iframeChannel** : `sendToChannel` appelle `assertNoSecretsInChannelPayload` avant `postMessage`. Toute présence de `privateKey` ou `cle_privee` dans le payload (récursif) lève une erreur ; le message n’est pas envoyé.
|
||
- **iframe.ts** : `sendMessageToParent` appelle aussi `assertNoSecretsInChannelPayload` sur le payload avant `postMessage`. Tous les envois vers le parent passent par cette vérification.
|
||
- **Messages envoyés au parent** : `auth-response` (signature, publicKey, message), `login-proof` (challenge, signatures avec `cle_publique`), `error`, `service-status`, `pairing-relay-status` (pairingSatisfied, relayOk). Aucun de ces messages ne contient de clé secrète.
|
||
- **Messages reçus du parent** : `auth-request`, `contract`. Le contrat peut contenir des `cle_publique` de service (validateurs) ; ce sont des clés publiques. Le parent n’envoie jamais de clé privée.
|
||
- **Parent (intégrateur)** : Ne doit jamais signer, chiffrer ni déchiffrer. Il peut uniquement **vérifier** des signatures (ex. `verifyLoginProof` avec clés publiques). Ex. skeleton : vérification uniquement, pas de crypto secrète.
|
||
|
||
**Contrôles**
|
||
|
||
- Avant tout envoi vers le parent : vérification systématique des payloads pour `privateKey` et `cle_privee`.
|
||
- Aucun usage de `privateKey` / `cle_privee` dans les types de messages définis pour le canal iframe (`AuthResponseMessage`, `LoginProofMessage`, etc.).
|
||
|
||
**Pages affectées**
|
||
|
||
- `userwallet/src/utils/iframeChannel.ts` (assertion, `sendToChannel`)
|
||
- `userwallet/src/utils/iframe.ts` (assertion, `sendMessageToParent`)
|
||
- `userwallet/features/userwallet-iframe-key-isolation.md` (ce document)
|