jobs/runner/tests/vendored_heimdall_guests.rs
//! **Heimdall's released verify-bundle guests, vendored** (lane HOL-HEIMDALL-02): the ten files
//! of heimdall-guests-0.2.1 under `guests/heimdall/0.2.1/` are the ones the release names.
//!
//! * every module matches its pin in `PINS.toml` AND Holger's compiled-in pin
//! (`guests::RELEASE`), by sha256 and BLAKE3, and its `.wasm.blake3` sidecar says the same;
//! * the release's SLSA statement (DSSE, the owner's YubiKey: Holger's own
//! `slsa/release-signing-key.pub`, dwarves' release runner) names each module's sha256,
//! verified by Holger's own provenance verifier;
//! * each `.wasm.p7s` verifies against the korp root, inside Heimdall's host, as the split pair
//! Holger runs (the decoder first) and the single-instance guest load;
//! * a module that is not the pinned one, or a trust root that is not the korp root, is refused.
use std::path::{Path, PathBuf};
use holger_job_runner::guests::{check_files, load_split, Pin, DIR, RELEASE};
fn repo() -> PathBuf {
Path::new(env!("CARGO_MANIFEST_DIR")).join("../..")
}
fn dir() -> PathBuf {
let d = repo().join(DIR);
let probe = std::fs::read(d.join(RELEASE.verifier.file)).unwrap();
assert!(
!probe.starts_with(b"version https://git-lfs"),
"{} is an LFS pointer: run `git lfs pull` first",
RELEASE.verifier.file
);
d
}
/// The korp root as DER in `tmp` (Heimdall's host takes DER roots).
fn korp_root(tmp: &Path) -> PathBuf {
let pem = std::fs::read_to_string(repo().join("holger-recipe/trust/korp-root-ca.pem")).unwrap();
der_file(&pem, tmp, "korp-root-ca.der")
}
fn der_file(pem: &str, tmp: &Path, name: &str) -> PathBuf {
use base64::Engine as _;
let b64: String = pem.lines().filter(|l| !l.starts_with("-----")).collect();
let der = base64::engine::general_purpose::STANDARD
.decode(b64.trim())
.unwrap();
let p = tmp.join(name);
std::fs::write(&p, der).unwrap();
p
}
#[test]
fn every_vendored_file_is_the_pinned_one_and_pins_toml_says_the_compiled_pins() {
let d = dir();
let pins: toml::Table = std::fs::read_to_string(d.join("PINS.toml"))
.unwrap()
.parse()
.unwrap();
assert_eq!(pins["release"].as_str(), Some(RELEASE.release));
assert_eq!(pins["tag"].as_str(), Some(RELEASE.tag));
assert_eq!(pins["commit"].as_str(), Some(RELEASE.commit));
assert_eq!(pins["attestation"].as_str(), Some(RELEASE.attestation));
let listed = pins["guest"].as_array().unwrap();
assert_eq!(listed.len(), 3);
for pin in RELEASE.pins() {
let row = listed
.iter()
.find(|g| g["role"].as_str() == Some(pin.role))
.unwrap_or_else(|| panic!("{} in PINS.toml", pin.role));
assert_eq!(row["file"].as_str(), Some(pin.file));
assert_eq!(row["sha256"].as_str(), Some(pin.sha256), "{}", pin.file);
assert_eq!(row["blake3"].as_str(), Some(pin.blake3), "{}", pin.file);
check_files(&d, &pin).unwrap();
assert!(
d.join(format!("{}.p7s", pin.file)).is_file(),
"{}.p7s",
pin.file
);
}
// The ten release files and the pins file, nothing else.
let mut names: Vec<String> = std::fs::read_dir(&d)
.unwrap()
.flatten()
.map(|e| e.file_name().to_string_lossy().into_owned())
.collect();
names.sort();
assert_eq!(names.len(), 11, "{names:?}");
// A changed module is refused by name.
let tmp = tempfile::tempdir().unwrap();
for f in std::fs::read_dir(&d).unwrap().flatten() {
std::fs::copy(f.path(), tmp.path().join(f.file_name())).unwrap();
}
let p = tmp.path().join(RELEASE.decoder.file);
let mut b = std::fs::read(&p).unwrap();
let n = b.len() / 2;
b[n] ^= 1;
std::fs::write(&p, b).unwrap();
let e = check_files(tmp.path(), &RELEASE.decoder).unwrap_err();
assert!(
e.contains("sha256") && e.contains(RELEASE.decoder.sha256),
"{e}"
);
}
#[test]
fn the_releases_slsa_statement_signed_with_the_owners_key_names_every_module() {
use holger_provenance::{effective, verify_artifact, ProvenanceFloor, ProvenanceGate, Verdict};
const BUILDER: &str = "https://git.gunnar.rs/nordisk/dwarves/slsa/builders/dwarves-server/v1";
const KEYID: &str = "d24d3785e8281bcd37e8f2c40a3a85e8152d3ce2200a5c929a1a5ca636e8249e";
let d = dir();
let pem = std::fs::read_to_string(repo().join("slsa/release-signing-key.pub")).unwrap();
let floor: ProvenanceFloor = ron::from_str(&format!(
r#"(keys: [(id: "{KEYID}", alg: ecdsa_p256, public_key: "{}")])"#,
pem.replace('\n', "\\n")
))
.unwrap();
let gate: ProvenanceGate = ron::from_str(&format!(
r#"require(builders: [(id: "{BUILDER}", level: 3)], keys: ["{KEYID}"], slsa_min: 3)"#
))
.unwrap();
let policy = effective(&floor, &gate);
let att = vec![(
RELEASE.attestation.to_string(),
std::fs::read(d.join(RELEASE.attestation)).unwrap(),
)];
for pin in RELEASE.pins() {
let r = verify_artifact(
&std::fs::read(d.join(pin.file)).unwrap(),
&att,
&policy,
None,
);
assert_eq!(r.verdict, Verdict::Pass, "{}: {}", pin.file, r.detail);
let c = r
.verified_provenance()
.next()
.expect("a verified statement");
assert_eq!(c.builder_id.as_deref(), Some(BUILDER));
let slsa = c.slsa.as_ref().unwrap();
assert_eq!(slsa.external_parameters["release"], RELEASE.release);
}
// Not a byte of another module passes.
let r = verify_artifact(b"not a guest", &att, &policy, None);
assert_ne!(r.verdict, Verdict::Pass);
}
#[test]
fn the_split_pair_loads_signed_under_the_korp_root_with_holgers_pins_and_nothing_else_does() {
let d = dir();
let tmp = tempfile::tempdir().unwrap();
let root = korp_root(tmp.path());
let limits = heimdall_run::RunLimits::default();
let g = load_split(&d, &RELEASE, std::slice::from_ref(&root), &limits).unwrap();
assert_eq!(g.digest_hex(), RELEASE.verifier.blake3);
assert_eq!(g.decoder_digest_hex(), Some(RELEASE.decoder.blake3));
assert!(g.signer().contains("plugin signing"), "{}", g.signer());
let single = heimdall_run::wasm::load_guest(
&d.join(RELEASE.single.file),
std::slice::from_ref(&root),
Some(RELEASE.single.blake3),
&limits,
)
.unwrap();
assert_eq!(single.digest_hex(), RELEASE.single.blake3);
// Another pin: refused before anything runs.
let wrong = holger_job_runner::guests::Release {
decoder: Pin {
blake3: RELEASE.single.blake3,
..RELEASE.decoder
},
..RELEASE
};
assert!(load_split(&d, &wrong, &[root], &limits).is_err());
// Another trust root (Holger's release key's certificate is no plugin root): refused.
let other = der_file(
&std::fs::read_to_string(repo().join("slsa/yubikey-piv-attestation-ca.pem")).unwrap(),
tmp.path(),
"other.der",
);
let e = load_split(&d, &RELEASE, &[other], &limits)
.err()
.expect("refused");
assert!(e.contains(RELEASE.release), "{e}");
// No trust root at all: there is no unsigned mode.
assert!(load_split(&d, &RELEASE, &[], &limits).is_err());
}
/// Lane HOL-HEIMDALL-04: the korp root the box stages as PEM is the DER a job carries, and a
/// DER file stays as it is.
#[test]
fn the_trust_root_pem_is_read_as_its_der() {
let tmp = tempfile::tempdir().unwrap();
let want = std::fs::read(korp_root(tmp.path())).unwrap();
let pem = std::fs::read(repo().join("holger-recipe/trust/korp-root-ca.pem")).unwrap();
assert_eq!(holger_job_runner::guests::der_of(&pem).unwrap(), want);
assert_eq!(holger_job_runner::guests::der_of(&want).unwrap(), want);
holger_job_runner::guests::check_release(&dir(), &RELEASE).unwrap();
}