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) )); }