From c565447d9db9b421dbdd94db73805dfdb5f31b61 Mon Sep 17 00:00:00 2001 From: yuxi-liu-wired <33951560+yuxi-liu-wired@users.noreply.github.com> Date: Fri, 2 Oct 2026 14:34:59 +0000 Subject: [PATCH] x509-cert: CrlBuilder: omit an empty revokedCertificates list RFC 5280 5.1.2.6: "When there are no revoked certificates, the revoked certificates list MUST be absent." `CrlBuilder::with_certificates` with an empty iterator set `revoked_certificates` to `Some(vec![])`, which encodes an empty `SEQUENCE {}` in the CRL. Drop an empty list in `finalize`, before the TBS is encoded and signed. --- x509-cert/src/builder.rs | 11 +++++++++++ x509-cert/tests/builder_crl.rs | 28 ++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/x509-cert/src/builder.rs b/x509-cert/src/builder.rs index bb054eea8..029d87a0a 100644 --- a/x509-cert/src/builder.rs +++ b/x509-cert/src/builder.rs @@ -682,6 +682,17 @@ where { self.tbs.signature = cert_signer.signature_algorithm_identifier()?; + // RFC 5280 5.1.2.6: "When there are no revoked certificates, the revoked certificates + // list MUST be absent." + if self + .tbs + .revoked_certificates + .as_ref() + .is_some_and(|revoked| revoked.is_empty()) + { + self.tbs.revoked_certificates = None; + } + self.tbs.to_der().map_err(Error::from) } diff --git a/x509-cert/tests/builder_crl.rs b/x509-cert/tests/builder_crl.rs index 41f8ecd41..2045b5abb 100644 --- a/x509-cert/tests/builder_crl.rs +++ b/x509-cert/tests/builder_crl.rs @@ -180,3 +180,31 @@ fn crl_verify() { println!("{verification_stderr}"); assert!(verification_stderr.contains("certificate revoked")); } + +/// RFC 5280 5.1.2.6: "When there are no revoked certificates, the revoked certificates list +/// MUST be absent." +#[test] +fn crl_without_revoked_certificates() { + let mut rng = rng(); + let signer = ecdsa_signer(); + let subject = Name::from_str("CN=root,O=World domination Inc,C=US").unwrap(); + let profile = profile::cabf::Root::new(false, subject).expect("create root profile"); + let pub_key = SubjectPublicKeyInfo::try_from(PKCS8_PUBLIC_KEY_DER).expect("get ecdsa pub key"); + let ca_certificate = CertificateBuilder::new( + profile, + SerialNumber::generate(&mut rng), + Validity::from_now(Duration::new(60, 0)).unwrap(), + pub_key, + ) + .expect("Create certificate") + .build::<_, DerSignature>(&signer) + .unwrap(); + + let crl = CrlBuilder::::new(&ca_certificate, CrlNumber::try_from(1u128).unwrap()) + .unwrap() + .with_certificates(core::iter::empty()) + .build::<_, DerSignature>(&signer) + .unwrap(); + + assert_eq!(crl.tbs_cert_list.revoked_certificates, None); +}