// SPDX-License-Identifier: AGPL-3.0-only
//! Real bundles, produced by Holger's own library, are ACCEPTED, and the guest
//! says the same thing about them that Holger's own verifier says.
mod common;
use common::*;
use heimdall_guest_verify_bundle::{REPORT_NAME, REPORT_SCHEMA};
fn report(o: &Outcome) -> serde_json::Value {
assert!(o.is_accepted(), "refused: {:?}", o.reason());
serde_json::from_slice(&o.output).unwrap()
}
#[test]
fn a_pinned_signer_bundle_made_by_holger_is_accepted() {
let fx = good();
let o = fx.guest();
let r = report(&o);
assert_eq!(r["schema"], REPORT_SCHEMA);
assert_eq!(r["bundle_id"], "bundle-0005");
assert_eq!(r["sequence"], 5);
assert_eq!(r["candidate_digest"], fx.candidate_digest);
assert_eq!(r["release_signer_fingerprint"], fx.release.fingerprint);
assert_eq!(r["approvals"].as_array().unwrap().len(), 2);
}
#[test]
fn a_rooted_chain_bundle_made_by_holger_is_accepted() {
let fx = build(Spec {
rooted: true,
..Spec::default()
});
let r = report(&fx.guest());
assert!(r["checks"]
.as_array()
.unwrap()
.iter()
.any(|c| c.as_str().unwrap().contains("RootedChain")));
}
#[test]
fn the_guest_and_holgers_own_verifier_agree_on_every_reported_field() {
let fx = good();
let archive = fx.pack();
let h = fx.holger(&archive).expect("Holger accepts its own bundle");
let o = verify_bundle(&archive, &fx.params());
let r = report(&o);
assert_eq!(r["bundle_id"], h.bundle_id);
assert_eq!(r["sequence"], h.sequence);
assert_eq!(r["supplier"], h.supplier);
assert_eq!(r["product"], h.product);
assert_eq!(r["release_version"], h.release_version);
assert_eq!(r["candidate_digest"], h.candidate_digest);
assert_eq!(
r["release_signer_fingerprint"],
h.release_signer_fingerprint
);
assert_eq!(r["release_signer_subject"], h.release_signer_subject);
assert_eq!(r["non_production_evidence"], h.non_production_evidence);
let mut ga: Vec<(String, String, String)> = r["approvals"]
.as_array()
.unwrap()
.iter()
.map(|a| {
(
a["role"].as_str().unwrap().into(),
a["fingerprint"].as_str().unwrap().into(),
a["subject"].as_str().unwrap().into(),
)
})
.collect();
let mut ha: Vec<(String, String, String)> = h
.approvals
.iter()
.map(|a| (a.role.clone(), a.fingerprint.clone(), a.subject.clone()))
.collect();
ga.sort();
ha.sort();
assert_eq!(ga, ha);
}
#[test]
fn an_accepted_bundle_emits_the_report_and_exactly_its_payload_and_evidence_bytes() {
let fx = good();
let o = fx.guest();
assert!(o.is_accepted());
let names: Vec<&str> = o.emitted.iter().map(|e| e.name.as_str()).collect();
assert_eq!(
names,
vec![
REPORT_NAME,
"evidence+2fsbom+2fapp.cdx.json",
"evidence+2fsource-receipt.json",
"payload+2ffirmware.bin"
]
);
for e in &o.emitted[1..] {
assert_eq!(
&e.bytes,
member_for(&fx.members, &e.name),
"{} differs",
e.name
);
}
assert_eq!(
o.emitted[0].bytes, o.output,
"the report output and the emitted report are one"
);
}
#[test]
fn emit_all_also_emits_the_control_members_and_emit_report_emits_only_the_report() {
let fx = good();
let all = verify_bundle(&fx.pack(), &fx.params_with("emit: All"));
assert_eq!(all.emitted.len(), 1 + fx.members.len());
let only = verify_bundle(&fx.pack(), &fx.params_with("emit: Report"));
assert_eq!(only.emitted.len(), 1);
assert_eq!(only.emitted[0].name, REPORT_NAME);
}
#[test]
fn a_multi_megabyte_payload_split_into_many_chunks_is_accepted_byte_exact() {
let big: Vec<u8> = (0..9 * 1024 * 1024u32)
.map(|i| (i.wrapping_mul(2654435761) >> 13) as u8)
.collect();
let mut spec = Spec::default();
spec.payloads.push((
"big/blob.bin".into(),
big.clone(),
"application/octet-stream".into(),
));
let fx = build(spec);
let o = fx.guest();
assert!(o.is_accepted(), "{:?}", o.reason());
let e = o
.emitted
.iter()
.find(|e| e.name == "payload+2fbig+2fblob.bin")
.unwrap();
assert_eq!(e.bytes, big);
}
#[test]
fn an_empty_payload_file_is_accepted() {
let mut spec = Spec::default();
spec.payloads.push((
"empty.bin".into(),
Vec::new(),
"application/octet-stream".into(),
));
let o = build(spec).guest();
assert!(o.is_accepted(), "{:?}", o.reason());
assert!(o
.emitted
.iter()
.any(|e| e.name == "payload+2fempty.bin" && e.bytes.is_empty()));
}
#[test]
fn a_bundle_with_no_expiry_is_accepted_when_the_policy_does_not_require_one() {
let o = build(Spec {
expires_in: None,
..Spec::default()
})
.guest();
assert!(o.is_accepted(), "{:?}", o.reason());
}
#[test]
fn many_small_members_are_accepted() {
let mut spec = Spec::default();
for i in 0..300 {
spec.payloads.push((
format!("pkgs/p{i:04}.bin"),
format!("pkg {i}").into_bytes(),
"application/octet-stream".into(),
));
}
let o = build(spec).guest();
assert!(o.is_accepted(), "{:?}", o.reason());
assert_eq!(o.emitted.len(), 1 + 301 + 2);
}
#[test]
fn verification_is_deterministic_byte_for_byte() {
let fx = good();
let a = fx.pack();
let p = fx.params();
let first = verify_bundle(&a, &p);
for _ in 0..3 {
assert_eq!(verify_bundle(&a, &p), first);
}
}
#[test]
fn a_bundle_holger_packs_itself_with_openzl_members_is_accepted_like_holger_accepts_it() {
// Was the open finding (heimdall-bundle-3): znippy compresses with OpenZL.
// With the `openzl` feature the guest decodes the frames itself; without
// it the same file is still refused by name.
let fx = good();
let archive = pack_holger(&fx.members);
let h = fx
.holger(&archive)
.expect("Holger reads its own OpenZL archive");
let o = verify_bundle(&archive, &fx.params());
if cfg!(feature = "openzl") {
let r = report(&o);
assert_eq!(r["bundle_id"], h.bundle_id);
assert_eq!(r["candidate_digest"], h.candidate_digest);
assert_eq!(
r["release_signer_fingerprint"],
h.release_signer_fingerprint
);
} else {
assert_refused(&o, "heimdall-bundle-3", "OpenZL");
}
}
#[test]
fn every_output_name_is_one_plain_file_name_and_the_mapping_is_injective() {
let paths = [
"payload/firmware.bin",
"payload+2ffirmware.bin",
"payload/a+b",
".hidden",
"verify-report.json",
"evidence/sbom/app.cdx.json",
"payload/ünïcode",
];
let mut seen = std::collections::BTreeSet::new();
for p in paths {
let n = output_name(p);
assert!(!n.is_empty() && n.len() <= 255, "{n}");
assert!(!n.starts_with('.'), "{n}");
assert!(
n.chars()
.all(|c| c.is_ascii_alphanumeric() || "._-+".contains(c)),
"{n}"
);
assert_ne!(n, REPORT_NAME);
assert!(seen.insert(n.clone()), "{p} collides as {n}");
}
assert_eq!(
output_name("payload/firmware.bin"),
"payload+2ffirmware.bin"
);
let long = format!("payload/{}", "x".repeat(300));
assert!(output_name(&long).starts_with("member+"));
}