rpki/tests/test_ca_instance_uris_coverage.rs
2026-03-04 11:12:53 +08:00

150 lines
5.1 KiB
Rust

use rpki::data_model::oid::{OID_AD_CA_REPOSITORY, OID_AD_RPKI_MANIFEST, OID_AD_RPKI_NOTIFY};
use rpki::data_model::rc::{
AccessDescription, ResourceCertKind, ResourceCertificate, SubjectInfoAccess,
SubjectInfoAccessCa,
};
use rpki::validation::ca_instance::{CaInstanceUrisError, ca_instance_uris_from_ca_certificate};
fn apnic_child_ca_fixture_der() -> Vec<u8> {
std::fs::read(
"tests/fixtures/repository/rpki.apnic.net/repository/B527EF581D6611E2BB468F7C72FD1FF2/BfycW4hQb3wNP4YsiJW-1n6fjro.cer",
)
.expect("read apnic fixture ca")
}
fn set_sia_ca(cert: &mut ResourceCertificate, ads: Vec<AccessDescription>) {
cert.tbs.extensions.subject_info_access = Some(SubjectInfoAccess::Ca(SubjectInfoAccessCa {
access_descriptions: ads,
}));
}
#[test]
fn ca_instance_uris_success_and_error_branches() {
let mut cert = ResourceCertificate::decode_der(&apnic_child_ca_fixture_der())
.expect("decode apnic fixture ca");
// Success path.
let uris = ca_instance_uris_from_ca_certificate(&cert).expect("uris");
assert!(uris.rsync_base_uri.starts_with("rsync://"));
assert!(uris.rsync_base_uri.ends_with('/'));
assert!(uris.manifest_rsync_uri.starts_with("rsync://"));
assert!(uris.manifest_rsync_uri.ends_with(".mft"));
// NotCa.
cert.kind = ResourceCertKind::Ee;
let err = ca_instance_uris_from_ca_certificate(&cert).unwrap_err();
assert!(matches!(err, CaInstanceUrisError::NotCa));
cert.kind = ResourceCertKind::Ca;
// MissingSia.
cert.tbs.extensions.subject_info_access = None;
let err = ca_instance_uris_from_ca_certificate(&cert).unwrap_err();
assert!(matches!(err, CaInstanceUrisError::MissingSia));
// MissingCaRepository / MissingRpkiManifest.
set_sia_ca(
&mut cert,
vec![AccessDescription {
access_method_oid: OID_AD_RPKI_MANIFEST.to_string(),
access_location: "rsync://example.test/repo/x.mft".to_string(),
}],
);
let err = ca_instance_uris_from_ca_certificate(&cert).unwrap_err();
assert!(
matches!(err, CaInstanceUrisError::MissingCaRepository),
"{err}"
);
set_sia_ca(
&mut cert,
vec![AccessDescription {
access_method_oid: OID_AD_CA_REPOSITORY.to_string(),
access_location: "rsync://example.test/repo/".to_string(),
}],
);
let err = ca_instance_uris_from_ca_certificate(&cert).unwrap_err();
assert!(
matches!(err, CaInstanceUrisError::MissingRpkiManifest),
"{err}"
);
// Scheme validation branches.
set_sia_ca(
&mut cert,
vec![AccessDescription {
access_method_oid: OID_AD_CA_REPOSITORY.to_string(),
access_location: "http://example.test/repo/".to_string(),
}],
);
let err = ca_instance_uris_from_ca_certificate(&cert).unwrap_err();
assert!(
matches!(err, CaInstanceUrisError::CaRepositoryNotRsync(_)),
"{err}"
);
set_sia_ca(
&mut cert,
vec![
AccessDescription {
access_method_oid: OID_AD_CA_REPOSITORY.to_string(),
access_location: "rsync://example.test/repo/".to_string(),
},
AccessDescription {
access_method_oid: OID_AD_RPKI_MANIFEST.to_string(),
access_location: "http://example.test/repo/x.mft".to_string(),
},
],
);
let err = ca_instance_uris_from_ca_certificate(&cert).unwrap_err();
assert!(
matches!(err, CaInstanceUrisError::RpkiManifestNotRsync(_)),
"{err}"
);
set_sia_ca(
&mut cert,
vec![
AccessDescription {
access_method_oid: OID_AD_CA_REPOSITORY.to_string(),
access_location: "rsync://example.test/repo/".to_string(),
},
AccessDescription {
access_method_oid: OID_AD_RPKI_MANIFEST.to_string(),
access_location: "rsync://example.test/repo/x.mft".to_string(),
},
AccessDescription {
access_method_oid: OID_AD_RPKI_NOTIFY.to_string(),
access_location: "rsync://example.test/repo/notification.xml".to_string(),
},
],
);
let err = ca_instance_uris_from_ca_certificate(&cert).unwrap_err();
assert!(
matches!(err, CaInstanceUrisError::RpkiNotifyNotHttps(_)),
"{err}"
);
// ManifestNotUnderPublicationPoint.
set_sia_ca(
&mut cert,
vec![
AccessDescription {
access_method_oid: OID_AD_CA_REPOSITORY.to_string(),
access_location: "rsync://example.test/repo/".to_string(),
},
AccessDescription {
access_method_oid: OID_AD_RPKI_MANIFEST.to_string(),
access_location: "rsync://other.test/repo/x.mft".to_string(),
},
],
);
let err = ca_instance_uris_from_ca_certificate(&cert).unwrap_err();
assert!(
matches!(
err,
CaInstanceUrisError::ManifestNotUnderPublicationPoint { .. }
),
"{err}"
);
}