signalscreen-checker 0.2.1

Windows code-signing hygiene checker. Reads the Authenticode signature in a PE file and grades it A-F. Pure Rust, no Windows dependency.
Documentation
//! Roll check results into a 0–100 score and an A–F grade. Pure — no parsing.
use crate::checks::{CheckResult, Status};

/// Penalty per failing/warning check id. Encodes the SmartScreen-reputation thesis.
fn penalty(id: &str, status: &Status) -> u32 {
    match (id, status) {
        ("signature", Status::Fail) => 100, // unsigned/invalid => F outright
        ("timestamp", Status::Fail) => 40,
        ("digest", Status::Fail) => 30,
        ("chain", Status::Fail) => 40,
        ("expiry", Status::Fail) => 20,
        ("expiry", Status::Warn) => 10,
        _ => 0,
    }
}

pub fn score(results: &[CheckResult]) -> u32 {
    let total: u32 = results.iter().map(|c| penalty(&c.id, &c.status)).sum();
    100u32.saturating_sub(total)
}

pub fn grade(score: u32) -> char {
    match score {
        90..=100 => 'A',
        80..=89 => 'B',
        70..=79 => 'C',
        60..=69 => 'D',
        _ => 'F',
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::checks::{CheckResult, Status};

    fn c(id: &str, s: Status) -> CheckResult {
        CheckResult {
            id: id.into(),
            status: s,
            detail: String::new(),
        }
    }

    #[test]
    fn clean_is_a() {
        let r = vec![
            c("signature", Status::Pass),
            c("timestamp", Status::Pass),
            c("digest", Status::Pass),
            c("expiry", Status::Pass),
        ];
        assert_eq!(score(&r), 100);
        assert_eq!(grade(100), 'A');
    }

    #[test]
    fn unsigned_is_f() {
        let r = vec![c("signature", Status::Fail)];
        assert_eq!(score(&r), 0);
        assert_eq!(grade(score(&r)), 'F');
    }

    #[test]
    fn missing_timestamp_drops_to_d() {
        let r = vec![
            c("signature", Status::Pass),
            c("timestamp", Status::Fail),
            c("digest", Status::Pass),
            c("expiry", Status::Pass),
        ];
        assert_eq!(score(&r), 60); // 100 - 40
        assert_eq!(grade(60), 'D');
    }
}