201 lines
6.9 KiB
Rust
201 lines
6.9 KiB
Rust
use std::path::{Path, PathBuf};
|
|
use std::process::Command;
|
|
|
|
use rpki::cir::{
|
|
CIR_VERSION_V1, CanonicalInputRepresentation, CirHashAlgorithm, CirObject, CirTal, encode_cir,
|
|
materialize_cir,
|
|
};
|
|
|
|
fn apnic_tal_path() -> PathBuf {
|
|
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/fixtures/tal/apnic-rfc7730-https.tal")
|
|
}
|
|
|
|
fn apnic_ta_path() -> PathBuf {
|
|
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/fixtures/ta/apnic-ta.cer")
|
|
}
|
|
|
|
fn build_ta_only_cir() -> (CanonicalInputRepresentation, Vec<u8>) {
|
|
let tal_bytes = std::fs::read(apnic_tal_path()).expect("read tal");
|
|
let ta_bytes = std::fs::read(apnic_ta_path()).expect("read ta");
|
|
let tal = rpki::data_model::tal::Tal::decode_bytes(&tal_bytes).expect("decode tal");
|
|
let ta_rsync_uri = tal
|
|
.ta_uris
|
|
.iter()
|
|
.find(|uri| uri.scheme() == "rsync")
|
|
.expect("tal has rsync uri")
|
|
.as_str()
|
|
.to_string();
|
|
let ta_hash = {
|
|
use sha2::{Digest, Sha256};
|
|
Sha256::digest(&ta_bytes).to_vec()
|
|
};
|
|
(
|
|
CanonicalInputRepresentation {
|
|
version: CIR_VERSION_V1,
|
|
hash_alg: CirHashAlgorithm::Sha256,
|
|
validation_time: time::OffsetDateTime::parse(
|
|
"2026-04-07T00:00:00Z",
|
|
&time::format_description::well_known::Rfc3339,
|
|
)
|
|
.unwrap(),
|
|
objects: vec![CirObject {
|
|
rsync_uri: ta_rsync_uri,
|
|
sha256: ta_hash,
|
|
}],
|
|
tals: vec![CirTal {
|
|
tal_uri: "https://example.test/root.tal".to_string(),
|
|
tal_bytes,
|
|
}],
|
|
},
|
|
ta_bytes,
|
|
)
|
|
}
|
|
|
|
fn write_static(root: &Path, date: &str, bytes: &[u8]) {
|
|
use sha2::{Digest, Sha256};
|
|
let hash = hex::encode(Sha256::digest(bytes));
|
|
let dir = root.join(date).join(&hash[0..2]).join(&hash[2..4]);
|
|
std::fs::create_dir_all(&dir).expect("mkdir static");
|
|
std::fs::write(dir.join(hash), bytes).expect("write static object");
|
|
}
|
|
|
|
fn prepare_reference_ccr(
|
|
work: &Path,
|
|
cir: &CanonicalInputRepresentation,
|
|
mirror_root: &Path,
|
|
) -> PathBuf {
|
|
let reference_ccr = work.join("reference.ccr");
|
|
let rpki_bin = env!("CARGO_BIN_EXE_rpki");
|
|
let wrapper = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("scripts/cir/cir-rsync-wrapper");
|
|
let tal_path = apnic_tal_path();
|
|
let ta_path = apnic_ta_path();
|
|
let out = Command::new(rpki_bin)
|
|
.env("REAL_RSYNC_BIN", "/usr/bin/rsync")
|
|
.env("CIR_MIRROR_ROOT", mirror_root)
|
|
.args([
|
|
"--db",
|
|
work.join("reference-db").to_string_lossy().as_ref(),
|
|
"--tal-path",
|
|
tal_path.to_string_lossy().as_ref(),
|
|
"--ta-path",
|
|
ta_path.to_string_lossy().as_ref(),
|
|
"--disable-rrdp",
|
|
"--rsync-command",
|
|
wrapper.to_string_lossy().as_ref(),
|
|
"--validation-time",
|
|
&cir.validation_time
|
|
.format(&time::format_description::well_known::Rfc3339)
|
|
.unwrap(),
|
|
"--max-depth",
|
|
"0",
|
|
"--max-instances",
|
|
"1",
|
|
"--ccr-out",
|
|
reference_ccr.to_string_lossy().as_ref(),
|
|
])
|
|
.output()
|
|
.expect("run reference rpki");
|
|
assert!(
|
|
out.status.success(),
|
|
"stderr={}",
|
|
String::from_utf8_lossy(&out.stderr)
|
|
);
|
|
reference_ccr
|
|
}
|
|
|
|
#[test]
|
|
fn cir_routinator_script_matches_reference_on_ta_only_cir() {
|
|
if !Path::new("/usr/bin/rsync").exists()
|
|
|| !Path::new("/home/yuyr/dev/rust_playground/routinator/target/debug/routinator").exists()
|
|
{
|
|
return;
|
|
}
|
|
let td = tempfile::tempdir().expect("tempdir");
|
|
let static_root = td.path().join("static");
|
|
let cir_path = td.path().join("sample.cir");
|
|
let mirror_root = td.path().join("mirror");
|
|
let out_dir = td.path().join("routinator-out");
|
|
|
|
let (cir, ta_bytes) = build_ta_only_cir();
|
|
std::fs::write(&cir_path, encode_cir(&cir).expect("encode cir")).expect("write cir");
|
|
write_static(&static_root, "20260407", &ta_bytes);
|
|
materialize_cir(&cir, &static_root, &mirror_root, true).expect("materialize");
|
|
let reference_ccr = prepare_reference_ccr(td.path(), &cir, &mirror_root);
|
|
|
|
let script =
|
|
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("scripts/cir/run_cir_replay_routinator.sh");
|
|
let out = Command::new(script)
|
|
.args([
|
|
"--cir",
|
|
cir_path.to_string_lossy().as_ref(),
|
|
"--static-root",
|
|
static_root.to_string_lossy().as_ref(),
|
|
"--out-dir",
|
|
out_dir.to_string_lossy().as_ref(),
|
|
"--reference-ccr",
|
|
reference_ccr.to_string_lossy().as_ref(),
|
|
])
|
|
.output()
|
|
.expect("run routinator cir script");
|
|
assert!(
|
|
out.status.success(),
|
|
"stderr={}",
|
|
String::from_utf8_lossy(&out.stderr)
|
|
);
|
|
let summary: serde_json::Value = serde_json::from_slice(
|
|
&std::fs::read(out_dir.join("compare-summary.json")).expect("read summary"),
|
|
)
|
|
.expect("parse summary");
|
|
assert_eq!(summary["vrps"]["match"], true);
|
|
assert_eq!(summary["vaps"]["match"], true);
|
|
}
|
|
|
|
#[test]
|
|
fn cir_rpki_client_script_matches_reference_on_ta_only_cir() {
|
|
if !Path::new("/usr/bin/rsync").exists()
|
|
|| !Path::new("/home/yuyr/dev/rpki-client-9.7/build-m5/src/rpki-client").exists()
|
|
{
|
|
return;
|
|
}
|
|
let td = tempfile::tempdir().expect("tempdir");
|
|
let static_root = td.path().join("static");
|
|
let cir_path = td.path().join("sample.cir");
|
|
let mirror_root = td.path().join("mirror");
|
|
let out_dir = td.path().join("rpki-client-out");
|
|
|
|
let (cir, ta_bytes) = build_ta_only_cir();
|
|
std::fs::write(&cir_path, encode_cir(&cir).expect("encode cir")).expect("write cir");
|
|
write_static(&static_root, "20260407", &ta_bytes);
|
|
materialize_cir(&cir, &static_root, &mirror_root, true).expect("materialize");
|
|
let reference_ccr = prepare_reference_ccr(td.path(), &cir, &mirror_root);
|
|
|
|
let script =
|
|
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("scripts/cir/run_cir_replay_rpki_client.sh");
|
|
let out = Command::new(script)
|
|
.args([
|
|
"--cir",
|
|
cir_path.to_string_lossy().as_ref(),
|
|
"--static-root",
|
|
static_root.to_string_lossy().as_ref(),
|
|
"--out-dir",
|
|
out_dir.to_string_lossy().as_ref(),
|
|
"--reference-ccr",
|
|
reference_ccr.to_string_lossy().as_ref(),
|
|
"--build-dir",
|
|
"/home/yuyr/dev/rpki-client-9.7/build-m5",
|
|
])
|
|
.output()
|
|
.expect("run rpki-client cir script");
|
|
assert!(
|
|
out.status.success(),
|
|
"stderr={}",
|
|
String::from_utf8_lossy(&out.stderr)
|
|
);
|
|
let summary: serde_json::Value = serde_json::from_slice(
|
|
&std::fs::read(out_dir.join("compare-summary.json")).expect("read summary"),
|
|
)
|
|
.expect("parse summary");
|
|
assert_eq!(summary["vrps"]["match"], true);
|
|
assert_eq!(summary["vaps"]["match"], true);
|
|
}
|