20260511 CIR V3 trust anchors self-contained
This commit is contained in:
@@ -6,8 +6,8 @@ use rpki::ccr::{
|
||||
encode_content_info,
|
||||
};
|
||||
use rpki::cir::{
|
||||
CIR_VERSION_V2, CanonicalInputRepresentation, CirHashAlgorithm, CirObject, CirTal,
|
||||
compute_reject_list_sha256, encode_cir,
|
||||
CIR_VERSION_V3, CanonicalInputRepresentation, CirHashAlgorithm, CirObject, CirTrustAnchor,
|
||||
compute_reject_list_sha256, encode_cir, sha256,
|
||||
};
|
||||
|
||||
fn skip_heavy_blackbox_test() -> bool {
|
||||
@@ -42,9 +42,10 @@ fn cir_full_and_delta_pair_reuses_shared_repo_bytes_db() {
|
||||
use sha2::{Digest, Sha256};
|
||||
hex::encode(Sha256::digest(b"delta-object"))
|
||||
};
|
||||
let trust_anchors = vec![test_trust_anchor()];
|
||||
|
||||
let full_cir = CanonicalInputRepresentation {
|
||||
version: CIR_VERSION_V2,
|
||||
version: CIR_VERSION_V3,
|
||||
hash_alg: CirHashAlgorithm::Sha256,
|
||||
validation_time: time::OffsetDateTime::parse(
|
||||
"2026-03-16T11:49:15Z",
|
||||
@@ -55,15 +56,12 @@ fn cir_full_and_delta_pair_reuses_shared_repo_bytes_db() {
|
||||
rsync_uri: "rsync://example.net/repo/full.roa".to_string(),
|
||||
sha256: hex::decode(&full_obj_hash).unwrap(),
|
||||
}],
|
||||
tals: vec![CirTal {
|
||||
tal_uri: "https://rpki.apnic.net/tal/apnic-rfc7730-https.tal".to_string(),
|
||||
tal_bytes: b"rsync://example.net/repo/root.cer\nMIIB".to_vec(),
|
||||
}],
|
||||
trust_anchors: trust_anchors.clone(),
|
||||
reject_list_sha256: compute_reject_list_sha256(std::iter::empty::<&str>()),
|
||||
rejected_objects: Vec::new(),
|
||||
};
|
||||
let delta_cir = CanonicalInputRepresentation {
|
||||
version: CIR_VERSION_V2,
|
||||
version: CIR_VERSION_V3,
|
||||
hash_alg: CirHashAlgorithm::Sha256,
|
||||
validation_time: time::OffsetDateTime::parse(
|
||||
"2026-03-16T11:50:15Z",
|
||||
@@ -84,7 +82,7 @@ fn cir_full_and_delta_pair_reuses_shared_repo_bytes_db() {
|
||||
objects.sort_by(|a, b| a.rsync_uri.cmp(&b.rsync_uri));
|
||||
objects
|
||||
},
|
||||
tals: full_cir.tals.clone(),
|
||||
trust_anchors,
|
||||
reject_list_sha256: compute_reject_list_sha256(std::iter::empty::<&str>()),
|
||||
rejected_objects: Vec::new(),
|
||||
};
|
||||
@@ -226,3 +224,15 @@ fi
|
||||
assert!(out.join("full").join("result.ccr").is_file());
|
||||
assert!(out.join("delta-001").join("result.ccr").is_file());
|
||||
}
|
||||
|
||||
fn test_trust_anchor() -> CirTrustAnchor {
|
||||
let ta_rsync_uri = "rsync://example.net/repo/root.cer";
|
||||
let ta_certificate_der = b"ta-der".to_vec();
|
||||
CirTrustAnchor {
|
||||
ta_rsync_uri: ta_rsync_uri.to_string(),
|
||||
tal_uri: "https://rpki.apnic.net/tal/apnic-rfc7730-https.tal".to_string(),
|
||||
tal_bytes: format!("{ta_rsync_uri}\n\nAQID\n").into_bytes(),
|
||||
ta_certificate_sha256: sha256(&ta_certificate_der),
|
||||
ta_certificate_der,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@ use rpki::ccr::{
|
||||
encode_content_info,
|
||||
};
|
||||
use rpki::cir::{
|
||||
CIR_VERSION_V2, CanonicalInputRepresentation, CirHashAlgorithm, CirObject, CirTal,
|
||||
compute_reject_list_sha256, encode_cir,
|
||||
CIR_VERSION_V3, CanonicalInputRepresentation, CirHashAlgorithm, CirObject, CirTrustAnchor,
|
||||
compute_reject_list_sha256, encode_cir, sha256,
|
||||
};
|
||||
|
||||
#[test]
|
||||
@@ -34,7 +34,7 @@ fn cir_drop_report_counts_dropped_roa_objects_and_vrps() {
|
||||
.expect("write repo bytes");
|
||||
|
||||
let cir = CanonicalInputRepresentation {
|
||||
version: CIR_VERSION_V2,
|
||||
version: CIR_VERSION_V3,
|
||||
hash_alg: CirHashAlgorithm::Sha256,
|
||||
validation_time: time::OffsetDateTime::parse(
|
||||
"2026-04-09T00:00:00Z",
|
||||
@@ -45,10 +45,7 @@ fn cir_drop_report_counts_dropped_roa_objects_and_vrps() {
|
||||
rsync_uri: "rsync://example.net/repo/AS4538.roa".to_string(),
|
||||
sha256: hex::decode(&hash).unwrap(),
|
||||
}],
|
||||
tals: vec![CirTal {
|
||||
tal_uri: "https://example.test/root.tal".to_string(),
|
||||
tal_bytes: b"rsync://example.net/repo/root.cer\nMIIB".to_vec(),
|
||||
}],
|
||||
trust_anchors: vec![test_trust_anchor()],
|
||||
reject_list_sha256: compute_reject_list_sha256(std::iter::empty::<&str>()),
|
||||
rejected_objects: Vec::new(),
|
||||
};
|
||||
@@ -124,3 +121,15 @@ fn cir_drop_report_counts_dropped_roa_objects_and_vrps() {
|
||||
.contains("Dropped By Reason")
|
||||
);
|
||||
}
|
||||
|
||||
fn test_trust_anchor() -> CirTrustAnchor {
|
||||
let ta_rsync_uri = "rsync://example.net/repo/root.cer";
|
||||
let ta_certificate_der = b"ta-der".to_vec();
|
||||
CirTrustAnchor {
|
||||
ta_rsync_uri: ta_rsync_uri.to_string(),
|
||||
tal_uri: "https://example.test/root.tal".to_string(),
|
||||
tal_bytes: format!("{ta_rsync_uri}\n\nAQID\n").into_bytes(),
|
||||
ta_certificate_sha256: sha256(&ta_certificate_der),
|
||||
ta_certificate_der,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ use std::process::Command;
|
||||
|
||||
use rpki::blob_store::ExternalRepoBytesDb;
|
||||
use rpki::cir::{
|
||||
CIR_VERSION_V2, CanonicalInputRepresentation, CirHashAlgorithm, CirObject, CirTal,
|
||||
compute_reject_list_sha256, encode_cir, materialize_cir_from_repo_bytes,
|
||||
CIR_VERSION_V3, CanonicalInputRepresentation, CirHashAlgorithm, CirTrustAnchor,
|
||||
compute_reject_list_sha256, encode_cir, materialize_cir_from_repo_bytes, sha256,
|
||||
};
|
||||
|
||||
fn skip_heavy_script_replay_test() -> bool {
|
||||
@@ -30,26 +30,22 @@ fn build_ta_only_cir() -> (CanonicalInputRepresentation, Vec<u8>) {
|
||||
.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_V2,
|
||||
version: CIR_VERSION_V3,
|
||||
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 {
|
||||
objects: Vec::new(),
|
||||
trust_anchors: vec![CirTrustAnchor {
|
||||
ta_rsync_uri,
|
||||
tal_uri: "https://example.test/root.tal".to_string(),
|
||||
tal_bytes,
|
||||
ta_certificate_sha256: sha256(&ta_bytes),
|
||||
ta_certificate_der: ta_bytes.clone(),
|
||||
}],
|
||||
reject_list_sha256: compute_reject_list_sha256(std::iter::empty::<&str>()),
|
||||
rejected_objects: Vec::new(),
|
||||
|
||||
@@ -3,8 +3,8 @@ use std::process::Command;
|
||||
|
||||
use rpki::blob_store::ExternalRepoBytesDb;
|
||||
use rpki::cir::{
|
||||
CIR_VERSION_V2, CanonicalInputRepresentation, CirHashAlgorithm, CirObject, CirTal,
|
||||
compute_reject_list_sha256, encode_cir, materialize_cir_from_repo_bytes,
|
||||
CIR_VERSION_V3, CanonicalInputRepresentation, CirHashAlgorithm, CirTrustAnchor,
|
||||
compute_reject_list_sha256, encode_cir, materialize_cir_from_repo_bytes, sha256,
|
||||
};
|
||||
|
||||
fn skip_heavy_script_replay_test() -> bool {
|
||||
@@ -30,26 +30,22 @@ fn build_ta_only_cir() -> (CanonicalInputRepresentation, Vec<u8>) {
|
||||
.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_V2,
|
||||
version: CIR_VERSION_V3,
|
||||
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 {
|
||||
objects: Vec::new(),
|
||||
trust_anchors: vec![CirTrustAnchor {
|
||||
ta_rsync_uri,
|
||||
tal_uri: "https://example.test/root.tal".to_string(),
|
||||
tal_bytes,
|
||||
ta_certificate_sha256: sha256(&ta_bytes),
|
||||
ta_certificate_der: ta_bytes.clone(),
|
||||
}],
|
||||
reject_list_sha256: compute_reject_list_sha256(std::iter::empty::<&str>()),
|
||||
rejected_objects: Vec::new(),
|
||||
|
||||
@@ -6,8 +6,8 @@ use rpki::ccr::{
|
||||
encode_content_info,
|
||||
};
|
||||
use rpki::cir::{
|
||||
CIR_VERSION_V2, CanonicalInputRepresentation, CirHashAlgorithm, CirObject, CirTal,
|
||||
compute_reject_list_sha256, encode_cir,
|
||||
CIR_VERSION_V3, CanonicalInputRepresentation, CirHashAlgorithm, CirObject, CirTrustAnchor,
|
||||
compute_reject_list_sha256, encode_cir, sha256,
|
||||
};
|
||||
|
||||
fn skip_heavy_blackbox_test() -> bool {
|
||||
@@ -36,7 +36,7 @@ fn cir_offline_sequence_writes_parseable_sequence_json_and_steps() {
|
||||
.unwrap();
|
||||
|
||||
let mk_cir = |uri: &str, hash_hex: &str, vt: &str| CanonicalInputRepresentation {
|
||||
version: CIR_VERSION_V2,
|
||||
version: CIR_VERSION_V3,
|
||||
hash_alg: CirHashAlgorithm::Sha256,
|
||||
validation_time: time::OffsetDateTime::parse(
|
||||
vt,
|
||||
@@ -47,10 +47,7 @@ fn cir_offline_sequence_writes_parseable_sequence_json_and_steps() {
|
||||
rsync_uri: uri.to_string(),
|
||||
sha256: hex::decode(hash_hex).unwrap(),
|
||||
}],
|
||||
tals: vec![CirTal {
|
||||
tal_uri: "https://rpki.apnic.net/tal/apnic-rfc7730-https.tal".to_string(),
|
||||
tal_bytes: b"rsync://example.net/repo/root.cer\nMIIB".to_vec(),
|
||||
}],
|
||||
trust_anchors: vec![test_trust_anchor()],
|
||||
reject_list_sha256: compute_reject_list_sha256(std::iter::empty::<&str>()),
|
||||
rejected_objects: Vec::new(),
|
||||
};
|
||||
@@ -68,7 +65,7 @@ fn cir_offline_sequence_writes_parseable_sequence_json_and_steps() {
|
||||
"2026-03-16T11:49:15Z",
|
||||
);
|
||||
let delta_cir = CanonicalInputRepresentation {
|
||||
version: CIR_VERSION_V2,
|
||||
version: CIR_VERSION_V3,
|
||||
hash_alg: CirHashAlgorithm::Sha256,
|
||||
validation_time: time::OffsetDateTime::parse(
|
||||
"2026-03-16T11:50:15Z",
|
||||
@@ -86,7 +83,7 @@ fn cir_offline_sequence_writes_parseable_sequence_json_and_steps() {
|
||||
objects.sort_by(|a, b| a.rsync_uri.cmp(&b.rsync_uri));
|
||||
objects
|
||||
},
|
||||
tals: full_cir.tals.clone(),
|
||||
trust_anchors: full_cir.trust_anchors.clone(),
|
||||
reject_list_sha256: compute_reject_list_sha256(std::iter::empty::<&str>()),
|
||||
rejected_objects: Vec::new(),
|
||||
};
|
||||
@@ -244,3 +241,15 @@ fi
|
||||
assert!(out.join(rel).is_file(), "missing {}", rel);
|
||||
}
|
||||
}
|
||||
|
||||
fn test_trust_anchor() -> CirTrustAnchor {
|
||||
let ta_rsync_uri = "rsync://example.net/repo/root.cer";
|
||||
let ta_certificate_der = b"ta-der".to_vec();
|
||||
CirTrustAnchor {
|
||||
ta_rsync_uri: ta_rsync_uri.to_string(),
|
||||
tal_uri: "https://rpki.apnic.net/tal/apnic-rfc7730-https.tal".to_string(),
|
||||
tal_bytes: format!("{ta_rsync_uri}\n\nAQID\n").into_bytes(),
|
||||
ta_certificate_sha256: sha256(&ta_certificate_der),
|
||||
ta_certificate_der,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ use std::process::Command;
|
||||
|
||||
use rpki::blob_store::ExternalRepoBytesDb;
|
||||
use rpki::cir::{
|
||||
CIR_VERSION_V2, CanonicalInputRepresentation, CirHashAlgorithm, CirObject, CirTal,
|
||||
compute_reject_list_sha256, encode_cir, materialize_cir_from_repo_bytes,
|
||||
CIR_VERSION_V3, CanonicalInputRepresentation, CirHashAlgorithm, CirTrustAnchor,
|
||||
compute_reject_list_sha256, encode_cir, materialize_cir_from_repo_bytes, sha256,
|
||||
};
|
||||
|
||||
fn skip_heavy_script_replay_test() -> bool {
|
||||
@@ -30,26 +30,22 @@ fn build_ta_only_cir() -> (CanonicalInputRepresentation, Vec<u8>) {
|
||||
.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_V2,
|
||||
version: CIR_VERSION_V3,
|
||||
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 {
|
||||
objects: Vec::new(),
|
||||
trust_anchors: vec![CirTrustAnchor {
|
||||
ta_rsync_uri,
|
||||
tal_uri: "https://example.test/root.tal".to_string(),
|
||||
tal_bytes,
|
||||
ta_certificate_sha256: sha256(&ta_bytes),
|
||||
ta_certificate_der: ta_bytes.clone(),
|
||||
}],
|
||||
reject_list_sha256: compute_reject_list_sha256(std::iter::empty::<&str>()),
|
||||
rejected_objects: Vec::new(),
|
||||
|
||||
@@ -3,8 +3,8 @@ use std::process::Command;
|
||||
|
||||
use rpki::blob_store::ExternalRepoBytesDb;
|
||||
use rpki::cir::{
|
||||
CIR_VERSION_V2, CanonicalInputRepresentation, CirHashAlgorithm, CirObject, CirTal,
|
||||
compute_reject_list_sha256, encode_cir, materialize_cir_from_repo_bytes,
|
||||
CIR_VERSION_V3, CanonicalInputRepresentation, CirHashAlgorithm, CirTrustAnchor,
|
||||
compute_reject_list_sha256, encode_cir, materialize_cir_from_repo_bytes, sha256,
|
||||
};
|
||||
|
||||
fn skip_heavy_script_replay_test() -> bool {
|
||||
@@ -30,26 +30,22 @@ fn build_ta_only_cir() -> (CanonicalInputRepresentation, Vec<u8>) {
|
||||
.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_V2,
|
||||
version: CIR_VERSION_V3,
|
||||
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 {
|
||||
objects: Vec::new(),
|
||||
trust_anchors: vec![CirTrustAnchor {
|
||||
ta_rsync_uri,
|
||||
tal_uri: "https://example.test/root.tal".to_string(),
|
||||
tal_bytes,
|
||||
ta_certificate_sha256: sha256(&ta_bytes),
|
||||
ta_certificate_der: ta_bytes.clone(),
|
||||
}],
|
||||
reject_list_sha256: compute_reject_list_sha256(std::iter::empty::<&str>()),
|
||||
rejected_objects: Vec::new(),
|
||||
|
||||
@@ -127,12 +127,16 @@ fn cli_run_offline_mode_writes_cir_and_static_pool() {
|
||||
|
||||
let bytes = std::fs::read(&cir_path).expect("read cir");
|
||||
let cir = rpki::cir::decode_cir(&bytes).expect("decode cir");
|
||||
assert_eq!(cir.tals.len(), 1);
|
||||
assert_eq!(cir.tals[0].tal_uri, "https://example.test/root.tal");
|
||||
assert_eq!(cir.trust_anchors.len(), 1);
|
||||
assert_eq!(
|
||||
cir.trust_anchors[0].tal_uri,
|
||||
"https://example.test/root.tal"
|
||||
);
|
||||
assert!(!cir.trust_anchors[0].ta_certificate_der.is_empty());
|
||||
assert!(
|
||||
cir.objects
|
||||
!cir.objects
|
||||
.iter()
|
||||
.any(|item| item.rsync_uri.contains("apnic-rpki-root-iana-origin.cer"))
|
||||
.any(|item| item.rsync_uri == cir.trust_anchors[0].ta_rsync_uri)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user