138 lines
4.8 KiB
Rust
138 lines
4.8 KiB
Rust
use rpki::audit::PublicationPointAudit;
|
|
use rpki::policy::{Policy, SignedObjectFailurePolicy};
|
|
use rpki::storage::{FetchCachePpPack, PackFile, PackTime};
|
|
use rpki::validation::manifest::PublicationPointSource;
|
|
use rpki::validation::objects::process_fetch_cache_pp_pack_for_issuer;
|
|
use rpki::validation::tree::{
|
|
CaInstanceHandle, PublicationPointRunResult, PublicationPointRunner, TreeRunConfig,
|
|
run_tree_serial_audit,
|
|
};
|
|
|
|
fn fixture_bytes(path: &str) -> Vec<u8> {
|
|
std::fs::read(std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")).join(path))
|
|
.unwrap_or_else(|e| panic!("read fixture {path}: {e}"))
|
|
}
|
|
|
|
fn dummy_pack(files: Vec<PackFile>) -> FetchCachePpPack {
|
|
let now = time::OffsetDateTime::now_utc();
|
|
let manifest_rsync_uri =
|
|
"rsync://rpki.cernet.net/repo/cernet/0/05FC9C5B88506F7C0D3F862C8895BED67E9F8EBA.mft";
|
|
FetchCachePpPack {
|
|
format_version: FetchCachePpPack::FORMAT_VERSION_V1,
|
|
manifest_rsync_uri: manifest_rsync_uri.to_string(),
|
|
publication_point_rsync_uri: "rsync://rpki.cernet.net/repo/cernet/0/".to_string(),
|
|
manifest_number_be: vec![1],
|
|
this_update: PackTime::from_utc_offset_datetime(now),
|
|
next_update: PackTime::from_utc_offset_datetime(now + time::Duration::hours(1)),
|
|
verified_at: PackTime::from_utc_offset_datetime(now),
|
|
manifest_bytes: fixture_bytes(
|
|
"tests/fixtures/repository/rpki.cernet.net/repo/cernet/0/05FC9C5B88506F7C0D3F862C8895BED67E9F8EBA.mft",
|
|
),
|
|
files,
|
|
}
|
|
}
|
|
|
|
struct SinglePackRunner {
|
|
policy: Policy,
|
|
pack: FetchCachePpPack,
|
|
}
|
|
|
|
impl PublicationPointRunner for SinglePackRunner {
|
|
fn run_publication_point(
|
|
&self,
|
|
ca: &CaInstanceHandle,
|
|
) -> Result<PublicationPointRunResult, String> {
|
|
let objects = process_fetch_cache_pp_pack_for_issuer(
|
|
&self.pack,
|
|
&self.policy,
|
|
&ca.ca_certificate_der,
|
|
ca.ca_certificate_rsync_uri.as_deref(),
|
|
ca.effective_ip_resources.as_ref(),
|
|
ca.effective_as_resources.as_ref(),
|
|
time::OffsetDateTime::now_utc(),
|
|
);
|
|
|
|
Ok(PublicationPointRunResult {
|
|
source: PublicationPointSource::Fresh,
|
|
pack: self.pack.clone(),
|
|
warnings: Vec::new(),
|
|
objects,
|
|
audit: PublicationPointAudit::default(),
|
|
discovered_children: Vec::new(),
|
|
})
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn crl_mismatch_drops_publication_point_and_cites_rfc_sections() {
|
|
let roa_bytes =
|
|
fixture_bytes("tests/fixtures/repository/rpki.cernet.net/repo/cernet/0/AS4538.roa");
|
|
|
|
// Include at least one CRL file but with a URI that does NOT match the EE certificate's CRLDP.
|
|
let pack = dummy_pack(vec![
|
|
PackFile::from_bytes_compute_sha256("rsync://example.test/repo/not-it.crl", vec![0x01]),
|
|
PackFile::from_bytes_compute_sha256("rsync://example.test/repo/a.roa", roa_bytes),
|
|
]);
|
|
|
|
let mut policy = Policy::default();
|
|
policy.signed_object_failure_policy = SignedObjectFailurePolicy::DropPublicationPoint;
|
|
|
|
let runner = SinglePackRunner { policy, pack };
|
|
|
|
let root = CaInstanceHandle {
|
|
depth: 0,
|
|
ca_certificate_der: vec![0x01, 0x02, 0x03],
|
|
ca_certificate_rsync_uri: None,
|
|
effective_ip_resources: None,
|
|
effective_as_resources: None,
|
|
rsync_base_uri: "rsync://example.test/repo/".to_string(),
|
|
manifest_rsync_uri:
|
|
"rsync://rpki.cernet.net/repo/cernet/0/05FC9C5B88506F7C0D3F862C8895BED67E9F8EBA.mft"
|
|
.to_string(),
|
|
publication_point_rsync_uri: "rsync://example.test/repo/".to_string(),
|
|
rrdp_notification_uri: None,
|
|
};
|
|
|
|
let out = run_tree_serial_audit(
|
|
root,
|
|
&runner,
|
|
&TreeRunConfig {
|
|
max_depth: Some(0),
|
|
max_instances: Some(1),
|
|
},
|
|
)
|
|
.expect("run tree audit");
|
|
|
|
assert_eq!(out.tree.instances_processed, 1);
|
|
assert_eq!(out.tree.instances_failed, 0);
|
|
|
|
assert!(
|
|
out.tree.warnings.iter().any(|w| w
|
|
.message
|
|
.contains("dropping publication point due to invalid ROA")),
|
|
"expected publication point drop warning"
|
|
);
|
|
let w = out
|
|
.tree
|
|
.warnings
|
|
.iter()
|
|
.find(|w| {
|
|
w.message
|
|
.contains("dropping publication point due to invalid ROA")
|
|
})
|
|
.expect("warning present");
|
|
let refs = w.rfc_refs.iter().map(|r| r.0).collect::<Vec<_>>();
|
|
assert!(
|
|
refs.contains(&"RFC 6487 §4.8.6"),
|
|
"expected CRLDP RFC reference in warning: {refs:?}"
|
|
);
|
|
assert!(
|
|
refs.contains(&"RFC 9286 §4.2.1"),
|
|
"expected manifest locked-pack RFC reference in warning: {refs:?}"
|
|
);
|
|
|
|
assert_eq!(out.publication_points.len(), 1);
|
|
assert_eq!(out.publication_points[0].node_id, Some(0));
|
|
assert_eq!(out.publication_points[0].parent_node_id, None);
|
|
}
|