Files
khadhroony-solana-project/docs/validation/008-V0_2_5_WALLET_SECURITY_COMPLIANCE.md
2026-08-20 09:24:10 +02:00

12 KiB

Validation 0.2.5 — Wallet security / interoperability / compliance

1. Objet

Cette matrice ferme le gate technique de 0.2.5-pre.009 avant la documentation finale pre.010. Elle ne remplace ni la spécification ../formats/KSPWALLET_V1.md, ni le threat model du plan ../plans/012-V0_2_5_WALLET_FOUNDATION_PLAN.md, ni les deltas.

Le verdict recherché porte sur quatre axes :

security/adversarial
interoperability indépendante
frontières KSP
Cargo/dependency compliance

2. État fonctionnel audité

Au gate pre.009, Wallet possède :

format autonome .kspwallet V1
VIEW / OWNER indépendants
Argon2id v19
XChaCha20-Poly1305
CSPRNG OS
content keys séparées OWNER / metadata / secret
Ed25519 distinct pour state_signature OWNER
keypair Solana immuable et encapsulée
create/open VIEW/OWNER
persistence no-clobber
replacement administratif capability-bound
signature Solana OWNER
alias/notes + rotations OWNER/VIEW
strong disable/recreate VIEW
import/export Solana CLI JSON + Base58 keypair 64 octets

Aucune dépendance Wallet vers Config, Transport, ExecutionPolicy, Store ou Tauri n'est autorisée.

3. Matrice adversariale

Cas Résultat attendu Preuve
mutation canonique KDF/wrap OWNER rejet security_tests::owner_signed_regions_reject_canonical_tampering_before_unlock
mutation owner-control rejet même canari
mutation metadata rejet même canari
mutation secret rejet même canari
mutation state_signature rejet même canari
état OWNER-signed invalide + password vide wallet.authentication_failed avant Argon2 security_tests::owner_signature_verification_precedes_owner_and_view_password_kdf
mutation des credentials rotatables VIEW uniquement état OWNER toujours valide, OWNER ouvrable, VIEW rejeté security_tests::view_credential_tampering_does_not_forge_owner_state_and_cannot_unlock_view
wrong VIEW wallet.view_unlock_failed générique tests Wallet + security
wrong OWNER wallet.owner_unlock_failed générique tests Wallet + security
password canary dans Display/Debug absent security_tests::unlock_failures_do_not_echo_password_material
metadata plaintext dans wallet verrouillé absent wallet::tests::locked_full_vector_contains_no_authorized_identity_or_metadata_plaintext
stale OWNER handle wallet.state_conflict administration tests
wallet A handle vers wallet B wallet.state_conflict administration tests
écriture interrompue avant publish ancien/destination absent préservé persistence fault tests
concurrence create no-clobber exactement un gagnant persistence concurrency test
export secret depuis VIEW surface publique absente dependency/public-surface canary

4. Ordre de vérification et anti-oracle

Pour VIEW et OWNER :

parse structurel borné
-> state_signature OWNER
-> seulement ensuite Argon2 du slot demandé
-> unwrap AEAD
-> déchiffrement compartment
-> parsing plaintext protégé

Le canari state_signature invalide + password vide distingue explicitement cet ordre : si Argon2 était évalué avant l'authentification d'état, l'entrée vide produirait une erreur de paramètres crypto ; le résultat attendu reste wallet.authentication_failed.

Les erreurs de password ne distinguent pas KDF, wrapping AEAD ou contenu protégé et ne reflètent pas le password fourni.

5. Interopérabilité indépendante

Les fixtures publiques test-only restent :

kspwallet_v1_wire_only.json
kspwallet_v1_crypto_vectors.json
kspwallet_v1_full_vector.json
kspwallet_v1_full_vector_meta.json

Une sonde indépendante hors Rust/KSP exécutée pendant pre.009 reproduit :

Argon2id OWNER derived key  = exact
Argon2id VIEW derived key   = exact
pre.004 XChaCha wrapped key = exact
pre.004 unwrap content key  = exact
Ed25519 state signature     = vérifiée sur le transcript exact
Solana keypair Base58       = reproduite depuis 64 octets
Solana Pubkey Base58        = reproduite depuis les 32 octets publics

La sonde utilise Python avec Argon2 et Ed25519/ChaCha20-Poly1305 disponibles localement ; XChaCha20 est reproduit par la construction HChaCha20 + ChaCha20-Poly1305 IETF. Cette sonde n'est ni versionnée ni requise par KSP : elle sert uniquement de seconde implémentation de vérification.

