use rpki::data_model::crl::RpkixCrl; use rpki::data_model::manifest::ManifestObject; use rpki::data_model::rc::ResourceCertificate; use rpki::validation::cert_path::{CertPathError, validate_ee_cert_path}; fn max_time(mut t: time::OffsetDateTime, other: time::OffsetDateTime) -> time::OffsetDateTime { if other > t { t = other; } t } fn min_time(mut t: time::OffsetDateTime, other: time::OffsetDateTime) -> time::OffsetDateTime { if other < t { t = other; } t } #[test] fn ee_cert_must_be_issued_by_ca_and_not_revoked() { let manifest_der = std::fs::read( "tests/fixtures/repository/rpki.cernet.net/repo/cernet/0/05FC9C5B88506F7C0D3F862C8895BED67E9F8EBA.mft", ) .expect("read manifest fixture"); let crl_der = std::fs::read( "tests/fixtures/repository/rpki.cernet.net/repo/cernet/0/05FC9C5B88506F7C0D3F862C8895BED67E9F8EBA.crl", ) .expect("read CRL fixture"); let issuer_ca_der = std::fs::read( "tests/fixtures/repository/rpki.apnic.net/repository/B527EF581D6611E2BB468F7C72FD1FF2/BfycW4hQb3wNP4YsiJW-1n6fjro.cer", ) .expect("read issuer CA cert fixture"); let manifest = ManifestObject::decode_der(&manifest_der).expect("decode manifest"); let ee_der = &manifest.signed_object.signed_data.certificates[0].raw_der; let ee = ResourceCertificate::decode_der(ee_der).expect("decode EE cert"); let issuer = ResourceCertificate::decode_der(&issuer_ca_der).expect("decode issuer CA cert"); let crl = RpkixCrl::decode_der(&crl_der).expect("decode CRL"); let mut t = ee.tbs.validity_not_before; t = max_time(t, issuer.tbs.validity_not_before); t = max_time(t, crl.this_update.utc); t = max_time(t, manifest.manifest.this_update); t += time::Duration::seconds(1); let mut upper = ee.tbs.validity_not_after; upper = min_time(upper, issuer.tbs.validity_not_after); upper = min_time(upper, crl.next_update.utc); upper = min_time(upper, manifest.manifest.next_update); assert!(t < upper); validate_ee_cert_path(ee_der, &issuer_ca_der, &crl_der, None, None, t) .expect("cert path validates"); } #[test] fn wrong_issuer_ca_is_rejected() { let manifest_der = std::fs::read( "tests/fixtures/repository/rpki.cernet.net/repo/cernet/0/05FC9C5B88506F7C0D3F862C8895BED67E9F8EBA.mft", ) .expect("read manifest fixture"); let crl_der = std::fs::read( "tests/fixtures/repository/rpki.cernet.net/repo/cernet/0/05FC9C5B88506F7C0D3F862C8895BED67E9F8EBA.crl", ) .expect("read CRL fixture"); let wrong_issuer_ca_der = std::fs::read( "tests/fixtures/repository/ca.rg.net/rpki/RGnet-OU/R-lVU1XGsAeqzV1Fv0HjOD6ZFkE.cer", ) .expect("read wrong issuer CA cert fixture"); let manifest = ManifestObject::decode_der(&manifest_der).expect("decode manifest"); let ee_der = &manifest.signed_object.signed_data.certificates[0].raw_der; let ee = ResourceCertificate::decode_der(ee_der).expect("decode EE cert"); let crl = RpkixCrl::decode_der(&crl_der).expect("decode CRL"); let t = max_time(ee.tbs.validity_not_before, crl.this_update.utc) + time::Duration::seconds(1); let err = validate_ee_cert_path(ee_der, &wrong_issuer_ca_der, &crl_der, None, None, t) .expect_err("wrong issuer must be rejected"); assert!( matches!( err, CertPathError::IssuerSubjectMismatch { .. } | CertPathError::EeSignatureInvalid(_) | CertPathError::IssuerNotCa ), "{err}" ); } #[test] fn ee_not_valid_after_not_after_is_rejected() { let manifest_der = std::fs::read( "tests/fixtures/repository/rpki.cernet.net/repo/cernet/0/05FC9C5B88506F7C0D3F862C8895BED67E9F8EBA.mft", ) .expect("read manifest fixture"); let crl_der = std::fs::read( "tests/fixtures/repository/rpki.cernet.net/repo/cernet/0/05FC9C5B88506F7C0D3F862C8895BED67E9F8EBA.crl", ) .expect("read CRL fixture"); let issuer_ca_der = std::fs::read( "tests/fixtures/repository/rpki.apnic.net/repository/B527EF581D6611E2BB468F7C72FD1FF2/BfycW4hQb3wNP4YsiJW-1n6fjro.cer", ) .expect("read issuer CA cert fixture"); let manifest = ManifestObject::decode_der(&manifest_der).expect("decode manifest"); let ee_der = &manifest.signed_object.signed_data.certificates[0].raw_der; let ee = ResourceCertificate::decode_der(ee_der).expect("decode EE cert"); let too_late = ee.tbs.validity_not_after + time::Duration::seconds(1); let err = validate_ee_cert_path(ee_der, &issuer_ca_der, &crl_der, None, None, too_late) .expect_err("expired ee rejected"); assert!( matches!(err, CertPathError::CertificateNotValidAtTime), "{err}" ); }