147 lines
5.8 KiB
Rust
147 lines
5.8 KiB
Rust
use sanctum::upgrade::{
|
|
run_upgrade, validate_trusted_comment_version, verify_minisign_signature, UpgradeOptions,
|
|
SANCTUM_RELEASE_PUBKEY,
|
|
};
|
|
|
|
#[test]
|
|
fn test_minisign_signature_valid() {
|
|
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";
|
|
|
|
let res = verify_minisign_signature(payload, sig_text, SANCTUM_RELEASE_PUBKEY);
|
|
assert!(
|
|
res.is_ok(),
|
|
"Gültige Minisign-Signatur muss erfolgreich verifiziert werden: {:?}",
|
|
res.err()
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_minisign_signature_tampered_payload() {
|
|
let tampered_payload = b"Hello Sanctum Release 0.7.0 Tampered Payload!\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";
|
|
|
|
let res = verify_minisign_signature(tampered_payload, sig_text, SANCTUM_RELEASE_PUBKEY);
|
|
assert!(
|
|
res.is_err(),
|
|
"Manipulierte Binärdaten müssen die Minisign-Prüfung verfehlen"
|
|
);
|
|
assert!(res.unwrap_err().to_string().contains("FEHLGESCHLAGEN"));
|
|
}
|
|
|
|
#[test]
|
|
fn test_minisign_signature_wrong_key() {
|
|
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";
|
|
|
|
// Ein anderer, unautorisierter Public Key
|
|
let other_key = "RWSb0a70vF1X8qIjc7xi28Gmw+cIWbMipOy4L6ToJEUPkWDw3c0qIjc7";
|
|
let res = verify_minisign_signature(payload, sig_text, other_key);
|
|
assert!(
|
|
res.is_err(),
|
|
"Signaturprüfung mit fremdem Schlüssel muss fehlschlagen"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_upgrade_blocks_unofficial_url_without_insecure_flag() {
|
|
let options = UpgradeOptions {
|
|
check_only: true,
|
|
yes: false,
|
|
force: false,
|
|
base_url: "https://evil-attacker.org/sanctum".into(),
|
|
insecure_url: false,
|
|
};
|
|
|
|
let res = run_upgrade(&options);
|
|
assert!(
|
|
res.is_err(),
|
|
"Inoffizielle Server-URL ohne --insecure-url muss blockiert werden"
|
|
);
|
|
let err_msg = res.unwrap_err().to_string();
|
|
assert!(
|
|
err_msg.contains("Sicherheitsverstoß") || err_msg.contains("nicht vertrauenswürdig"),
|
|
"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"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_u02_validate_trusted_comment_version_matching() {
|
|
// Standard Minisign format with -t "version:0.8.0"
|
|
let tc1 = "timestamp:1789750897\tversion:0.8.0\tfile:SHA256SUMS.txt\thashed";
|
|
assert!(validate_trusted_comment_version(tc1, "0.8.0").is_ok());
|
|
assert!(validate_trusted_comment_version(tc1, "v0.8.0").is_ok());
|
|
|
|
// Alternative tags like tag:v0.8.0 or release:0.8.0
|
|
let tc2 = "release:0.8.0";
|
|
assert!(validate_trusted_comment_version(tc2, "0.8.0").is_ok());
|
|
let tc3 = "tag:v0.8.0";
|
|
assert!(validate_trusted_comment_version(tc3, "0.8.0").is_ok());
|
|
}
|
|
|
|
#[test]
|
|
fn test_u02_reject_mismatched_release_tag_replay() {
|
|
// An attacker replays a valid signature from v0.7.0 for an update claiming to be v0.8.0
|
|
let tc_old = "timestamp:1789750897\tversion:0.7.0\tfile:SHA256SUMS.txt\thashed";
|
|
let res = validate_trusted_comment_version(tc_old, "v0.8.0");
|
|
assert!(
|
|
res.is_err(),
|
|
"U-02: Ältere oder abweichende Version im Trusted Comment muss abgewiesen werden"
|
|
);
|
|
let err_msg = res.unwrap_err().to_string();
|
|
assert!(
|
|
err_msg.contains("U-02") && err_msg.contains("Replay-Angriff"),
|
|
"Fehlermeldung muss auf Replay-Angriff und U-02 hinweisen: {err_msg}"
|
|
);
|
|
|
|
// Empty or completely missing version token
|
|
let tc_no_ver = "timestamp:1789750897\tfile:SHA256SUMS.txt\thashed";
|
|
let res2 = validate_trusted_comment_version(tc_no_ver, "0.8.0");
|
|
assert!(res2.is_err());
|
|
}
|
|
|