138 lines
4.5 KiB
Rust
138 lines
4.5 KiB
Rust
use rpki::data_model::manifest::ManifestObject;
|
|
use rpki::data_model::rc::{AsIdOrRange, AsIdentifierChoice, AsResourceSet, ResourceCertificate};
|
|
use rpki::data_model::roa::{IpPrefix, RoaAfi};
|
|
use rpki::data_model::ta::{TaCertificate, TaCertificateParsed, TaCertificateProfileError};
|
|
use rpki::data_model::tal::{Tal, TalDecodeError, TalProfileError};
|
|
|
|
#[test]
|
|
fn tal_validate_profile_noop_is_callable() {
|
|
let raw = std::fs::read("tests/fixtures/tal/apnic-rfc7730-https.tal").expect("read tal");
|
|
let tal = Tal::decode_bytes(&raw).expect("decode tal");
|
|
tal.validate_profile().expect("validate_profile is no-op");
|
|
}
|
|
|
|
#[test]
|
|
fn tal_invalid_uri_after_valid_uri_is_reported_as_missing_separator() {
|
|
let s = "https://example.invalid/ta.cer\nnot a url\n\nAQ==\n";
|
|
assert!(matches!(
|
|
Tal::decode_bytes(s.as_bytes()),
|
|
Err(TalDecodeError::Validate(
|
|
TalProfileError::MissingSeparatorEmptyLine
|
|
))
|
|
));
|
|
}
|
|
|
|
#[test]
|
|
fn tal_missing_separator_empty_line_is_rejected() {
|
|
let s = "https://example.invalid/ta.cer\nAQ==\n";
|
|
assert!(matches!(
|
|
Tal::decode_bytes(s.as_bytes()),
|
|
Err(TalDecodeError::Validate(
|
|
TalProfileError::MissingSeparatorEmptyLine
|
|
))
|
|
));
|
|
}
|
|
|
|
#[test]
|
|
fn tal_missing_spki_is_rejected() {
|
|
let s = "https://example.invalid/ta.cer\n\n\n";
|
|
assert!(matches!(
|
|
Tal::decode_bytes(s.as_bytes()),
|
|
Err(TalDecodeError::Validate(TalProfileError::MissingSpki))
|
|
));
|
|
}
|
|
|
|
#[test]
|
|
fn tal_missing_separator_due_to_eof_is_rejected() {
|
|
// One URI and then EOF: should fail at the mandatory empty-line separator check.
|
|
let s = "https://example.invalid/ta.cer";
|
|
assert!(matches!(
|
|
Tal::decode_bytes(s.as_bytes()),
|
|
Err(TalDecodeError::Validate(
|
|
TalProfileError::MissingSeparatorEmptyLine
|
|
))
|
|
));
|
|
}
|
|
|
|
#[test]
|
|
fn ta_validate_profile_noop_is_callable() {
|
|
let der = std::fs::read("tests/fixtures/ta/apnic-ta.cer").expect("read ta");
|
|
let ta = TaCertificate::decode_der(&der).expect("decode ta");
|
|
ta.validate_profile().expect("validate_profile is no-op");
|
|
}
|
|
|
|
#[test]
|
|
fn ta_parsed_validate_profile_rejects_ee_resource_certificate() {
|
|
// Extract an embedded EE certificate from a real manifest fixture and feed it into the TA
|
|
// profile validator to hit the `NotCa` branch in `TaCertificateParsed::validate_profile`.
|
|
let mft_der = std::fs::read(
|
|
"tests/fixtures/repository/ca.rg.net/rpki/RGnet-OU/bW-_qXU9uNhGQz21NR2ansB8lr0.mft",
|
|
)
|
|
.expect("read manifest fixture");
|
|
let mft = ManifestObject::decode_der(&mft_der).expect("decode manifest");
|
|
let ee_der = mft.signed_object.signed_data.certificates[0]
|
|
.resource_cert
|
|
.raw_der
|
|
.clone();
|
|
|
|
let rc_parsed = ResourceCertificate::parse_der(&ee_der).expect("parse embedded EE cert");
|
|
let ta_parsed = TaCertificateParsed { rc_parsed };
|
|
let err = ta_parsed.validate_profile().unwrap_err();
|
|
assert!(matches!(err, TaCertificateProfileError::NotCa));
|
|
}
|
|
|
|
#[test]
|
|
fn ta_rc_constraints_exercise_rdi_non_empty_branch() {
|
|
let der = std::fs::read("tests/fixtures/ta/apnic-ta.cer").expect("read ta");
|
|
let ta = TaCertificate::decode_der(&der).expect("decode ta");
|
|
|
|
let mut rc = ta.rc_ca.clone();
|
|
rc.tbs.extensions.as_resources = Some(AsResourceSet {
|
|
asnum: rc
|
|
.tbs
|
|
.extensions
|
|
.as_resources
|
|
.as_ref()
|
|
.and_then(|v| v.asnum.clone()),
|
|
rdi: Some(AsIdentifierChoice::AsIdsOrRanges(vec![AsIdOrRange::Id(
|
|
64496,
|
|
)])),
|
|
});
|
|
|
|
TaCertificate::validate_rc_constraints(&rc).expect("constraints should still pass");
|
|
}
|
|
|
|
#[test]
|
|
fn audit_helpers_format_roa_ip_prefix_smoke() {
|
|
let v4 = IpPrefix {
|
|
afi: RoaAfi::Ipv4,
|
|
prefix_len: 24,
|
|
addr: vec![192, 0, 2, 0],
|
|
};
|
|
assert_eq!(rpki::audit::format_roa_ip_prefix(&v4), "192.0.2.0/24");
|
|
|
|
let v6 = IpPrefix {
|
|
afi: RoaAfi::Ipv6,
|
|
prefix_len: 32,
|
|
addr: vec![0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
};
|
|
assert!(rpki::audit::format_roa_ip_prefix(&v6).ends_with("/32"));
|
|
|
|
let bad = IpPrefix {
|
|
afi: RoaAfi::Ipv4,
|
|
prefix_len: 8,
|
|
addr: vec![1, 2, 3],
|
|
};
|
|
assert!(rpki::audit::format_roa_ip_prefix(&bad).starts_with("ipv4:"));
|
|
}
|
|
|
|
#[test]
|
|
fn audit_helpers_sha256_hex_smoke() {
|
|
let h = rpki::audit::sha256_hex(b"abc");
|
|
assert_eq!(h.len(), 64);
|
|
|
|
let bytes = [0x11u8; 32];
|
|
let h2 = rpki::audit::sha256_hex_from_32(&bytes);
|
|
assert_eq!(h2, "11".repeat(32));
|
|
}
|