# Delta `0.2.5-pre.009` — security / interoperability / compliance Wallet ## Base ```text 0.2.5-pre.8 ``` Le checkpoint opérateur de la base a validé sans warning : ```text cargo fmt --all cargo check --workspace cargo clippy --workspace --all-targets cargo test -p ksp-wallet-lib cargo test --workspace ``` Wallet : `54 passed / 1 ignored` en unit tests, `2/2` dependency boundary, `9/9` public API et `2/2` doctests. Le tree opérateur confirme aussi : ```text solana-keypair 3.1.2 -> parent KSP direct unique = ksp-wallet-lib ed25519-dalek 2.2.0 -> génération unique solana-address 2.7.0 -> génération unique partagée solana-pubkey / solana-keypair ``` Version workspace cible : ```text 0.2.5-pre.9 ``` ## Objectif Cette tranche ne change ni le wire `.kspwallet` V1 ni les primitives crypto. Elle ferme le gate technique avant `pre.010` : ```text adversarial tests security contract independent interoperability verification dependency/cargo-tree compliance normative Wallet rules known limitations made explicit ``` ## Canaris adversariaux Nouveau fichier : ```text crates/ksp-wallet-lib/unit_tests/security.rs ``` Il couvre : ```text OWNER KDF salt tampering -> wallet.authentication_failed OWNER wrap tampering -> wallet.authentication_failed owner-control tampering -> wallet.authentication_failed metadata tampering -> wallet.authentication_failed secret tampering -> wallet.authentication_failed state_signature tampering -> wallet.authentication_failed state invalid + empty password -> authentication_failed before Argon2 VIEW wrap tampering only -> OWNER state signature stays valid -> OWNER remains unlockable -> VIEW fails with view_unlock_failed wrong OWNER/VIEW password -> generic capability-specific errors -> no password echo in Display/Debug ``` Le test de priorité `state_signature invalide + password vide` matérialise le contrat anti-oracle : la signature OWNER est vérifiée avant tout KDF password. ## Frontière publique renforcée Le canari `dependency_boundary` vérifie désormais aussi : ```text pas de dépendance directe solana-signer pas de dépendance directe solana-signature pas de re-export public solana-keypair / solana-signer / solana-signature WalletView ne possède ni sign_message ni export_transfer WalletTransferFormat reste #[non_exhaustive] ``` `ksp-core-lib::Pubkey` reste le seul type Solana public transversal du domaine Wallet ; la keypair secrète reste encapsulée dans Wallet. ## Règles normatives Wallet `docs/rules/RULES_KSP.md` formalise maintenant : ```text KSP-WALLET-002 format V1 autonome, sans facteur/ancre externe obligatoire KSP-WALLET-003 indépendance VIEW / OWNER et capacité VIEW bornée KSP-WALLET-004 keypair immuable/encapsulée, Pubkey via Core KSP-WALLET-005 create/import no-clobber KSP-WALLET-006 chemins fournis par caller, aucun Config/env Wallet KSP-WALLET-007 état OWNER-signed + limites replacement/rollback total ``` ## Interopérabilité externe Une sonde indépendante hors Rust/KSP a été exécutée pendant la préparation du delta. Elle reproduit les fixtures publiques test-only avec une implémentation distincte : ```text Argon2id OWNER derived key exact Argon2id VIEW derived key exact XChaCha20-Poly1305 pre.004 wrapped key exact + unwrap exact Ed25519 state_signature vérifiée sur le state_transcript exact Base58 keypair 64 octets reproduite indépendamment Base58 Pubkey 32 octets reproduite indépendamment ``` La sonde n'est pas ajoutée au dépôt et ne devient aucune dépendance runtime. Elle utilise les primitives disponibles dans l'environnement Python de préparation et une construction HChaCha20 + ChaCha20-Poly1305 IETF pour le contrôle XChaCha. ## Réaudit crypto primaire Le gate réaudit les références primaires : ```text RFC 9106 Argon2id RFC 8032 Ed25519 RustCrypto chacha20poly1305 solana-keypair 3.1.2 tempfile 3.27 ``` RFC 9106 décrit `Argon2id, t=3, 64 MiB` comme seconde recommandation pour les environnements contraints, cohérente avec le profil de création KSP calibré en `pre.005` : ```text 64 MiB / 3 / 1 ``` Les paramètres restent sérialisés par slot ; ce default peut donc évoluer ultérieurement sans casser les wallets existants. ## Audit Cargo / doublons Le tree opérateur `pre.008` montre les doublons transitifs suivants : ```text block-buffer 0.10 / 0.12 cpufeatures 0.2 / 0.3 crypto-common 0.1 / 0.2 digest 0.10 / 0.11 getrandom 0.3 / 0.4 rand 0.9 / 0.10 rand_core 0.6 / 0.9 / 0.10 sha2 0.10 / 0.11 syn 2 / 3 ``` Verdict : acceptés comme transitifs des générations RustCrypto, Solana et Logging actuellement consommées. Wallet ne déclare pas plusieurs versions directes pour contourner les upstream. Les convergences critiques restent obtenues pour Dalek et `solana-address`. `solana-keypair 3.1.2` conserve un `unsafe` upstream dans son codec Base58 interne. KSP n'ajoute pas `bs58` uniquement pour dupliquer ce codec ; `#![forbid(unsafe_code)]` continue de s'appliquer au code KSP lui-même. ## Extensibilité transfer clarifiée `WalletTransferFormat` reste `#[non_exhaustive]` : les formats built-in sont additifs et les consumers ne peuvent pas considérer la liste comme définitivement fermée. `pre.009` ne crée pas de trait/plugin public arbitraire de codec : un adapter externe d'import/export devrait recevoir/retourner les 64 octets secrets de la keypair, ce qui créerait une nouvelle surface publique de secret. Un vrai besoin futur d'adapters tiers recevra un contrat dédié et audité plutôt qu'une abstraction V1 prématurée. ## Limites explicitement conservées Le verdict security est positif dans le threat model V1, sans revendiquer : ```text anti-rollback externe reconnaissance d'un remplacement intégral par un autre wallet valide CAS filesystem portable linéarisable atomicité/crash durability identique sur tous les OS/filesystems garantie cryptographique fondée sur 0600/ACL effacement physique absolu de toute copie mémoire protection hardware / OTP / keychain / remote signer ``` Ces limites doivent rester visibles dans `pre.010` et la release stable. ## Documentation durable Ajout : ```text docs/validation/008-V0_2_5_WALLET_SECURITY_COMPLIANCE.md ``` Mise à jour : ```text ROADMAP.md docs/000-README.md docs/formats/000-README.md docs/formats/KSPWALLET_V1.md docs/plans/012-V0_2_5_WALLET_FOUNDATION_PLAN.md docs/rules/RULES_KSP.md docs/validation/000-README.md ``` La prochaine tranche devient `pre.010` : documentation finale, README/USAGE de `ksp-wallet-lib`, synchronisation de clôture et prompt `0.2.6`. ## Nettoyage test Le double attribut `#[test]` accidentel devant `owner_and_view_slots_use_independent_kdf_material` est réduit à un seul attribut. Aucun comportement de production n'est modifié. ## Dépendances Aucune nouvelle dépendance tierce. ## Validation statique de préparation Le sandbox de préparation ne possède pas Cargo/Rust. Les contrôles statiques ont vérifié : - aucune dépendance nouvelle ; - aucun accès Config/Transport/Tauri/env/tracing direct/solana-pubkey direct ; - aucun `unsafe` dans les sources Wallet KSP ; - aucun changement du wire ni des fixtures ; - versions de fichiers modifiés incrémentées ; - archive delta limitée aux fichiers ajoutés/modifiés ; - reconstruction exacte du delta sur la base `pre.008` avant livraison. Une sonde crypto externe indépendante a en revanche réellement été exécutée comme indiqué plus haut. ## Validation opérateur requise ```bash cargo fmt --all cargo check --workspace cargo clippy --workspace --all-targets cargo test -p ksp-wallet-lib cargo test --workspace cargo tree -p ksp-wallet-lib cargo tree -p ksp-wallet-lib -d cargo tree -i ed25519-dalek@2.2.0 cargo tree -i solana-keypair@3.1.2 cargo tree -i solana-address@2.7.0 ``` ## Commit attendu ```text v0.2.5-pre.009 ```