1use crate::algorithm::{self, AlgorithmIdentifier};
8use crate::error::{Error, ErrorCode, Located, Result};
9use crate::extension::{self, Extensions};
10use crate::name::{self, Name};
11use crate::path::{Verified, Verify, WorkingKey};
12use crate::time::{self, Time};
13use structured_asn1::memory::{OwnedVec, Work};
14use structured_asn1::{BitString, Element, Integer, Parser, Reader, Span, Tag, universal};
15
16mod scope;
17use crate::revocation::{RevocationScheme, RevocationTarget, TargetKind};
18pub use scope::{CertificateKind, IssuingDistributionPoint, Reasons, ScopeFailure, ScopeOutcome};
19mod entry;
20pub use entry::EntryLookup;
21pub use entry::Reason;
22pub(crate) use entry::reason_element;
23mod delta;
24pub use delta::{
25 BoundDelta, CombinedEntry, DeltaBinding, DeltaFailure, EntryOrigin, MissingDeltaField,
26};
27mod freshness;
28pub use freshness::Freshness;
29pub(crate) use freshness::update_window;
30
31mod evidence;
32pub use evidence::{
33 AbsenceEvidence, CompleteEvidence, CompleteFacts, Coverage, CoverageAdmission, DeltaEvidence,
34 DeltaFacts, Evaluation, EvidenceSource, SourceOrigin,
35};
36
37#[derive(Debug, Clone, Copy, PartialEq, Eq)]
39pub enum Version {
40 V1,
42 V2,
44}
45
46#[derive(Debug, Clone, Copy, PartialEq, Eq)]
48pub enum AuthenticationFailure {
49 KeyBinding,
51 IssuerName,
53 KeyUsage,
55 Signature,
57}
58
59#[derive(Debug, Clone, Copy)]
62pub struct Authenticated<'r, 'a> {
63 crl: &'r CertificateList<'a>,
64 issuer: &'r crate::Certificate<'a>,
65 key: WorkingKey<'a>,
66}
67
68impl<'r, 'a> Authenticated<'r, 'a> {
69 #[must_use]
71 pub fn crl(self) -> &'r CertificateList<'a> {
72 self.crl
73 }
74 #[must_use]
76 pub fn issuer(self) -> &'r crate::Certificate<'a> {
77 self.issuer
78 }
79 #[must_use]
81 pub fn key(self) -> WorkingKey<'a> {
82 self.key
83 }
84}
85
86#[derive(Debug)]
89pub enum Authentication<'r, 'a> {
90 Authenticated(Authenticated<'r, 'a>),
92 Rejected(AuthenticationFailure),
94 Unsupported,
96}
97
98#[derive(Debug)]
101pub struct RevokedCertificate<'a> {
102 serial: Integer<'a>,
103 revocation_date: Time,
104 revocation_date_offset: u64,
105 extensions: Extensions<'a>,
106 span: Span,
107}
108
109impl<'a> RevokedCertificate<'a> {
110 #[must_use]
112 pub fn serial(&self) -> Integer<'a> {
113 self.serial
114 }
115
116 #[must_use]
118 pub fn revocation_date(&self) -> Time {
119 self.revocation_date
120 }
121
122 pub fn time_relation<W: Work>(
126 &self,
127 now: crate::temporal::Reading,
128 utc: &crate::temporal::LeapTable<'_>,
129 execution: &W,
130 ) -> Result<crate::time::Relation> {
131 crate::time::relation_in(
132 self.revocation_date.instant(),
133 now,
134 utc,
135 execution,
136 (
137 "certificateList.revokedCertificates.revocationDate",
138 self.revocation_date_offset,
139 ),
140 )
141 }
142
143 #[must_use]
145 pub fn extensions(&self) -> &Extensions<'a> {
146 &self.extensions
147 }
148
149 #[must_use]
151 pub fn span(&self) -> Span {
152 self.span
153 }
154}
155
156#[derive(Debug)]
159pub struct TbsCertList<'a> {
160 source_depth: u32,
161 version: Version,
162 signature: AlgorithmIdentifier<'a>,
163 issuer: Name<'a>,
164 this_update: Time,
165 next_update: Option<Time>,
166 revoked: OwnedVec<RevokedCertificate<'a>>,
167 extensions: Extensions<'a>,
168 bytes: &'a [u8],
169 span: Span,
170}
171
172impl<'a> TbsCertList<'a> {
173 pub(crate) fn reader_scoped<'q, W: Work>(
174 &self,
175 work: &'q W,
176 ) -> Result<structured_asn1::ScopedReader<'a, 'q>>
177 where
178 'a: 'q,
179 {
180 work.read_scoped_source(
181 self.signature.source_parser(),
182 self.bytes,
183 self.span.start,
184 structured_asn1::Encoding::Der,
185 self.source_depth,
186 )
187 .field(TBS)
188 }
189
190 #[must_use]
192 pub fn version(&self) -> Version {
193 self.version
194 }
195 #[must_use]
197 pub fn signature(&self) -> AlgorithmIdentifier<'a> {
198 self.signature
199 }
200 #[must_use]
202 pub fn issuer(&self) -> &Name<'a> {
203 &self.issuer
204 }
205 #[must_use]
207 pub fn this_update(&self) -> Time {
208 self.this_update
209 }
210 #[must_use]
213 pub fn next_update(&self) -> Option<Time> {
214 self.next_update
215 }
216 #[must_use]
218 pub fn revoked_certificates(&self) -> &[RevokedCertificate<'a>] {
219 &self.revoked
220 }
221 #[must_use]
223 pub fn extensions(&self) -> &Extensions<'a> {
224 &self.extensions
225 }
226 #[must_use]
228 pub fn as_bytes(&self) -> &'a [u8] {
229 self.bytes
230 }
231 #[must_use]
233 pub fn span(&self) -> Span {
234 self.span
235 }
236}
237
238#[derive(Debug)]
240pub struct CertificateList<'a> {
241 tbs: TbsCertList<'a>,
242 signature_algorithm: AlgorithmIdentifier<'a>,
243 signature: crate::signature::SignatureValue<'a>,
244 bytes: &'a [u8],
245 span: Span,
246}
247
248impl<'a> CertificateList<'a> {
249 #[must_use]
252 pub fn execution_in<'operation, W: Work>(
253 &self,
254 work: &'operation W,
255 ) -> structured_asn1::memory::Execution<'operation>
256 where
257 'a: 'operation,
258 {
259 self.signature_algorithm.query_in(work)
260 }
261
262 pub fn authenticate<'r, V: Verify<E>, E: Work>(
271 &'r self,
272 issuer: &'r crate::Certificate<'a>,
273 key: WorkingKey<'a>,
274 verifier: &V,
275 execution: &E,
276 ) -> crate::error::CallbackResult<Authentication<'r, 'a>, V::Error> {
277 use crate::error::CallbackError;
278 let encoded_key = key.key().as_bytes();
279 let issuer_key = issuer.tbs().public_key().as_bytes();
280 let work = (encoded_key.len().max(issuer_key.len()) as u64)
281 .checked_mul(2)
282 .and_then(|n| n.checked_add(1))
283 .ok_or_else(|| {
284 Error::resource(
285 structured_asn1::memory::MemoryError::WorkExceeded,
286 FIELD,
287 self.span.start,
288 )
289 })?;
290 execution
291 .charge_work(work)
292 .map_err(|reason| Error::resource(reason, FIELD, self.span.start))?;
293 if encoded_key != issuer_key {
294 return Ok(Authentication::Rejected(AuthenticationFailure::KeyBinding));
295 }
296 if !self.tbs.issuer.matches(issuer.tbs().subject(), execution)? {
297 return Ok(Authentication::Rejected(AuthenticationFailure::IssuerName));
298 }
299 let usage = issuer.tbs().extensions().key_usage(execution)?;
300 if usage.is_some_and(|usage| !usage.crl_sign())
305 || (usage.is_none() && issuer.tbs().version() == crate::Version::V3)
306 {
307 return Ok(Authentication::Rejected(AuthenticationFailure::KeyUsage));
308 }
309 match verifier
310 .verify(
311 &self.tbs.signature,
312 key,
313 self.signed_bytes(),
314 self.signature,
315 execution,
316 )
317 .map_err(CallbackError::Callback)?
318 {
319 Verified::Yes => Ok(Authentication::Authenticated(Authenticated {
320 crl: self,
321 issuer,
322 key,
323 })),
324 Verified::No => Ok(Authentication::Rejected(AuthenticationFailure::Signature)),
325 Verified::Unsupported => Ok(Authentication::Unsupported),
326 }
327 }
328
329 pub fn read(parser: &'a Parser, bytes: &'a [u8], base: u64) -> Result<Self> {
331 let mut reader = parser.read(bytes, base).field(FIELD)?;
332 let element = required(&mut reader, FIELD, base)?;
333 let crl = Self::read_element(&reader, &element)?;
334 if !reader.is_empty() {
335 return Err(Error::new(
336 ErrorCode::TrailingData,
337 FIELD,
338 element.span().end(),
339 ));
340 }
341 Ok(crl)
342 }
343
344 pub fn read_element(parent: &Reader<'a>, element: &Element<'a>) -> Result<Self> {
347 let mut outer = parent
350 .reread(element, structured_asn1::Encoding::Der)
351 .field(FIELD)?;
352 let root = outer
353 .expect(Tag::constructed(universal::SEQUENCE))
354 .field(FIELD)?;
355 let mut inside = outer.enter(&root).field(FIELD)?;
356 let tbs_element = required(&mut inside, TBS, root.span().start)?;
357 let tbs = read_tbs(&inside, &tbs_element)?;
358 let algorithm_element = required(&mut inside, ALGORITHM, root.span().start)?;
359 let signature_algorithm = algorithm::read(&inside, &algorithm_element, ALGORITHM)?;
360 let signature = crate::signature::SignatureValue::read(&mut inside, SIGNATURE)?;
361 end(&inside, FIELD, root.span().start)?;
362 if !signature_algorithm.matches_in(&tbs.signature, &inside)? {
365 return Err(Error::new(
366 ErrorCode::AlgorithmMismatch,
367 ALGORITHM,
368 algorithm_element.span().start,
369 ));
370 }
371 Ok(Self {
372 tbs,
373 signature_algorithm,
374 signature,
375 bytes: root.as_bytes(),
376 span: root.span(),
377 })
378 }
379
380 #[must_use]
382 pub fn tbs(&self) -> &TbsCertList<'a> {
383 &self.tbs
384 }
385 #[must_use]
387 pub fn signature_algorithm(&self) -> AlgorithmIdentifier<'a> {
388 self.signature_algorithm
389 }
390 #[must_use]
392 pub fn signature(&self) -> BitString<'a> {
393 self.signature.bit_string()
394 }
395 #[must_use]
397 pub fn signature_value(&self) -> crate::signature::SignatureValue<'a> {
398 self.signature
399 }
400 #[must_use]
402 pub fn signed_bytes(&self) -> &'a [u8] {
403 self.tbs.bytes
404 }
405 #[must_use]
407 pub fn as_bytes(&self) -> &'a [u8] {
408 self.bytes
409 }
410 #[must_use]
412 pub fn span(&self) -> Span {
413 self.span
414 }
415}
416
417const FIELD: &str = "certificateList";
418const TBS: &str = "certificateList.tbsCertList";
419const ALGORITHM: &str = "certificateList.signatureAlgorithm";
420const SIGNATURE: &str = "certificateList.signature";
421const ISSUER: &str = "certificateList.tbsCertList.issuer";
422const THIS_UPDATE: &str = "certificateList.tbsCertList.thisUpdate";
423const NEXT_UPDATE: &str = "certificateList.tbsCertList.nextUpdate";
424const ENTRIES: &str = "certificateList.tbsCertList.revokedCertificates";
425const EXTENSIONS: &str = "certificateList.tbsCertList.crlExtensions";
426
427fn required<'a>(reader: &mut Reader<'a>, field: &'static str, at: u64) -> Result<Element<'a>> {
428 reader
429 .next_element()
430 .field(field)?
431 .ok_or_else(|| Error::new(ErrorCode::MissingField, field, at))
432}
433
434fn end(reader: &structured_asn1::ScopedReader<'_, '_>, field: &'static str, at: u64) -> Result<()> {
435 if reader.is_empty() {
436 return Ok(());
437 }
438 Err(Error::new(ErrorCode::TrailingData, field, at))
439}
440
441fn is_time(element: &Element<'_>) -> bool {
442 element.tag() == Tag::primitive(universal::UTC_TIME)
443 || element.tag() == Tag::primitive(universal::GENERALIZED_TIME)
444}
445
446fn read_tbs<'a>(parent: &Reader<'a>, element: &Element<'a>) -> Result<TbsCertList<'a>> {
447 if element.tag() != Tag::constructed(universal::SEQUENCE) {
448 return Err(Error::new(
449 ErrorCode::Encoding(structured_asn1::ErrorCode::UnexpectedTag),
450 TBS,
451 element.span().start,
452 ));
453 }
454 let mut inside = parent.enter(element).field(TBS)?;
455 let mut next = required(&mut inside, TBS, element.span().start)?;
456 let version = if next.tag() == Tag::primitive(universal::INTEGER) {
457 inside.charge(9).field(TBS)?;
460 if inside.integer(&next).field(TBS)?.as_u64() != Some(1) {
461 return Err(Error::new(
462 ErrorCode::UnsupportedVersion,
463 TBS,
464 next.span().start,
465 ));
466 }
467 next = required(&mut inside, TBS, element.span().start)?;
468 Version::V2
469 } else {
470 Version::V1
471 };
472 let signature = algorithm::read(&inside, &next, TBS)?;
473 let issuer_element = required(&mut inside, ISSUER, element.span().start)?;
474 let issuer = name::read(&inside, &issuer_element, ISSUER)?;
475 if issuer.is_empty() {
477 return Err(Error::new(
478 ErrorCode::EmptySequence,
479 ISSUER,
480 issuer_element.span().start,
481 ));
482 }
483 let this = required(&mut inside, THIS_UPDATE, element.span().start)?;
484 let this_update = time::read_in(&inside, &this, THIS_UPDATE)?;
485 let mut next = inside.next_element().field(TBS)?;
486 let next_update = match next {
487 Some(value) if is_time(&value) => {
488 let time = time::read_in(&inside, &value, NEXT_UPDATE)?;
489 next = inside.next_element().field(TBS)?;
490 Some(time)
491 }
492 _ => None,
493 };
494 let work = parent.execution();
495 let mut revoked = work.vector();
496 if let Some(sequence) =
497 next.filter(|value| value.tag() == Tag::constructed(universal::SEQUENCE))
498 {
499 let mut entries = inside.enter(&sequence).field(ENTRIES)?;
500 while let Some(entry) = entries.next_element().field(ENTRIES)? {
501 let value = read_entry(&entries, &entry, version)?;
502 revoked
503 .try_push(value)
504 .map_err(|reason| Error::resource(reason, ENTRIES, entry.span().start))?;
505 }
506 if revoked.is_empty() {
508 return Err(Error::new(
509 ErrorCode::EmptySequence,
510 ENTRIES,
511 sequence.span().start,
512 ));
513 }
514 next = inside.next_element().field(TBS)?;
515 }
516 let mut extensions = Extensions::empty(inside.memory());
517 if let Some(tagged) = next {
518 if tagged.tag() != Tag::context(true, 0) || version != Version::V2 {
519 return Err(Error::new(
520 ErrorCode::UnexpectedField,
521 EXTENSIONS,
522 tagged.span().start,
523 ));
524 }
525 let mut wrapper = inside.enter(&tagged).field(EXTENSIONS)?;
526 let sequence = required(&mut wrapper, EXTENSIONS, tagged.span().start)?;
527 extensions = extension::read(&wrapper, &sequence, EXTENSIONS)?;
528 end(&wrapper, EXTENSIONS, tagged.span().start)?;
529 }
530 end(&inside, TBS, element.span().start)?;
531 Ok(TbsCertList {
532 source_depth: parent.depth(),
533 version,
534 signature,
535 issuer,
536 this_update,
537 next_update,
538 revoked: revoked.into_owned(),
539 extensions,
540 bytes: element.as_bytes(),
541 span: element.span(),
542 })
543}
544
545fn read_entry<'a>(
546 parent: &Reader<'a>,
547 element: &Element<'a>,
548 version: Version,
549) -> Result<RevokedCertificate<'a>> {
550 if element.tag() != Tag::constructed(universal::SEQUENCE) {
551 return Err(Error::new(
552 ErrorCode::Encoding(structured_asn1::ErrorCode::UnexpectedTag),
553 ENTRIES,
554 element.span().start,
555 ));
556 }
557 let mut inside = parent.enter(element).field(ENTRIES)?;
558 let serial = inside.read_integer().field(ENTRIES)?;
559 let date = required(&mut inside, ENTRIES, element.span().start)?;
560 let revocation_date = time::read_in(&inside, &date, ENTRIES)?;
561 let extensions = match inside.next_element().field(ENTRIES)? {
562 Some(value) => {
563 if version != Version::V2 {
565 return Err(Error::new(
566 ErrorCode::UnexpectedField,
567 ENTRIES,
568 value.span().start,
569 ));
570 }
571 extension::read(&inside, &value, ENTRIES)?
572 }
573 None => Extensions::empty(inside.memory()),
574 };
575 end(&inside, ENTRIES, element.span().start)?;
576 Ok(RevokedCertificate {
577 serial,
578 revocation_date,
579 revocation_date_offset: date.span().start,
580 extensions,
581 span: element.span(),
582 })
583}