177 lines
5.6 KiB
Rust
177 lines
5.6 KiB
Rust
use der_parser::num_bigint::BigUint;
|
|
use time::OffsetDateTime;
|
|
|
|
use rpki::data_model::rc::{
|
|
Afi, AsResourceSet, IpAddressChoice, IpAddressFamily, IpAddressOrRange, IpPrefix, IpResourceSet,
|
|
RcExtensions, ResourceCertKind, ResourceCertificate, RpkixTbsCertificate, SubjectInfoAccess,
|
|
};
|
|
use rpki::data_model::roa::{RoaAfi, RoaEContent, RoaIpAddress, RoaIpAddressFamily, RoaValidateError};
|
|
|
|
fn dummy_ee(ip_resources: Option<IpResourceSet>, as_resources: Option<AsResourceSet>) -> ResourceCertificate {
|
|
ResourceCertificate {
|
|
raw_der: vec![],
|
|
tbs: RpkixTbsCertificate {
|
|
version: 2,
|
|
serial_number: BigUint::from(1u8),
|
|
signature_algorithm: "1.2.840.113549.1.1.11".to_string(),
|
|
issuer_dn: "CN=issuer".to_string(),
|
|
subject_dn: "CN=subject".to_string(),
|
|
validity_not_before: OffsetDateTime::UNIX_EPOCH,
|
|
validity_not_after: OffsetDateTime::UNIX_EPOCH,
|
|
subject_public_key_info: vec![],
|
|
extensions: RcExtensions {
|
|
basic_constraints_ca: false,
|
|
subject_key_identifier: Some(vec![0x01]),
|
|
subject_info_access: Some(SubjectInfoAccess::Ca(
|
|
rpki::data_model::rc::SubjectInfoAccessCa {
|
|
access_descriptions: vec![],
|
|
},
|
|
)),
|
|
certificate_policies_oid: None,
|
|
ip_resources,
|
|
as_resources,
|
|
},
|
|
},
|
|
kind: ResourceCertKind::Ee,
|
|
}
|
|
}
|
|
|
|
fn test_roa_single_v4_prefix() -> RoaEContent {
|
|
RoaEContent {
|
|
version: 0,
|
|
as_id: 64496,
|
|
ip_addr_blocks: vec![RoaIpAddressFamily {
|
|
afi: RoaAfi::Ipv4,
|
|
addresses: vec![RoaIpAddress {
|
|
prefix: rpki::data_model::roa::IpPrefix {
|
|
afi: RoaAfi::Ipv4,
|
|
prefix_len: 8,
|
|
addr: vec![10, 0, 0, 0],
|
|
},
|
|
max_length: Some(24),
|
|
}],
|
|
}],
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn validate_accepts_when_prefix_is_covered() {
|
|
let roa = test_roa_single_v4_prefix();
|
|
let ee = dummy_ee(
|
|
Some(IpResourceSet {
|
|
families: vec![IpAddressFamily {
|
|
afi: Afi::Ipv4,
|
|
choice: IpAddressChoice::AddressesOrRanges(vec![IpAddressOrRange::Prefix(
|
|
IpPrefix {
|
|
afi: Afi::Ipv4,
|
|
prefix_len: 0,
|
|
addr: vec![0, 0, 0, 0],
|
|
},
|
|
)]),
|
|
}],
|
|
}),
|
|
None,
|
|
);
|
|
roa.validate_against_ee_cert(&ee)
|
|
.expect("prefix should be covered by 0/0");
|
|
}
|
|
|
|
#[test]
|
|
fn validate_rejects_when_as_resources_present() {
|
|
let roa = test_roa_single_v4_prefix();
|
|
let ee = dummy_ee(
|
|
Some(IpResourceSet { families: vec![] }),
|
|
Some(AsResourceSet {
|
|
asnum: None,
|
|
rdi: None,
|
|
}),
|
|
);
|
|
let err = roa.validate_against_ee_cert(&ee).unwrap_err();
|
|
assert!(matches!(err, RoaValidateError::EeAsResourcesPresent));
|
|
}
|
|
|
|
#[test]
|
|
fn validate_rejects_when_ip_resources_missing() {
|
|
let roa = test_roa_single_v4_prefix();
|
|
let ee = dummy_ee(None, None);
|
|
let err = roa.validate_against_ee_cert(&ee).unwrap_err();
|
|
assert!(matches!(err, RoaValidateError::EeIpResourcesMissing));
|
|
}
|
|
|
|
#[test]
|
|
fn validate_rejects_when_ip_resources_inherit() {
|
|
let roa = test_roa_single_v4_prefix();
|
|
let ee = dummy_ee(
|
|
Some(IpResourceSet {
|
|
families: vec![IpAddressFamily {
|
|
afi: Afi::Ipv4,
|
|
choice: IpAddressChoice::Inherit,
|
|
}],
|
|
}),
|
|
None,
|
|
);
|
|
let err = roa.validate_against_ee_cert(&ee).unwrap_err();
|
|
assert!(matches!(err, RoaValidateError::EeIpResourcesInherit));
|
|
}
|
|
|
|
#[test]
|
|
fn validate_rejects_when_prefix_not_covered() {
|
|
let roa = test_roa_single_v4_prefix();
|
|
let ee = dummy_ee(
|
|
Some(IpResourceSet {
|
|
families: vec![IpAddressFamily {
|
|
afi: Afi::Ipv4,
|
|
choice: IpAddressChoice::AddressesOrRanges(vec![IpAddressOrRange::Prefix(
|
|
IpPrefix {
|
|
afi: Afi::Ipv4,
|
|
prefix_len: 24,
|
|
addr: vec![192, 0, 2, 0],
|
|
},
|
|
)]),
|
|
}],
|
|
}),
|
|
None,
|
|
);
|
|
let err = roa.validate_against_ee_cert(&ee).unwrap_err();
|
|
assert!(matches!(err, RoaValidateError::PrefixNotInEeResources { .. }));
|
|
}
|
|
|
|
#[test]
|
|
fn contains_prefix_handles_non_octet_boundary_prefix_len() {
|
|
let roa = RoaEContent {
|
|
version: 0,
|
|
as_id: 64496,
|
|
ip_addr_blocks: vec![RoaIpAddressFamily {
|
|
afi: RoaAfi::Ipv4,
|
|
addresses: vec![RoaIpAddress {
|
|
prefix: rpki::data_model::roa::IpPrefix {
|
|
afi: RoaAfi::Ipv4,
|
|
prefix_len: 16,
|
|
addr: vec![0b1010_0000, 0x12, 0, 0], // 160.18.0.0/16
|
|
},
|
|
max_length: None,
|
|
}],
|
|
}],
|
|
};
|
|
|
|
let ee = dummy_ee(
|
|
Some(IpResourceSet {
|
|
families: vec![IpAddressFamily {
|
|
afi: Afi::Ipv4,
|
|
choice: IpAddressChoice::AddressesOrRanges(vec![IpAddressOrRange::Prefix(
|
|
IpPrefix {
|
|
afi: Afi::Ipv4,
|
|
prefix_len: 9,
|
|
addr: vec![0b1010_0000, 0, 0, 0], // 160.0.0.0/9
|
|
},
|
|
)]),
|
|
}],
|
|
}),
|
|
None,
|
|
);
|
|
|
|
roa.validate_against_ee_cert(&ee)
|
|
.expect("160.18.0.0/16 should be covered by 160.0.0.0/9");
|
|
}
|
|
|