v0.2.5-pre.009
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/validation/000-README.md -->
|
||||
<!-- version: 11 -->
|
||||
<!-- version: 12 -->
|
||||
|
||||
# Validations KSP
|
||||
|
||||
@@ -17,3 +17,4 @@ Documents :
|
||||
|
||||
- [`006-V0_2_3_HTTP_TRANSACTIONS.md`](006-V0_2_3_HTTP_TRANSACTIONS.md) — matrice finale validée de `0.2.3`, 11 wrappers Transactions, sécurité write/simulation, réaudit 52+14, `KSP-TRANSPORT-007` 37/37, graphes Cargo et deux smokes Devnet passés avant publication stable.
|
||||
- [`007-V0_2_4_HTTP_FINAL_COMPLIANCE.md`](007-V0_2_4_HTTP_FINAL_COMPLIANCE.md) — matrice finale validée de `0.2.4`, inventaire exact 52 current + 14 Deprecated, preuve typed 52/52, audit SIMD final, `KSP-TRANSPORT-007`, workspace complet et deux smokes Devnet passés avant publication stable.
|
||||
- [`008-V0_2_5_WALLET_SECURITY_COMPLIANCE.md`](008-V0_2_5_WALLET_SECURITY_COMPLIANCE.md) — matrice security/interoperability/compliance de `0.2.5`, threat model V1, adversarial canaries, reproduction externe des vecteurs, audit de frontières et graphes Cargo Wallet.
|
||||
|
||||
224
docs/validation/008-V0_2_5_WALLET_SECURITY_COMPLIANCE.md
Normal file
224
docs/validation/008-V0_2_5_WALLET_SECURITY_COMPLIANCE.md
Normal file
@@ -0,0 +1,224 @@
|
||||
<!-- file: docs/validation/008-V0_2_5_WALLET_SECURITY_COMPLIANCE.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# 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`](../formats/KSPWALLET_V1.md), ni le threat model du plan [`../plans/012-V0_2_5_WALLET_FOUNDATION_PLAN.md`](../plans/012-V0_2_5_WALLET_FOUNDATION_PLAN.md), ni les deltas.
|
||||
|
||||
Le verdict recherché porte sur quatre axes :
|
||||
|
||||
```text
|
||||
security/adversarial
|
||||
interoperability indépendante
|
||||
frontières KSP
|
||||
Cargo/dependency compliance
|
||||
```
|
||||
|
||||
## 2. État fonctionnel audité
|
||||
|
||||
Au gate `pre.009`, Wallet possède :
|
||||
|
||||
```text
|
||||
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 :
|
||||
|
||||
```text
|
||||
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 :
|
||||
|
||||
```text
|
||||
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 :
|
||||
|
||||
```text
|
||||
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 :
|
||||
|
||||
```bash
|
||||
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 :
|
||||
|
||||
```text
|
||||
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 :
|
||||
|
||||
```text
|
||||
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 :
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
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 :
|
||||
|
||||
```text
|
||||
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 :
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
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`.
|
||||
Reference in New Issue
Block a user