235 lines
7.4 KiB
Rust
235 lines
7.4 KiB
Rust
use rpki::validation::from_tal::discover_root_ca_instance_from_tal_and_ta_der;
|
|
use rpki::validation::run_tree_from_tal::root_handle_from_trust_anchor;
|
|
use rpki::validation::run_tree_from_tal::{
|
|
run_tree_from_tal_and_ta_der_serial, run_tree_from_tal_and_ta_der_serial_audit,
|
|
run_tree_from_tal_url_serial, run_tree_from_tal_url_serial_audit,
|
|
};
|
|
use rpki::validation::tree::TreeRunConfig;
|
|
|
|
use std::collections::HashMap;
|
|
|
|
struct MapHttpFetcher {
|
|
map: HashMap<String, Vec<u8>>,
|
|
}
|
|
|
|
impl rpki::sync::rrdp::Fetcher for MapHttpFetcher {
|
|
fn fetch(&self, uri: &str) -> Result<Vec<u8>, String> {
|
|
self.map
|
|
.get(uri)
|
|
.cloned()
|
|
.ok_or_else(|| format!("no fixture mapped for {uri}"))
|
|
}
|
|
}
|
|
|
|
struct EmptyRsyncFetcher;
|
|
impl rpki::fetch::rsync::RsyncFetcher for EmptyRsyncFetcher {
|
|
fn fetch_objects(
|
|
&self,
|
|
_rsync_base_uri: &str,
|
|
) -> Result<Vec<(String, Vec<u8>)>, rpki::fetch::rsync::RsyncFetchError> {
|
|
Ok(Vec::new())
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn root_handle_is_constructible_from_fixture_tal_and_ta() {
|
|
let tal_bytes = std::fs::read("tests/fixtures/tal/apnic-rfc7730-https.tal")
|
|
.expect("read apnic tal fixture");
|
|
let ta_der = std::fs::read("tests/fixtures/ta/apnic-ta.cer").expect("read apnic ta fixture");
|
|
|
|
let discovery =
|
|
discover_root_ca_instance_from_tal_and_ta_der(&tal_bytes, &ta_der, None).expect("discover");
|
|
|
|
let root = root_handle_from_trust_anchor(&discovery.trust_anchor, None, &discovery.ca_instance);
|
|
|
|
assert_eq!(root.depth, 0);
|
|
assert_eq!(
|
|
root.manifest_rsync_uri,
|
|
discovery.ca_instance.manifest_rsync_uri
|
|
);
|
|
assert_eq!(root.rsync_base_uri, discovery.ca_instance.rsync_base_uri);
|
|
assert!(
|
|
root.ca_certificate_der.len() > 100,
|
|
"TA der should be non-empty"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn run_tree_from_tal_url_entry_executes_and_records_failure_when_repo_empty() {
|
|
let tal_url = "mock:apnic.tal";
|
|
let tal_bytes = std::fs::read("tests/fixtures/tal/apnic-rfc7730-https.tal")
|
|
.expect("read apnic tal fixture");
|
|
let ta_der = std::fs::read("tests/fixtures/ta/apnic-ta.cer").expect("read apnic ta fixture");
|
|
|
|
let mut map = HashMap::new();
|
|
map.insert(tal_url.to_string(), tal_bytes);
|
|
map.insert(
|
|
"https://rpki.apnic.net/repository/apnic-rpki-root-iana-origin.cer".to_string(),
|
|
ta_der.clone(),
|
|
);
|
|
map.insert(
|
|
"rsync://rpki.apnic.net/repository/apnic-rpki-root-iana-origin.cer".to_string(),
|
|
ta_der.clone(),
|
|
);
|
|
let http = MapHttpFetcher { map };
|
|
|
|
let rsync = EmptyRsyncFetcher;
|
|
let temp = tempfile::tempdir().expect("tempdir");
|
|
let store = rpki::storage::RocksStore::open(temp.path()).expect("open rocksdb");
|
|
let policy = rpki::policy::Policy {
|
|
sync_preference: rpki::policy::SyncPreference::RsyncOnly,
|
|
..rpki::policy::Policy::default()
|
|
};
|
|
|
|
let out = run_tree_from_tal_url_serial(
|
|
&store,
|
|
&policy,
|
|
tal_url,
|
|
&http,
|
|
&rsync,
|
|
time::OffsetDateTime::now_utc(),
|
|
&TreeRunConfig {
|
|
max_depth: Some(0),
|
|
max_instances: Some(1),
|
|
},
|
|
)
|
|
.expect("run tree");
|
|
assert_eq!(out.tree.instances_processed, 0);
|
|
assert_eq!(out.tree.instances_failed, 1);
|
|
assert!(
|
|
out.tree
|
|
.warnings
|
|
.iter()
|
|
.any(|w| w.message.contains("publication point failed")),
|
|
"expected failure warning"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn run_tree_from_tal_and_ta_der_entry_executes_and_records_failure_when_repo_empty() {
|
|
let tal_bytes = std::fs::read("tests/fixtures/tal/apnic-rfc7730-https.tal")
|
|
.expect("read apnic tal fixture");
|
|
let ta_der = std::fs::read("tests/fixtures/ta/apnic-ta.cer").expect("read apnic ta fixture");
|
|
|
|
let http = MapHttpFetcher {
|
|
map: HashMap::new(),
|
|
};
|
|
let rsync = EmptyRsyncFetcher;
|
|
let temp = tempfile::tempdir().expect("tempdir");
|
|
let store = rpki::storage::RocksStore::open(temp.path()).expect("open rocksdb");
|
|
let policy = rpki::policy::Policy {
|
|
sync_preference: rpki::policy::SyncPreference::RsyncOnly,
|
|
..rpki::policy::Policy::default()
|
|
};
|
|
|
|
let out = run_tree_from_tal_and_ta_der_serial(
|
|
&store,
|
|
&policy,
|
|
&tal_bytes,
|
|
&ta_der,
|
|
None,
|
|
&http,
|
|
&rsync,
|
|
time::OffsetDateTime::now_utc(),
|
|
&TreeRunConfig {
|
|
max_depth: Some(0),
|
|
max_instances: Some(1),
|
|
},
|
|
)
|
|
.expect("run tree");
|
|
assert_eq!(out.tree.instances_processed, 0);
|
|
assert_eq!(out.tree.instances_failed, 1);
|
|
assert!(
|
|
out.tree
|
|
.warnings
|
|
.iter()
|
|
.any(|w| w.message.contains("publication point failed")),
|
|
"expected failure warning"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn run_tree_from_tal_url_audit_entry_collects_no_publication_points_when_repo_empty() {
|
|
let tal_url = "mock:apnic.tal";
|
|
let tal_bytes = std::fs::read("tests/fixtures/tal/apnic-rfc7730-https.tal")
|
|
.expect("read apnic tal fixture");
|
|
let ta_der = std::fs::read("tests/fixtures/ta/apnic-ta.cer").expect("read apnic ta fixture");
|
|
|
|
let mut map = HashMap::new();
|
|
map.insert(tal_url.to_string(), tal_bytes);
|
|
map.insert(
|
|
"https://rpki.apnic.net/repository/apnic-rpki-root-iana-origin.cer".to_string(),
|
|
ta_der.clone(),
|
|
);
|
|
map.insert(
|
|
"rsync://rpki.apnic.net/repository/apnic-rpki-root-iana-origin.cer".to_string(),
|
|
ta_der.clone(),
|
|
);
|
|
let http = MapHttpFetcher { map };
|
|
let rsync = EmptyRsyncFetcher;
|
|
|
|
let temp = tempfile::tempdir().expect("tempdir");
|
|
let store = rpki::storage::RocksStore::open(temp.path()).expect("open rocksdb");
|
|
let policy = rpki::policy::Policy {
|
|
sync_preference: rpki::policy::SyncPreference::RsyncOnly,
|
|
..rpki::policy::Policy::default()
|
|
};
|
|
|
|
let out = run_tree_from_tal_url_serial_audit(
|
|
&store,
|
|
&policy,
|
|
tal_url,
|
|
&http,
|
|
&rsync,
|
|
time::OffsetDateTime::now_utc(),
|
|
&TreeRunConfig {
|
|
max_depth: Some(0),
|
|
max_instances: Some(1),
|
|
},
|
|
)
|
|
.expect("run tree audit");
|
|
|
|
assert_eq!(out.tree.instances_processed, 0);
|
|
assert_eq!(out.tree.instances_failed, 1);
|
|
assert!(out.publication_points.is_empty());
|
|
}
|
|
|
|
#[test]
|
|
fn run_tree_from_tal_and_ta_der_audit_entry_collects_no_publication_points_when_repo_empty() {
|
|
let tal_bytes = std::fs::read("tests/fixtures/tal/apnic-rfc7730-https.tal")
|
|
.expect("read apnic tal fixture");
|
|
let ta_der = std::fs::read("tests/fixtures/ta/apnic-ta.cer").expect("read apnic ta fixture");
|
|
|
|
let http = MapHttpFetcher {
|
|
map: HashMap::new(),
|
|
};
|
|
let rsync = EmptyRsyncFetcher;
|
|
|
|
let temp = tempfile::tempdir().expect("tempdir");
|
|
let store = rpki::storage::RocksStore::open(temp.path()).expect("open rocksdb");
|
|
let policy = rpki::policy::Policy {
|
|
sync_preference: rpki::policy::SyncPreference::RsyncOnly,
|
|
..rpki::policy::Policy::default()
|
|
};
|
|
|
|
let out = run_tree_from_tal_and_ta_der_serial_audit(
|
|
&store,
|
|
&policy,
|
|
&tal_bytes,
|
|
&ta_der,
|
|
None,
|
|
&http,
|
|
&rsync,
|
|
time::OffsetDateTime::now_utc(),
|
|
&TreeRunConfig {
|
|
max_depth: Some(0),
|
|
max_instances: Some(1),
|
|
},
|
|
)
|
|
.expect("run tree audit");
|
|
|
|
assert_eq!(out.tree.instances_processed, 0);
|
|
assert_eq!(out.tree.instances_failed, 1);
|
|
assert!(out.publication_points.is_empty());
|
|
}
|