diff --git a/src/upgrade.rs b/src/upgrade.rs index 23e7626..7808c27 100644 --- a/src/upgrade.rs +++ b/src/upgrade.rs @@ -64,14 +64,16 @@ impl Default for UpgradeOptions { } } -/// Überprüft eine Minisign-Signatur für gegebene Binärdaten mit dem angegebenen Minisign Public Key (S-02). +/// Überprüft eine Minisign-Signatur für gegebene Binärdaten mit dem angegebenen Minisign Public Key (U-01). +/// +/// Erzwingt strikt Pre-Hashing (`allow_legacy = false`), um Malleability- und Längenangriffe auszuschließen. pub fn verify_minisign_signature(data: &[u8], sig_str: &str, pubkey_str: &str) -> Result<()> { let pubkey = minisign_verify::PublicKey::from_base64(pubkey_str) .map_err(|e| anyhow::anyhow!("Ungültiger öffentlicher Minisign-Schlüssel: {e}"))?; let signature = minisign_verify::Signature::decode(sig_str) .map_err(|e| anyhow::anyhow!("Ungültiges Minisign-Signaturformat: {e}"))?; pubkey - .verify(data, &signature, true) + .verify(data, &signature, false) .map_err(|e| anyhow::anyhow!("Minisign-Signaturprüfung FEHLGESCHLAGEN: {e}. Das Release-Manifest ist nicht vertrauenswürdig!"))?; Ok(()) } diff --git a/tests/upgrade_security_test.rs b/tests/upgrade_security_test.rs index 8f8b8f0..e67578b 100644 --- a/tests/upgrade_security_test.rs +++ b/tests/upgrade_security_test.rs @@ -75,3 +75,36 @@ fn test_upgrade_blocks_unofficial_url_without_insecure_flag() { "Fehler muss Sicherheitsverstoß anzeigen: {err_msg}" ); } + +#[test] +fn test_u01_reject_legacy_unhashed_signature() { + let payload = b"Hello Sanctum Release 0.7.0 Security Testing\n"; + let sig_text = "\ +untrusted comment: signature from minisign secret key\n\ +RUSsVphPgr8155LCucDq8RzDmWMzWElzhBmHrS5p+qJlOCGU4AQpn2F28MVPFrnoGPYEHx7/6TlKg2b45DlYuBQ0+ASeLIzMLwc=\n\ +trusted comment: timestamp:1789750897\tfile:test_payload.txt\thashed\n\ +0l7KsNJkDTo2uOKL8UAiaJOWuhwhGTVZ5fn0JFMdxXE9riYixQO9YnBpSVqz8iCDhWrz8hJBnmUrIWnaRaXVCA==\n"; + + // Gültige pre-hashed Signatur muss weiterhin erfolgreich geprüft werden + assert!(verify_minisign_signature(payload, sig_text, SANCTUM_RELEASE_PUBKEY).is_ok()); + + // Modifiziere die Signatur, um eine Legacy-Signatur (Ed statt ED) zu simulieren + // In Base64 entspricht 'ED' (0x45, 0x44) dem Präfix 'RU' + // 'Ed' (0x45, 0x64) entspricht in Base64 dem Präfix 'RW' + let lines: Vec<&str> = sig_text.lines().collect(); + let mut sig_line = lines[1].to_string(); + assert!(sig_line.starts_with("RU")); + sig_line.replace_range(0..2, "RW"); + + let legacy_sig_text = format!( + "{}\n{}\n{}\n{}\n", + lines[0], sig_line, lines[2], lines[3] + ); + + let res = verify_minisign_signature(payload, &legacy_sig_text, SANCTUM_RELEASE_PUBKEY); + assert!( + res.is_err(), + "U-01: Legacy-Signaturen (ohne Pre-Hashing) müssen strikt abgewiesen werden" + ); +} +