Références cryptographiques normatives/primaires réauditées :

  • RFC 9106 — Argon2 ; le profil Argon2id 64 MiB / t=3 est la seconde recommandation pour environnements contraints ;
  • RFC 8032 — Ed25519/EdDSA et signatures 64 octets ;
  • documentation RustCrypto chacha20poly1305 — XChaCha20-Poly1305 et nonce étendu 192 bits ;
  • documentation solana-keypair 3.1.2 — keypair Ed25519 64 octets, validation secret/public et codecs Base58/JSON ;
  • documentation tempfile 3.27 — publication/replacement et limites d'atomicité selon OS/filesystem.

6. Audit Cargo observé après pre.008

Commande opérateur :

cargo tree -p ksp-wallet-lib
cargo tree -p ksp-wallet-lib -d
cargo tree -i solana-keypair@3.1.2

Dépendances directes de Wallet observées :

argon2              0.5.3
base64              0.23.1
chacha20poly1305    0.11.0
ed25519-dalek       2.2.0
getrandom           0.4.3
ksp-core-lib
ksp-logging-lib
serde               1.0.229
serde_json          1.0.151
solana-keypair      3.1.2
tempfile            3.27.0
tokio               1.53.1
zeroize             1.9.0

Points de convergence recherchés :

ed25519-dalek 2.2.0 : une seule génération, partagée KSP + solana-keypair
solana-address 2.7.0: une seule génération, partagée solana-pubkey + solana-keypair
solana-keypair 3.1.2: unique parent KSP direct = ksp-wallet-lib

Doublons transitifs observés et acceptés au gate :

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

Ces doublons proviennent des générations transitives actuelles de RustCrypto, solana-keypair/solana-ed25519 et Logging. Ils ne correspondent pas à deux versions directes déclarées par Wallet pour une même fonction. Les éliminer exigerait de forcer des upstream incompatibles ou de régresser les versions retenues ; aucun contournement KSP n'est introduit.

7. Frontières KSP

Canaries durables :

Wallet -> Core + Logging + primitives explicites
Wallet -X-> Config
Wallet -X-> Transport
Wallet -X-> ExecutionPolicy
Wallet -X-> Store
Wallet -X-> Tauri
Wallet -X-> tracing direct
Wallet -X-> std::env
Wallet -X-> solana-pubkey direct
Wallet -X-> solana-signer direct
Wallet -X-> solana-signature direct
Wallet -X-> bs58 direct

ksp-core-lib::Pubkey reste le type public transversal. solana-keypair reste un détail secret/signing propre à Wallet ; aucune Keypair, Signer ou Signature Solana externe n'est réexportée par la surface publique Wallet.

WalletTransferFormat est #[non_exhaustive] : la liste built-in reste additive et les consumers ne peuvent pas supposer qu'elle est fermée. pre.009 ne crée pas de trait/plugin externe de codec secret : un tel trait devrait exposer les 64 octets de keypair à une implémentation tierce et constituerait une nouvelle surface secrète. Cette extension éventuelle exige un contrat dédié futur plutôt qu'une abstraction V1 prématurée.

8. Limites et non-garanties V1

Le verdict security est positif dans le threat model documenté, avec les limites explicites suivantes :

  1. un remplacement total par un autre wallet autonome valide n'est pas détectable à partir du nouveau fichier seul ;
  2. un rollback total vers une ancienne copie valide n'est pas détecté sans état/ancre externe ;
  3. le garde-fou wallet.state_conflict réduit les erreurs de cible/stale handle mais n'est pas un CAS filesystem portable linéarisable ;
  4. l'atomicité et la crash-durability du filesystem dépendent de l'OS/filesystem ;
  5. les ACL/permissions sont une hygiène externe, pas une garantie cryptographique ;
  6. zeroize s'applique aux buffers possédés explicitement mais ne prouve pas l'effacement physique de toutes les copies potentielles ;
  7. aucune protection hardware, second facteur, keychain, remote signer ou anti-rollback externe n'est incluse en V1.

Aucune de ces limites ne doit être masquée dans pre.010.

9. Gate opérateur pre.009

À exécuter après application du delta :

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

Le gate est vert seulement si les canaris adversariaux passent sans warning et si le tree ne révèle aucune nouvelle dépendance directe ou génération Dalek/Solana-address inattendue.

10. Verdict avant pre.010

Le verdict de conception et d'interopérabilité est positif sous réserve du checkpoint Cargo opérateur pre.009. Aucun changement de wire/crypto n'est requis par l'audit. pre.010 doit donc rester documentaire : README/USAGE Wallet, synchronisation finale de la spec/graphes, candidate de clôture et prompt 0.2.6.