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::time::{self, Time};
9use structured_asn1::{BitString, Element, Integer, Parser, Reader, Span, Tag, universal};
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
13pub enum Version {
14 V1,
16 V2,
18 V3,
20}
21
22#[derive(Debug, Clone, Copy, PartialEq, Eq)]
24pub struct Validity {
25 not_before: Time,
26 not_after: Time,
27}
28
29impl Validity {
30 #[must_use]
32 pub fn not_before(self) -> Time {
33 self.not_before
34 }
35
36 #[must_use]
38 pub fn not_after(self) -> Time {
39 self.not_after
40 }
41
42 #[must_use]
48 pub fn is_well_ordered(self) -> bool {
49 self.not_before <= self.not_after
50 }
51
52 #[must_use]
54 pub fn contains(self, moment: Time) -> bool {
55 self.not_before <= moment && moment <= self.not_after
56 }
57
58 #[must_use]
65 pub fn covers(self, from: Time, to: Time) -> bool {
66 from <= to && self.contains(from) && self.contains(to)
70 }
71}
72
73#[derive(Debug)]
75pub struct Certificate<'a> {
76 tbs: TbsCertificate<'a>,
77 signature_algorithm: AlgorithmIdentifier<'a>,
78 signature: BitString<'a>,
79 der: &'a [u8],
80 span: Span,
81}
82
83#[derive(Debug)]
85pub struct TbsCertificate<'a> {
86 version: Version,
87 serial: Integer<'a>,
88 signature: AlgorithmIdentifier<'a>,
89 issuer: Name<'a>,
90 validity: Validity,
91 subject: Name<'a>,
92 public_key: PublicKeyInfo<'a>,
93 issuer_unique_id: Option<BitString<'a>>,
94 subject_unique_id: Option<BitString<'a>>,
95 extensions: Extensions<'a>,
96 der: &'a [u8],
97 span: Span,
98}
99
100impl<'a> Certificate<'a> {
101 pub fn read(parser: &'a Parser, document: &'a [u8], base: u64) -> Result<Self> {
109 let mut reader = parser.read(document, base).field(FIELD)?;
110 let element = reader
111 .next_element()
112 .field(FIELD)?
113 .ok_or_else(|| Error::new(ErrorCode::MissingField, FIELD, base))?;
114 let certificate = Self::read_element(&reader, &element)?;
115
116 if !reader.is_empty() {
120 return Err(Error::new(
121 ErrorCode::TrailingData,
122 FIELD,
123 element.span().end(),
124 ));
125 }
126 Ok(certificate)
127 }
128
129 pub fn read_element(parent: &Reader<'a>, element: &Element<'a>) -> Result<Self> {
135 let fail = |code| Error::new(code, FIELD, element.span().start);
136
137 let mut outer = parent
144 .reread(element, structured_asn1::Encoding::Der)
145 .field(FIELD)?;
146 let element = &outer
147 .expect(Tag::constructed(universal::SEQUENCE))
148 .field(FIELD)?;
149
150 let mut inside = outer.enter(element).field(FIELD)?;
151
152 let tbs_element = inside
153 .next_element()
154 .field(FIELD)?
155 .ok_or_else(|| fail(ErrorCode::MissingField))?;
156 let tbs = read_tbs(&inside, &tbs_element)?;
157
158 let algorithm_element = inside
159 .next_element()
160 .field(FIELD)?
161 .ok_or_else(|| fail(ErrorCode::MissingField))?;
162 let signature_algorithm =
163 algorithm::read(&inside, &algorithm_element, SIGNATURE_ALGORITHM)?;
164 let signature = inside.read_bit_string().field(SIGNATURE)?;
165
166 if !inside.is_empty() {
167 return Err(fail(ErrorCode::TrailingData));
168 }
169
170 if !signature_algorithm.matches_in(&tbs.signature, &inside)? {
178 return Err(Error::new(
179 ErrorCode::AlgorithmMismatch,
180 SIGNATURE_ALGORITHM,
181 algorithm_element.span().start,
182 ));
183 }
184
185 Ok(Self {
186 tbs,
187 signature_algorithm,
188 signature,
189 der: element.as_bytes(),
190 span: element.span(),
191 })
192 }
193
194 #[must_use]
196 pub fn tbs(&self) -> &TbsCertificate<'a> {
197 &self.tbs
198 }
199
200 #[must_use]
204 pub fn signature_algorithm(&self) -> AlgorithmIdentifier<'a> {
205 self.signature_algorithm
206 }
207
208 #[must_use]
210 pub fn signature(&self) -> BitString<'a> {
211 self.signature
212 }
213
214 #[must_use]
217 pub fn as_bytes(&self) -> &'a [u8] {
218 self.der
219 }
220
221 #[must_use]
223 pub fn span(&self) -> Span {
224 self.span
225 }
226
227 #[must_use]
229 pub fn signed_bytes(&self) -> &'a [u8] {
230 self.tbs.der
231 }
232}
233
234impl<'a> TbsCertificate<'a> {
235 #[must_use]
237 pub fn version(&self) -> Version {
238 self.version
239 }
240
241 #[must_use]
250 pub fn serial(&self) -> Integer<'a> {
251 self.serial
252 }
253
254 #[must_use]
256 pub fn signature(&self) -> AlgorithmIdentifier<'a> {
257 self.signature
258 }
259
260 #[must_use]
262 pub fn issuer(&self) -> &Name<'a> {
263 &self.issuer
264 }
265
266 #[must_use]
268 pub fn validity(&self) -> Validity {
269 self.validity
270 }
271
272 #[must_use]
274 pub fn subject(&self) -> &Name<'a> {
275 &self.subject
276 }
277
278 #[must_use]
280 pub fn public_key(&self) -> PublicKeyInfo<'a> {
281 self.public_key
282 }
283
284 #[must_use]
286 pub fn issuer_unique_id(&self) -> Option<BitString<'a>> {
287 self.issuer_unique_id
288 }
289
290 #[must_use]
292 pub fn subject_unique_id(&self) -> Option<BitString<'a>> {
293 self.subject_unique_id
294 }
295
296 #[must_use]
298 pub fn extensions(&self) -> &Extensions<'a> {
299 &self.extensions
300 }
301
302 #[must_use]
304 pub fn as_bytes(&self) -> &'a [u8] {
305 self.der
306 }
307
308 #[must_use]
310 pub fn span(&self) -> Span {
311 self.span
312 }
313}
314
315const FIELD: &str = "certificate";
316const TBS: &str = "certificate.tbsCertificate";
317const VERSION: &str = "certificate.tbsCertificate.version";
318const SERIAL: &str = "certificate.tbsCertificate.serialNumber";
319const INNER_ALGORITHM: &str = "certificate.tbsCertificate.signature";
320const ISSUER: &str = "certificate.tbsCertificate.issuer";
321const VALIDITY: &str = "certificate.tbsCertificate.validity";
322const NOT_BEFORE: &str = "certificate.tbsCertificate.validity.notBefore";
323const NOT_AFTER: &str = "certificate.tbsCertificate.validity.notAfter";
324const SUBJECT: &str = "certificate.tbsCertificate.subject";
325const PUBLIC_KEY: &str = "certificate.tbsCertificate.subjectPublicKeyInfo";
326const ISSUER_UNIQUE_ID: &str = "certificate.tbsCertificate.issuerUniqueID";
327const SUBJECT_UNIQUE_ID: &str = "certificate.tbsCertificate.subjectUniqueID";
328const EXTENSIONS: &str = "certificate.tbsCertificate.extensions";
329const SIGNATURE_ALGORITHM: &str = "certificate.signatureAlgorithm";
330const SIGNATURE: &str = "certificate.signature";
331
332fn require(element: &Element<'_>, tag: Tag, field: &'static str) -> Result<()> {
333 if element.tag() == tag {
334 return Ok(());
335 }
336 Err(Error::new(
337 ErrorCode::Encoding(structured_asn1::ErrorCode::UnexpectedTag),
338 field,
339 element.span().start,
340 ))
341}
342
343fn read_tbs<'a>(parent: &Reader<'a>, element: &Element<'a>) -> Result<TbsCertificate<'a>> {
344 let fail = |code| Error::new(code, TBS, element.span().start);
345 require(element, Tag::constructed(universal::SEQUENCE), TBS)?;
346
347 let mut inside = parent.enter(element).field(TBS)?;
348 let mut next = inside.next_element().field(TBS)?;
349
350 let version = match next {
353 Some(tagged) if tagged.tag() == Tag::context(true, 0) => {
354 let version = read_version(&inside, &tagged)?;
355 next = inside.next_element().field(TBS)?;
356 version
357 }
358 _ => Version::V1,
361 };
362
363 let serial_element = next.ok_or_else(|| fail(ErrorCode::MissingField))?;
364 require(&serial_element, Tag::primitive(universal::INTEGER), SERIAL)?;
365 let serial = inside.integer(&serial_element).field(SERIAL)?;
366
367 let signature_element = inside
368 .next_element()
369 .field(TBS)?
370 .ok_or_else(|| fail(ErrorCode::MissingField))?;
371 let signature = algorithm::read(&inside, &signature_element, INNER_ALGORITHM)?;
372
373 let issuer_element = inside
374 .next_element()
375 .field(TBS)?
376 .ok_or_else(|| fail(ErrorCode::MissingField))?;
377 let issuer = name::read(&inside, &issuer_element, ISSUER)?;
378 if issuer.is_empty() {
384 return Err(Error::new(
385 ErrorCode::EmptySequence,
386 ISSUER,
387 issuer_element.span().start,
388 ));
389 }
390
391 let validity_element = inside
392 .next_element()
393 .field(TBS)?
394 .ok_or_else(|| fail(ErrorCode::MissingField))?;
395 let validity = read_validity(&inside, &validity_element)?;
396
397 let subject_element = inside
398 .next_element()
399 .field(TBS)?
400 .ok_or_else(|| fail(ErrorCode::MissingField))?;
401 let subject = name::read(&inside, &subject_element, SUBJECT)?;
402
403 let key_element = inside
404 .next_element()
405 .field(TBS)?
406 .ok_or_else(|| fail(ErrorCode::MissingField))?;
407 let public_key = PublicKeyInfo::read_element(&inside, &key_element, PUBLIC_KEY)?;
408
409 let Trailing {
410 issuer_unique_id,
411 subject_unique_id,
412 extensions,
413 } = read_trailing(&mut inside)?;
414
415 if !extensions.is_empty() && version != Version::V3 {
419 return Err(Error::new(
420 ErrorCode::UnexpectedField,
421 EXTENSIONS,
422 element.span().start,
423 ));
424 }
425 if (issuer_unique_id.is_some() || subject_unique_id.is_some()) && version == Version::V1 {
426 return Err(Error::new(
427 ErrorCode::UnexpectedField,
428 ISSUER_UNIQUE_ID,
429 element.span().start,
430 ));
431 }
432
433 if subject.is_empty()
438 && !extensions
439 .get(crate::oid::SUBJECT_ALT_NAME, &inside.execution())?
440 .is_some_and(|alternative| alternative.is_critical())
441 {
442 return Err(Error::new(
443 ErrorCode::MissingField,
444 SUBJECT,
445 subject_element.span().start,
446 ));
447 }
448
449 Ok(TbsCertificate {
450 version,
451 serial,
452 signature,
453 issuer,
454 validity,
455 subject,
456 public_key,
457 issuer_unique_id,
458 subject_unique_id,
459 extensions,
460 der: element.as_bytes(),
461 span: element.span(),
462 })
463}
464
465struct Trailing<'a> {
467 issuer_unique_id: Option<BitString<'a>>,
468 subject_unique_id: Option<BitString<'a>>,
469 extensions: Extensions<'a>,
470}
471
472fn read_trailing<'a>(inside: &mut Reader<'a>) -> Result<Trailing<'a>> {
473 let mut issuer_unique_id = None;
474 let mut subject_unique_id = None;
475 let mut extensions = Extensions::empty(inside.memory());
476
477 let mut last_number = 0;
482
483 while let Some(tagged) = inside.next_element().field(TBS)? {
484 let (field, number) = match tagged.tag() {
485 tag if tag == Tag::context(false, 1) && last_number < 1 => (ISSUER_UNIQUE_ID, 1),
486 tag if tag == Tag::context(false, 2) && last_number < 2 => (SUBJECT_UNIQUE_ID, 2),
487 tag if tag == Tag::context(true, 3) && last_number < 3 => (EXTENSIONS, 3),
488 _ => {
489 return Err(Error::new(
490 ErrorCode::UnexpectedField,
491 TBS,
492 tagged.span().start,
493 ));
494 }
495 };
496 last_number = number;
497
498 match number {
499 1 => issuer_unique_id = Some(inside.bit_string(&tagged).field(field)?),
500 2 => subject_unique_id = Some(inside.bit_string(&tagged).field(field)?),
501 _ => {
502 let mut wrapper = inside.enter(&tagged).field(field)?;
505 let sequence = wrapper.next_element().field(field)?.ok_or_else(|| {
506 Error::new(ErrorCode::MissingField, field, tagged.span().start)
507 })?;
508 extensions = extension::read(&wrapper, &sequence, field)?;
509 if !wrapper.is_empty() {
510 return Err(Error::new(
511 ErrorCode::TrailingData,
512 field,
513 tagged.span().start,
514 ));
515 }
516 }
517 }
518 }
519
520 Ok(Trailing {
521 issuer_unique_id,
522 subject_unique_id,
523 extensions,
524 })
525}
526
527fn read_version<'a>(parent: &Reader<'a>, element: &Element<'a>) -> Result<Version> {
528 let fail = |code| Error::new(code, VERSION, element.span().start);
529
530 let mut inside = parent.enter(element).field(VERSION)?;
531 let value = inside.read_integer().field(VERSION)?;
532 if !inside.is_empty() {
533 return Err(fail(ErrorCode::TrailingData));
534 }
535
536 match value.as_u64() {
537 Some(0) if inside.encoding().is_der() => Err(fail(ErrorCode::MalformedValue)),
541 Some(0) => Ok(Version::V1),
542 Some(1) => Ok(Version::V2),
543 Some(2) => Ok(Version::V3),
544 _ => Err(fail(ErrorCode::UnsupportedVersion)),
548 }
549}
550
551fn read_validity<'a>(parent: &Reader<'a>, element: &Element<'a>) -> Result<Validity> {
552 let fail = |code| Error::new(code, VALIDITY, element.span().start);
553 require(element, Tag::constructed(universal::SEQUENCE), VALIDITY)?;
554
555 let mut inside = parent.enter(element).field(VALIDITY)?;
556 let before = inside
557 .next_element()
558 .field(VALIDITY)?
559 .ok_or_else(|| fail(ErrorCode::MissingField))?;
560 let after = inside
561 .next_element()
562 .field(VALIDITY)?
563 .ok_or_else(|| fail(ErrorCode::MissingField))?;
564 if !inside.is_empty() {
565 return Err(fail(ErrorCode::TrailingData));
566 }
567
568 Ok(Validity {
569 not_before: time::read(&before, NOT_BEFORE)?,
570 not_after: time::read(&after, NOT_AFTER)?,
571 })
572}
573
574#[cfg(test)]
575mod tests;