1use crate::algorithm::{self, AlgorithmIdentifier};
4use crate::error::{Error, ErrorCode, Located, Result};
5use crate::extension::{self, Extensions};
6use crate::key::PublicKeyInfo;
7use crate::name::{self, Name};
8use crate::signature::SignatureValue;
9use crate::time::{self, Time};
10use structured_asn1::{BitString, Element, Integer, Parser, Reader, Span, Tag, universal};
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
14pub enum Version {
15 V1,
17 V2,
19 V3,
21}
22
23#[derive(Debug, Clone, Copy, PartialEq, Eq)]
25pub struct Validity {
26 not_before: Time,
27 not_after: Time,
28}
29
30impl Validity {
31 #[must_use]
33 pub fn not_before(self) -> Time {
34 self.not_before
35 }
36
37 #[must_use]
39 pub fn not_after(self) -> Time {
40 self.not_after
41 }
42
43 #[must_use]
49 pub fn is_well_ordered(self) -> bool {
50 self.not_before <= self.not_after
51 }
52
53 #[must_use]
55 pub fn contains(self, moment: Time) -> bool {
56 self.not_before <= moment && moment <= self.not_after
57 }
58
59 #[must_use]
66 pub fn covers(self, from: Time, to: Time) -> bool {
67 from <= to && self.contains(from) && self.contains(to)
71 }
72}
73
74#[derive(Debug)]
76pub struct Certificate<'a> {
77 tbs: TbsCertificate<'a>,
78 signature_algorithm: AlgorithmIdentifier<'a>,
79 signature: SignatureValue<'a>,
80 der: &'a [u8],
81 span: Span,
82}
83
84#[derive(Debug)]
86pub struct TbsCertificate<'a> {
87 source_depth: u32,
88 version: Version,
89 serial: Integer<'a>,
90 signature: AlgorithmIdentifier<'a>,
91 issuer: Name<'a>,
92 validity: Validity,
93 subject: Name<'a>,
94 public_key: PublicKeyInfo<'a>,
95 issuer_unique_id: Option<BitString<'a>>,
96 subject_unique_id: Option<BitString<'a>>,
97 extensions: Extensions<'a>,
98 der: &'a [u8],
99 span: Span,
100}
101
102impl<'a> Certificate<'a> {
103 pub fn read(parser: &'a Parser, document: &'a [u8], base: u64) -> Result<Self> {
111 let mut reader = parser.read(document, base).field(FIELD)?;
112 let element = reader
113 .next_element()
114 .field(FIELD)?
115 .ok_or_else(|| Error::new(ErrorCode::MissingField, FIELD, base))?;
116 let certificate = Self::read_element(&reader, &element)?;
117
118 if !reader.is_empty() {
122 return Err(Error::new(
123 ErrorCode::TrailingData,
124 FIELD,
125 element.span().end(),
126 ));
127 }
128 Ok(certificate)
129 }
130
131 pub fn read_element(parent: &Reader<'a>, element: &Element<'a>) -> Result<Self> {
137 let fail = |code| Error::new(code, FIELD, element.span().start);
138
139 let mut outer = parent
146 .reread(element, structured_asn1::Encoding::Der)
147 .field(FIELD)?;
148 let element = &outer
149 .expect(Tag::constructed(universal::SEQUENCE))
150 .field(FIELD)?;
151
152 let mut inside = outer.enter(element).field(FIELD)?;
153
154 let tbs_element = inside
155 .next_element()
156 .field(FIELD)?
157 .ok_or_else(|| fail(ErrorCode::MissingField))?;
158 let tbs = read_tbs(&inside, &tbs_element)?;
159
160 let algorithm_element = inside
161 .next_element()
162 .field(FIELD)?
163 .ok_or_else(|| fail(ErrorCode::MissingField))?;
164 let signature_algorithm =
165 algorithm::read(&inside, &algorithm_element, SIGNATURE_ALGORITHM)?;
166 let signature = SignatureValue::read(&mut inside, SIGNATURE)?;
167
168 if !inside.is_empty() {
169 return Err(fail(ErrorCode::TrailingData));
170 }
171
172 if !signature_algorithm.matches_in(&tbs.signature, &inside)? {
180 return Err(Error::new(
181 ErrorCode::AlgorithmMismatch,
182 SIGNATURE_ALGORITHM,
183 algorithm_element.span().start,
184 ));
185 }
186
187 Ok(Self {
188 tbs,
189 signature_algorithm,
190 signature,
191 der: element.as_bytes(),
192 span: element.span(),
193 })
194 }
195
196 #[must_use]
198 pub fn tbs(&self) -> &TbsCertificate<'a> {
199 &self.tbs
200 }
201
202 #[must_use]
206 pub fn signature_algorithm(&self) -> AlgorithmIdentifier<'a> {
207 self.signature_algorithm
208 }
209
210 #[must_use]
212 pub fn signature(&self) -> BitString<'a> {
213 self.signature.bit_string()
214 }
215
216 #[must_use]
218 pub fn signature_value(&self) -> SignatureValue<'a> {
219 self.signature
220 }
221
222 #[must_use]
225 pub fn as_bytes(&self) -> &'a [u8] {
226 self.der
227 }
228
229 #[must_use]
231 pub fn span(&self) -> Span {
232 self.span
233 }
234
235 #[must_use]
237 pub fn signed_bytes(&self) -> &'a [u8] {
238 self.tbs.der
239 }
240
241 pub fn execution_in<'operation, W: structured_asn1::memory::Work>(
248 &self,
249 work: &'operation W,
250 ) -> structured_asn1::memory::Execution<'operation>
251 where
252 'a: 'operation,
253 {
254 self.tbs.signature.query_in(work)
255 }
256}
257
258impl<'a> TbsCertificate<'a> {
259 pub(crate) fn reader_scoped<'q, W: structured_asn1::memory::Work>(
260 &self,
261 work: &'q W,
262 ) -> Result<structured_asn1::ScopedReader<'a, 'q>>
263 where
264 'a: 'q,
265 {
266 work.read_scoped_source(
267 self.signature.source_parser(),
268 self.der,
269 self.span.start,
270 structured_asn1::Encoding::Der,
271 self.source_depth,
272 )
273 .field(TBS)
274 }
275
276 #[must_use]
278 pub fn version(&self) -> Version {
279 self.version
280 }
281
282 #[must_use]
291 pub fn serial(&self) -> Integer<'a> {
292 self.serial
293 }
294
295 #[must_use]
297 pub fn signature(&self) -> AlgorithmIdentifier<'a> {
298 self.signature
299 }
300
301 #[must_use]
303 pub fn issuer(&self) -> &Name<'a> {
304 &self.issuer
305 }
306
307 #[must_use]
309 pub fn validity(&self) -> Validity {
310 self.validity
311 }
312
313 #[must_use]
315 pub fn subject(&self) -> &Name<'a> {
316 &self.subject
317 }
318
319 #[must_use]
321 pub fn public_key(&self) -> PublicKeyInfo<'a> {
322 self.public_key
323 }
324
325 #[must_use]
327 pub fn issuer_unique_id(&self) -> Option<BitString<'a>> {
328 self.issuer_unique_id
329 }
330
331 #[must_use]
333 pub fn subject_unique_id(&self) -> Option<BitString<'a>> {
334 self.subject_unique_id
335 }
336
337 #[must_use]
339 pub fn extensions(&self) -> &Extensions<'a> {
340 &self.extensions
341 }
342
343 #[must_use]
345 pub fn as_bytes(&self) -> &'a [u8] {
346 self.der
347 }
348
349 #[must_use]
351 pub fn span(&self) -> Span {
352 self.span
353 }
354}
355
356const FIELD: &str = "certificate";
357const TBS: &str = "certificate.tbsCertificate";
358const VERSION: &str = "certificate.tbsCertificate.version";
359const SERIAL: &str = "certificate.tbsCertificate.serialNumber";
360const INNER_ALGORITHM: &str = "certificate.tbsCertificate.signature";
361const ISSUER: &str = "certificate.tbsCertificate.issuer";
362const VALIDITY: &str = "certificate.tbsCertificate.validity";
363const NOT_BEFORE: &str = "certificate.tbsCertificate.validity.notBefore";
364const NOT_AFTER: &str = "certificate.tbsCertificate.validity.notAfter";
365const SUBJECT: &str = "certificate.tbsCertificate.subject";
366const PUBLIC_KEY: &str = "certificate.tbsCertificate.subjectPublicKeyInfo";
367const ISSUER_UNIQUE_ID: &str = "certificate.tbsCertificate.issuerUniqueID";
368const SUBJECT_UNIQUE_ID: &str = "certificate.tbsCertificate.subjectUniqueID";
369const EXTENSIONS: &str = "certificate.tbsCertificate.extensions";
370const SIGNATURE_ALGORITHM: &str = "certificate.signatureAlgorithm";
371const SIGNATURE: &str = "certificate.signature";
372
373fn require(element: &Element<'_>, tag: Tag, field: &'static str) -> Result<()> {
374 if element.tag() == tag {
375 return Ok(());
376 }
377 Err(Error::new(
378 ErrorCode::Encoding(structured_asn1::ErrorCode::UnexpectedTag),
379 field,
380 element.span().start,
381 ))
382}
383
384fn read_tbs<'a>(parent: &Reader<'a>, element: &Element<'a>) -> Result<TbsCertificate<'a>> {
385 let fail = |code| Error::new(code, TBS, element.span().start);
386 require(element, Tag::constructed(universal::SEQUENCE), TBS)?;
387
388 let mut inside = parent.enter(element).field(TBS)?;
389 let mut next = inside.next_element().field(TBS)?;
390
391 let version = match next {
394 Some(tagged) if tagged.tag() == Tag::context(true, 0) => {
395 let version = read_version(&inside, &tagged)?;
396 next = inside.next_element().field(TBS)?;
397 version
398 }
399 _ => Version::V1,
402 };
403
404 let serial_element = next.ok_or_else(|| fail(ErrorCode::MissingField))?;
405 require(&serial_element, Tag::primitive(universal::INTEGER), SERIAL)?;
406 let serial = inside.integer(&serial_element).field(SERIAL)?;
407
408 let signature_element = inside
409 .next_element()
410 .field(TBS)?
411 .ok_or_else(|| fail(ErrorCode::MissingField))?;
412 let signature = algorithm::read(&inside, &signature_element, INNER_ALGORITHM)?;
413
414 let issuer_element = inside
415 .next_element()
416 .field(TBS)?
417 .ok_or_else(|| fail(ErrorCode::MissingField))?;
418 let issuer = name::read(&inside, &issuer_element, ISSUER)?;
419 if issuer.is_empty() {
425 return Err(Error::new(
426 ErrorCode::EmptySequence,
427 ISSUER,
428 issuer_element.span().start,
429 ));
430 }
431
432 let validity_element = inside
433 .next_element()
434 .field(TBS)?
435 .ok_or_else(|| fail(ErrorCode::MissingField))?;
436 let validity = read_validity(&inside, &validity_element)?;
437
438 let subject_element = inside
439 .next_element()
440 .field(TBS)?
441 .ok_or_else(|| fail(ErrorCode::MissingField))?;
442 let subject = name::read(&inside, &subject_element, SUBJECT)?;
443
444 let key_element = inside
445 .next_element()
446 .field(TBS)?
447 .ok_or_else(|| fail(ErrorCode::MissingField))?;
448 let public_key = PublicKeyInfo::read_element(&inside, &key_element, PUBLIC_KEY)?;
449
450 let Trailing {
451 issuer_unique_id,
452 subject_unique_id,
453 extensions,
454 } = read_trailing(&mut inside)?;
455
456 if !extensions.is_empty() && version != Version::V3 {
460 return Err(Error::new(
461 ErrorCode::UnexpectedField,
462 EXTENSIONS,
463 element.span().start,
464 ));
465 }
466 if (issuer_unique_id.is_some() || subject_unique_id.is_some()) && version == Version::V1 {
467 return Err(Error::new(
468 ErrorCode::UnexpectedField,
469 ISSUER_UNIQUE_ID,
470 element.span().start,
471 ));
472 }
473
474 if subject.is_empty()
479 && !extensions
480 .get(crate::oid::SUBJECT_ALT_NAME, &inside.execution())?
481 .is_some_and(|alternative| alternative.is_critical())
482 {
483 return Err(Error::new(
484 ErrorCode::MissingField,
485 SUBJECT,
486 subject_element.span().start,
487 ));
488 }
489
490 Ok(TbsCertificate {
491 source_depth: parent.depth(),
492 version,
493 serial,
494 signature,
495 issuer,
496 validity,
497 subject,
498 public_key,
499 issuer_unique_id,
500 subject_unique_id,
501 extensions,
502 der: element.as_bytes(),
503 span: element.span(),
504 })
505}
506
507struct Trailing<'a> {
509 issuer_unique_id: Option<BitString<'a>>,
510 subject_unique_id: Option<BitString<'a>>,
511 extensions: Extensions<'a>,
512}
513
514fn read_trailing<'a>(inside: &mut Reader<'a>) -> Result<Trailing<'a>> {
515 let mut issuer_unique_id = None;
516 let mut subject_unique_id = None;
517 let mut extensions = Extensions::empty(inside.memory());
518
519 let mut last_number = 0;
524
525 while let Some(tagged) = inside.next_element().field(TBS)? {
526 let (field, number) = match tagged.tag() {
527 tag if tag == Tag::context(false, 1) && last_number < 1 => (ISSUER_UNIQUE_ID, 1),
528 tag if tag == Tag::context(false, 2) && last_number < 2 => (SUBJECT_UNIQUE_ID, 2),
529 tag if tag == Tag::context(true, 3) && last_number < 3 => (EXTENSIONS, 3),
530 _ => {
531 return Err(Error::new(
532 ErrorCode::UnexpectedField,
533 TBS,
534 tagged.span().start,
535 ));
536 }
537 };
538 last_number = number;
539
540 match number {
541 1 => issuer_unique_id = Some(inside.bit_string(&tagged).field(field)?),
542 2 => subject_unique_id = Some(inside.bit_string(&tagged).field(field)?),
543 _ => {
544 let mut wrapper = inside.enter(&tagged).field(field)?;
547 let sequence = wrapper.next_element().field(field)?.ok_or_else(|| {
548 Error::new(ErrorCode::MissingField, field, tagged.span().start)
549 })?;
550 extensions = extension::read(&wrapper, &sequence, field)?;
551 if !wrapper.is_empty() {
552 return Err(Error::new(
553 ErrorCode::TrailingData,
554 field,
555 tagged.span().start,
556 ));
557 }
558 }
559 }
560 }
561
562 Ok(Trailing {
563 issuer_unique_id,
564 subject_unique_id,
565 extensions,
566 })
567}
568
569fn read_version<'a>(parent: &Reader<'a>, element: &Element<'a>) -> Result<Version> {
570 let fail = |code| Error::new(code, VERSION, element.span().start);
571
572 let mut inside = parent.enter(element).field(VERSION)?;
573 let value = inside.read_integer().field(VERSION)?;
574 if !inside.is_empty() {
575 return Err(fail(ErrorCode::TrailingData));
576 }
577
578 match value.as_u64() {
579 Some(0) if inside.encoding().is_der() => Err(fail(ErrorCode::MalformedValue)),
583 Some(0) => Ok(Version::V1),
584 Some(1) => Ok(Version::V2),
585 Some(2) => Ok(Version::V3),
586 _ => Err(fail(ErrorCode::UnsupportedVersion)),
590 }
591}
592
593fn read_validity<'a>(parent: &Reader<'a>, element: &Element<'a>) -> Result<Validity> {
594 let fail = |code| Error::new(code, VALIDITY, element.span().start);
595 require(element, Tag::constructed(universal::SEQUENCE), VALIDITY)?;
596
597 let mut inside = parent.enter(element).field(VALIDITY)?;
598 let before = inside
599 .next_element()
600 .field(VALIDITY)?
601 .ok_or_else(|| fail(ErrorCode::MissingField))?;
602 let after = inside
603 .next_element()
604 .field(VALIDITY)?
605 .ok_or_else(|| fail(ErrorCode::MissingField))?;
606 if !inside.is_empty() {
607 return Err(fail(ErrorCode::TrailingData));
608 }
609
610 Ok(Validity {
611 not_before: time::read(&before, NOT_BEFORE)?,
612 not_after: time::read(&after, NOT_AFTER)?,
613 })
614}
615
616#[cfg(test)]
617mod tests;