132 lines
4.3 KiB
Rust
132 lines
4.3 KiB
Rust
use der_parser::num_bigint::BigUint;
|
|
use rpki::data_model::common::X509NameDer;
|
|
use rpki::data_model::oid::{
|
|
OID_AUTONOMOUS_SYS_IDS, OID_BASIC_CONSTRAINTS, OID_CERTIFICATE_POLICIES, OID_CP_IPADDR_ASNUMBER,
|
|
};
|
|
use rpki::data_model::rc::{
|
|
AsIdOrRange, AsIdentifierChoice, AsResourceSet, BasicConstraintsProfile,
|
|
CertificatePoliciesProfile, RcExtensions, ResourceCertKind, ResourceCertificate,
|
|
ResourceCertificateProfileError, ResourceCertificateRole, RpkixTbsCertificate,
|
|
};
|
|
use time::OffsetDateTime;
|
|
|
|
fn valid_ca_certificate() -> ResourceCertificate {
|
|
let validation_time = OffsetDateTime::from_unix_timestamp(0).expect("valid epoch");
|
|
ResourceCertificate {
|
|
raw_der: Vec::new(),
|
|
kind: ResourceCertKind::Ca,
|
|
tbs: RpkixTbsCertificate {
|
|
version: 2,
|
|
serial_number: BigUint::from(1u32),
|
|
signature_algorithm: "1.2.840.113549.1.1.11".to_string(),
|
|
issuer_name: X509NameDer(b"CN=issuer".to_vec()),
|
|
subject_name: X509NameDer(b"CN=subject".to_vec()),
|
|
validity_not_before: validation_time,
|
|
validity_not_after: validation_time,
|
|
subject_public_key_info: Vec::new(),
|
|
extensions: RcExtensions {
|
|
basic_constraints_ca: true,
|
|
basic_constraints: Some(BasicConstraintsProfile {
|
|
ca: true,
|
|
critical: true,
|
|
path_len_constraint: None,
|
|
}),
|
|
subject_key_identifier: None,
|
|
authority_key_identifier: None,
|
|
crl_distribution_points_uris: None,
|
|
ca_issuers_uris: None,
|
|
subject_info_access: None,
|
|
certificate_policies_oid: Some(OID_CP_IPADDR_ASNUMBER.to_string()),
|
|
certificate_policies: Some(CertificatePoliciesProfile {
|
|
policy_oid: OID_CP_IPADDR_ASNUMBER.to_string(),
|
|
qualifier_oids: Vec::new(),
|
|
}),
|
|
extension_oids: vec![
|
|
OID_BASIC_CONSTRAINTS.to_string(),
|
|
OID_CERTIFICATE_POLICIES.to_string(),
|
|
],
|
|
ip_resources: None,
|
|
as_resources: None,
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn ca_profile_accepts_required_basic_constraints_and_policy() {
|
|
valid_ca_certificate()
|
|
.validate_rfc6487_profile(ResourceCertificateRole::Ca)
|
|
.expect("valid CA profile");
|
|
}
|
|
|
|
#[test]
|
|
fn ca_profile_rejects_noncritical_basic_constraints() {
|
|
let mut certificate = valid_ca_certificate();
|
|
certificate
|
|
.tbs
|
|
.extensions
|
|
.basic_constraints
|
|
.as_mut()
|
|
.expect("constraints")
|
|
.critical = false;
|
|
|
|
assert!(matches!(
|
|
certificate.validate_rfc6487_profile(ResourceCertificateRole::Ca),
|
|
Err(ResourceCertificateProfileError::BasicConstraintsCriticality)
|
|
));
|
|
}
|
|
|
|
#[test]
|
|
fn ca_profile_rejects_unknown_extension() {
|
|
let mut certificate = valid_ca_certificate();
|
|
certificate
|
|
.tbs
|
|
.extensions
|
|
.extension_oids
|
|
.push("1.2.3.4".to_string());
|
|
|
|
assert!(matches!(
|
|
certificate.validate_rfc6487_profile(ResourceCertificateRole::Ca),
|
|
Err(ResourceCertificateProfileError::DisallowedExtension { .. })
|
|
));
|
|
}
|
|
|
|
#[test]
|
|
fn ca_profile_rejects_non_cps_policy_qualifier() {
|
|
let mut certificate = valid_ca_certificate();
|
|
certificate
|
|
.tbs
|
|
.extensions
|
|
.certificate_policies
|
|
.as_mut()
|
|
.expect("certificate policies")
|
|
.qualifier_oids
|
|
.push("1.2.3.4".to_string());
|
|
|
|
assert!(matches!(
|
|
certificate.validate_rfc6487_profile(ResourceCertificateRole::Ca),
|
|
Err(ResourceCertificateProfileError::CertificatePoliciesInvalidQualifier(_))
|
|
));
|
|
}
|
|
|
|
#[test]
|
|
fn ca_profile_rejects_autonomous_system_rdi() {
|
|
let mut certificate = valid_ca_certificate();
|
|
certificate.tbs.extensions.as_resources = Some(AsResourceSet {
|
|
asnum: None,
|
|
rdi: Some(AsIdentifierChoice::AsIdsOrRanges(vec![AsIdOrRange::Id(
|
|
64512,
|
|
)])),
|
|
});
|
|
certificate
|
|
.tbs
|
|
.extensions
|
|
.extension_oids
|
|
.push(OID_AUTONOMOUS_SYS_IDS.to_string());
|
|
|
|
assert!(matches!(
|
|
certificate.validate_rfc6487_profile(ResourceCertificateRole::Ca),
|
|
Err(ResourceCertificateProfileError::AsResourcesRdiPresent)
|
|
));
|
|
}
|