x509_parser/visitor/
crl_visitor.rs1use asn1_rs::BitString;
2use der_parser::num_bigint::BigUint;
3use oid_registry::*;
4
5use crate::extensions::*;
6use crate::revocation_list::*;
7use crate::time::ASN1Time;
8use crate::x509::*;
9
10pub trait CertificateRevocationListVisitor {
45 fn walk(&mut self, crl: &CertificateRevocationList)
47 where
48 Self: Sized,
49 {
50 crl.walk(self);
51 }
52
53 fn visit_tbs_cert_list(&mut self, _tbs: &TbsCertList) {}
55
56 fn visit_signature_algorithm(&mut self, _algorithm: &AlgorithmIdentifier) {}
61
62 fn visit_signature_value(&mut self, _signature: &BitString) {}
64
65 fn visit_version(&mut self, _version: Option<&X509Version>) {}
67
68 fn visit_tbs_signature_algorithm(&mut self, _algorithm: &AlgorithmIdentifier) {}
73
74 fn visit_issuer(&mut self, _name: &X509Name) {}
76
77 fn visit_this_update(&mut self, _time: &ASN1Time) {}
79
80 fn visit_next_update(&mut self, _time: Option<&ASN1Time>) {}
82
83 fn visit_revoked_certificates(&mut self, _certificate: &[RevokedCertificate]) {}
85
86 fn visit_revoked_certificate(&mut self, _certificate: &RevokedCertificate) {}
90
91 fn pre_visit_extensions(&mut self, _extensions: &[X509Extension]) {}
93
94 fn visit_extension(&mut self, _extension: &X509Extension) {}
98
99 fn post_visit_extensions(&mut self, _extensions: &[X509Extension]) {}
101
102 fn visit_extension_aki(&mut self, _aki: &AuthorityKeyIdentifier) {}
104
105 fn visit_extension_issuer_alternative_name(&mut self, _ian: &IssuerAlternativeName) {}
107
108 fn visit_extension_crl_number(&mut self, _number: &BigUint) {}
110
111 fn visit_extension_issuing_distribution_point(&mut self, _dp: &IssuingDistributionPoint) {}
113
114 fn visit_extension_authority_information_access(&mut self, _info: &AuthorityInfoAccess) {}
116
117 fn visit_extension_reason_code(&mut self, _code: &ReasonCode) {}
119
120 fn visit_extension_invalidity_date(&mut self, _time: &ASN1Time) {}
122
123 fn visit_extension_sct(&mut self, _sct: &[SignedCertificateTimestamp]) {}
125}
126
127impl CertificateRevocationList<'_> {
128 pub fn walk<V: CertificateRevocationListVisitor>(&self, visitor: &mut V) {
130 visitor.visit_tbs_cert_list(&self.tbs_cert_list);
131 self.tbs_cert_list.walk(visitor);
132 visitor.visit_signature_algorithm(&self.signature_algorithm);
133 visitor.visit_signature_value(&self.signature_value);
134 }
135}
136
137impl TbsCertList<'_> {
138 pub fn walk<V: CertificateRevocationListVisitor>(&self, visitor: &mut V) {
140 visitor.visit_version(self.version.as_ref());
141 visitor.visit_tbs_signature_algorithm(&self.signature);
142 visitor.visit_issuer(&self.issuer);
143 visitor.visit_this_update(&self.this_update);
144 visitor.visit_next_update(self.next_update.as_ref());
145 visitor.visit_revoked_certificates(&self.revoked_certificates);
146 for certificate in &self.revoked_certificates {
147 visitor.visit_revoked_certificate(certificate);
148 }
149 visitor.pre_visit_extensions(self.extensions());
150 for extension in self.extensions() {
151 visitor.visit_extension(extension);
152
153 if extension.oid == OID_X509_EXT_AUTHORITY_KEY_IDENTIFIER {
154 if let ParsedExtension::AuthorityKeyIdentifier(aki) = &extension.parsed_extension {
155 visitor.visit_extension_aki(aki);
156 }
157 } else if extension.oid == OID_X509_EXT_ISSUER_ALT_NAME {
158 if let ParsedExtension::IssuerAlternativeName(ian) = &extension.parsed_extension {
159 visitor.visit_extension_issuer_alternative_name(ian);
160 }
161 } else if extension.oid == OID_X509_EXT_CRL_NUMBER {
162 if let ParsedExtension::CRLNumber(number) = &extension.parsed_extension {
163 visitor.visit_extension_crl_number(number);
164 }
165 } else if extension.oid == OID_X509_EXT_ISSUER_DISTRIBUTION_POINT {
166 if let ParsedExtension::IssuingDistributionPoint(dp) = &extension.parsed_extension {
167 visitor.visit_extension_issuing_distribution_point(dp);
168 }
169 } else if extension.oid == OID_PKIX_AUTHORITY_INFO_ACCESS {
170 if let ParsedExtension::AuthorityInfoAccess(info) = &extension.parsed_extension {
171 visitor.visit_extension_authority_information_access(info);
172 }
173 } else if extension.oid == OID_X509_EXT_REASON_CODE {
174 if let ParsedExtension::ReasonCode(code) = &extension.parsed_extension {
175 visitor.visit_extension_reason_code(code);
176 }
177 } else if extension.oid == OID_X509_EXT_INVALIDITY_DATE {
178 if let ParsedExtension::InvalidityDate(time) = &extension.parsed_extension {
179 visitor.visit_extension_invalidity_date(time);
180 }
181 } else if extension.oid == OID_CT_LIST_SCT {
182 if let ParsedExtension::SCT(sct) = &extension.parsed_extension {
183 visitor.visit_extension_sct(sct);
184 }
185 }
186 }
187 visitor.post_visit_extensions(self.extensions());
188 }
189}
190
191#[cfg(test)]
192mod tests {
193 use super::*;
194 use crate::FromDer;
195
196 static CRL: &[u8] = include_bytes!("../../assets/example.crl");
197
198 #[test]
199 fn visitor_crl() {
200 #[derive(Debug, Default)]
201 struct RevokedCertsVisitor {
202 certificates: Vec<BigUint>,
203 }
204
205 impl CertificateRevocationListVisitor for RevokedCertsVisitor {
206 fn visit_revoked_certificate(&mut self, certificate: &RevokedCertificate) {
207 self.certificates.push(certificate.user_certificate.clone());
208 }
209 }
210
211 let mut visitor = RevokedCertsVisitor::default();
212 let (_, crl) = CertificateRevocationList::from_der(CRL).unwrap();
213
214 crl.walk(&mut visitor);
215 assert_eq!(visitor.certificates.len(), 5);
216 }
217}