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 version: Version,
88 serial: Integer<'a>,
89 signature: AlgorithmIdentifier<'a>,
90 issuer: Name<'a>,
91 validity: Validity,
92 subject: Name<'a>,
93 public_key: PublicKeyInfo<'a>,
94 issuer_unique_id: Option<BitString<'a>>,
95 subject_unique_id: Option<BitString<'a>>,
96 extensions: Extensions<'a>,
97 der: &'a [u8],
98 span: Span,
99}
100
101impl<'a> Certificate<'a> {
102 pub fn read(parser: &'a Parser, document: &'a [u8], base: u64) -> Result<Self> {
110 let mut reader = parser.read(document, base).field(FIELD)?;
111 let element = reader
112 .next_element()
113 .field(FIELD)?
114 .ok_or_else(|| Error::new(ErrorCode::MissingField, FIELD, base))?;
115 let certificate = Self::read_element(&reader, &element)?;
116
117 if !reader.is_empty() {
121 return Err(Error::new(
122 ErrorCode::TrailingData,
123 FIELD,
124 element.span().end(),
125 ));
126 }
127 Ok(certificate)
128 }
129
130 pub fn read_element(parent: &Reader<'a>, element: &Element<'a>) -> Result<Self> {
136 let fail = |code| Error::new(code, FIELD, element.span().start);
137
138 let mut outer = parent
145 .reread(element, structured_asn1::Encoding::Der)
146 .field(FIELD)?;
147 let element = &outer
148 .expect(Tag::constructed(universal::SEQUENCE))
149 .field(FIELD)?;
150
151 let mut inside = outer.enter(element).field(FIELD)?;
152
153 let tbs_element = inside
154 .next_element()
155 .field(FIELD)?
156 .ok_or_else(|| fail(ErrorCode::MissingField))?;
157 let tbs = read_tbs(&inside, &tbs_element)?;
158
159 let algorithm_element = inside
160 .next_element()
161 .field(FIELD)?
162 .ok_or_else(|| fail(ErrorCode::MissingField))?;
163 let signature_algorithm =
164 algorithm::read(&inside, &algorithm_element, SIGNATURE_ALGORITHM)?;
165 let signature = SignatureValue::read(&mut inside, SIGNATURE)?;
166
167 if !inside.is_empty() {
168 return Err(fail(ErrorCode::TrailingData));
169 }
170
171 if !signature_algorithm.matches_in(&tbs.signature, &inside)? {
179 return Err(Error::new(
180 ErrorCode::AlgorithmMismatch,
181 SIGNATURE_ALGORITHM,
182 algorithm_element.span().start,
183 ));
184 }
185
186 Ok(Self {
187 tbs,
188 signature_algorithm,
189 signature,
190 der: element.as_bytes(),
191 span: element.span(),
192 })
193 }
194
195 #[must_use]
197 pub fn tbs(&self) -> &TbsCertificate<'a> {
198 &self.tbs
199 }
200
201 #[must_use]
205 pub fn signature_algorithm(&self) -> AlgorithmIdentifier<'a> {
206 self.signature_algorithm
207 }
208
209 #[must_use]
211 pub fn signature(&self) -> BitString<'a> {
212 self.signature.bit_string()
213 }
214
215 #[must_use]
217 pub fn signature_value(&self) -> SignatureValue<'a> {
218 self.signature
219 }
220
221 #[must_use]
224 pub fn as_bytes(&self) -> &'a [u8] {
225 self.der
226 }
227
228 #[must_use]
230 pub fn span(&self) -> Span {
231 self.span
232 }
233
234 #[must_use]
236 pub fn signed_bytes(&self) -> &'a [u8] {
237 self.tbs.der
238 }
239
240 pub fn execution_in<'operation, W: structured_asn1::memory::Work>(
247 &self,
248 work: &'operation W,
249 ) -> structured_asn1::memory::Execution<'operation>
250 where
251 'a: 'operation,
252 {
253 self.tbs.signature.query_in(work)
254 }
255}
256
257impl<'a> TbsCertificate<'a> {
258 #[must_use]
260 pub fn version(&self) -> Version {
261 self.version
262 }
263
264 #[must_use]
273 pub fn serial(&self) -> Integer<'a> {
274 self.serial
275 }
276
277 #[must_use]
279 pub fn signature(&self) -> AlgorithmIdentifier<'a> {
280 self.signature
281 }
282
283 #[must_use]
285 pub fn issuer(&self) -> &Name<'a> {
286 &self.issuer
287 }
288
289 #[must_use]
291 pub fn validity(&self) -> Validity {
292 self.validity
293 }
294
295 #[must_use]
297 pub fn subject(&self) -> &Name<'a> {
298 &self.subject
299 }
300
301 #[must_use]
303 pub fn public_key(&self) -> PublicKeyInfo<'a> {
304 self.public_key
305 }
306
307 #[must_use]
309 pub fn issuer_unique_id(&self) -> Option<BitString<'a>> {
310 self.issuer_unique_id
311 }
312
313 #[must_use]
315 pub fn subject_unique_id(&self) -> Option<BitString<'a>> {
316 self.subject_unique_id
317 }
318
319 #[must_use]
321 pub fn extensions(&self) -> &Extensions<'a> {
322 &self.extensions
323 }
324
325 #[must_use]
327 pub fn as_bytes(&self) -> &'a [u8] {
328 self.der
329 }
330
331 #[must_use]
333 pub fn span(&self) -> Span {
334 self.span
335 }
336}
337
338const FIELD: &str = "certificate";
339const TBS: &str = "certificate.tbsCertificate";
340const VERSION: &str = "certificate.tbsCertificate.version";
341const SERIAL: &str = "certificate.tbsCertificate.serialNumber";
342const INNER_ALGORITHM: &str = "certificate.tbsCertificate.signature";
343const ISSUER: &str = "certificate.tbsCertificate.issuer";
344const VALIDITY: &str = "certificate.tbsCertificate.validity";
345const NOT_BEFORE: &str = "certificate.tbsCertificate.validity.notBefore";
346const NOT_AFTER: &str = "certificate.tbsCertificate.validity.notAfter";
347const SUBJECT: &str = "certificate.tbsCertificate.subject";
348const PUBLIC_KEY: &str = "certificate.tbsCertificate.subjectPublicKeyInfo";
349const ISSUER_UNIQUE_ID: &str = "certificate.tbsCertificate.issuerUniqueID";
350const SUBJECT_UNIQUE_ID: &str = "certificate.tbsCertificate.subjectUniqueID";
351const EXTENSIONS: &str = "certificate.tbsCertificate.extensions";
352const SIGNATURE_ALGORITHM: &str = "certificate.signatureAlgorithm";
353const SIGNATURE: &str = "certificate.signature";
354
355fn require(element: &Element<'_>, tag: Tag, field: &'static str) -> Result<()> {
356 if element.tag() == tag {
357 return Ok(());
358 }
359 Err(Error::new(
360 ErrorCode::Encoding(structured_asn1::ErrorCode::UnexpectedTag),
361 field,
362 element.span().start,
363 ))
364}
365
366fn read_tbs<'a>(parent: &Reader<'a>, element: &Element<'a>) -> Result<TbsCertificate<'a>> {
367 let fail = |code| Error::new(code, TBS, element.span().start);
368 require(element, Tag::constructed(universal::SEQUENCE), TBS)?;
369
370 let mut inside = parent.enter(element).field(TBS)?;
371 let mut next = inside.next_element().field(TBS)?;
372
373 let version = match next {
376 Some(tagged) if tagged.tag() == Tag::context(true, 0) => {
377 let version = read_version(&inside, &tagged)?;
378 next = inside.next_element().field(TBS)?;
379 version
380 }
381 _ => Version::V1,
384 };
385
386 let serial_element = next.ok_or_else(|| fail(ErrorCode::MissingField))?;
387 require(&serial_element, Tag::primitive(universal::INTEGER), SERIAL)?;
388 let serial = inside.integer(&serial_element).field(SERIAL)?;
389
390 let signature_element = inside
391 .next_element()
392 .field(TBS)?
393 .ok_or_else(|| fail(ErrorCode::MissingField))?;
394 let signature = algorithm::read(&inside, &signature_element, INNER_ALGORITHM)?;
395
396 let issuer_element = inside
397 .next_element()
398 .field(TBS)?
399 .ok_or_else(|| fail(ErrorCode::MissingField))?;
400 let issuer = name::read(&inside, &issuer_element, ISSUER)?;
401 if issuer.is_empty() {
407 return Err(Error::new(
408 ErrorCode::EmptySequence,
409 ISSUER,
410 issuer_element.span().start,
411 ));
412 }
413
414 let validity_element = inside
415 .next_element()
416 .field(TBS)?
417 .ok_or_else(|| fail(ErrorCode::MissingField))?;
418 let validity = read_validity(&inside, &validity_element)?;
419
420 let subject_element = inside
421 .next_element()
422 .field(TBS)?
423 .ok_or_else(|| fail(ErrorCode::MissingField))?;
424 let subject = name::read(&inside, &subject_element, SUBJECT)?;
425
426 let key_element = inside
427 .next_element()
428 .field(TBS)?
429 .ok_or_else(|| fail(ErrorCode::MissingField))?;
430 let public_key = PublicKeyInfo::read_element(&inside, &key_element, PUBLIC_KEY)?;
431
432 let Trailing {
433 issuer_unique_id,
434 subject_unique_id,
435 extensions,
436 } = read_trailing(&mut inside)?;
437
438 if !extensions.is_empty() && version != Version::V3 {
442 return Err(Error::new(
443 ErrorCode::UnexpectedField,
444 EXTENSIONS,
445 element.span().start,
446 ));
447 }
448 if (issuer_unique_id.is_some() || subject_unique_id.is_some()) && version == Version::V1 {
449 return Err(Error::new(
450 ErrorCode::UnexpectedField,
451 ISSUER_UNIQUE_ID,
452 element.span().start,
453 ));
454 }
455
456 if subject.is_empty()
461 && !extensions
462 .get(crate::oid::SUBJECT_ALT_NAME, &inside.execution())?
463 .is_some_and(|alternative| alternative.is_critical())
464 {
465 return Err(Error::new(
466 ErrorCode::MissingField,
467 SUBJECT,
468 subject_element.span().start,
469 ));
470 }
471
472 Ok(TbsCertificate {
473 version,
474 serial,
475 signature,
476 issuer,
477 validity,
478 subject,
479 public_key,
480 issuer_unique_id,
481 subject_unique_id,
482 extensions,
483 der: element.as_bytes(),
484 span: element.span(),
485 })
486}
487
488struct Trailing<'a> {
490 issuer_unique_id: Option<BitString<'a>>,
491 subject_unique_id: Option<BitString<'a>>,
492 extensions: Extensions<'a>,
493}
494
495fn read_trailing<'a>(inside: &mut Reader<'a>) -> Result<Trailing<'a>> {
496 let mut issuer_unique_id = None;
497 let mut subject_unique_id = None;
498 let mut extensions = Extensions::empty(inside.memory());
499
500 let mut last_number = 0;
505
506 while let Some(tagged) = inside.next_element().field(TBS)? {
507 let (field, number) = match tagged.tag() {
508 tag if tag == Tag::context(false, 1) && last_number < 1 => (ISSUER_UNIQUE_ID, 1),
509 tag if tag == Tag::context(false, 2) && last_number < 2 => (SUBJECT_UNIQUE_ID, 2),
510 tag if tag == Tag::context(true, 3) && last_number < 3 => (EXTENSIONS, 3),
511 _ => {
512 return Err(Error::new(
513 ErrorCode::UnexpectedField,
514 TBS,
515 tagged.span().start,
516 ));
517 }
518 };
519 last_number = number;
520
521 match number {
522 1 => issuer_unique_id = Some(inside.bit_string(&tagged).field(field)?),
523 2 => subject_unique_id = Some(inside.bit_string(&tagged).field(field)?),
524 _ => {
525 let mut wrapper = inside.enter(&tagged).field(field)?;
528 let sequence = wrapper.next_element().field(field)?.ok_or_else(|| {
529 Error::new(ErrorCode::MissingField, field, tagged.span().start)
530 })?;
531 extensions = extension::read(&wrapper, &sequence, field)?;
532 if !wrapper.is_empty() {
533 return Err(Error::new(
534 ErrorCode::TrailingData,
535 field,
536 tagged.span().start,
537 ));
538 }
539 }
540 }
541 }
542
543 Ok(Trailing {
544 issuer_unique_id,
545 subject_unique_id,
546 extensions,
547 })
548}
549
550fn read_version<'a>(parent: &Reader<'a>, element: &Element<'a>) -> Result<Version> {
551 let fail = |code| Error::new(code, VERSION, element.span().start);
552
553 let mut inside = parent.enter(element).field(VERSION)?;
554 let value = inside.read_integer().field(VERSION)?;
555 if !inside.is_empty() {
556 return Err(fail(ErrorCode::TrailingData));
557 }
558
559 match value.as_u64() {
560 Some(0) if inside.encoding().is_der() => Err(fail(ErrorCode::MalformedValue)),
564 Some(0) => Ok(Version::V1),
565 Some(1) => Ok(Version::V2),
566 Some(2) => Ok(Version::V3),
567 _ => Err(fail(ErrorCode::UnsupportedVersion)),
571 }
572}
573
574fn read_validity<'a>(parent: &Reader<'a>, element: &Element<'a>) -> Result<Validity> {
575 let fail = |code| Error::new(code, VALIDITY, element.span().start);
576 require(element, Tag::constructed(universal::SEQUENCE), VALIDITY)?;
577
578 let mut inside = parent.enter(element).field(VALIDITY)?;
579 let before = inside
580 .next_element()
581 .field(VALIDITY)?
582 .ok_or_else(|| fail(ErrorCode::MissingField))?;
583 let after = inside
584 .next_element()
585 .field(VALIDITY)?
586 .ok_or_else(|| fail(ErrorCode::MissingField))?;
587 if !inside.is_empty() {
588 return Err(fail(ErrorCode::TrailingData));
589 }
590
591 Ok(Validity {
592 not_before: time::read(&before, NOT_BEFORE)?,
593 not_after: time::read(&after, NOT_AFTER)?,
594 })
595}
596
597#[cfg(test)]
598mod tests;