fix(sign): match cloud signature to requested digest - #3
Conversation
|
Thanks — the selection bug is real: One thing before this goes in. Since the case carries no information for a hex string, I'd rather not depend on it: .and_then(|m| {
m.iter()
.find(|(k, _)| k.eq_ignore_ascii_case(digest_hex))
.map(|(_, v)| v)
})Same guarantee, no allocation, and nothing to break on a formatting detail that was never promised. Worth adding a test with a realistic 64-char digest in both cases too — the current ones use |
CI : ajout de --workspace à clippy et cargo test. Sans lui, le CI ne lançait qu'UN test (celui du binaire) et n'a jamais exécuté les 16 tests de ssign-core — y compris ceux ajoutés par #3 et #4. Clippy ne lintait pas non plus ssign-core. --all-targets sur clippy pour couvrir les tests. Secrets : la graine TOTP et le code sont désormais portés par Zeroizing<String> et effacés à leur libération ; les copies laissées par clap sont effacées dès que le secret est repris. Limite documentée dans le code : cela ne couvre pas ce qui précède main (argv et environ restent lisibles dans /proc), d'où le conseil de préférer les variables d'environnement. Contenu de la release, via #3 et #4 : - signature cloud sélectionnée sur le digest exact demandé, comparaison insensible à la casse (le contrat de l'API porte sur du hex, pas sur une casse) ; - table de certificats PE bornée, sans rejeter un offset résiduel quand la table est vide ; - validation structurelle CMS du token d'horodatage avant intégration ; - écriture atomique des sorties : fichier temporaire O_EXCL dans le même répertoire, sync, permissions préservées, remplacement atomique, et refus d'écraser un .orig existant. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0138mtPxwfXPetBypyjp6KwU
What changed
Scope
This PR intentionally contains only the response-selection fix. Timestamp transport policy, Content-Type handling, PE bounds checks, and output-write hardening are excluded.