Skip to main content

structured_pkix/
certificate.rs

1//! The certificate: what it says, and the bytes that were signed.
2
3use 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/// Which version of the structure a certificate was written to.
12#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
13pub enum Version {
14    /// The original, with no extensions and no unique identifiers.
15    V1,
16    /// Adds the unique identifiers.
17    V2,
18    /// Adds extensions, and is what every certificate in use is.
19    V3,
20}
21
22/// The interval a certificate says it may be relied on within.
23#[derive(Debug, Clone, Copy, PartialEq, Eq)]
24pub struct Validity {
25    not_before: Time,
26    not_after: Time,
27}
28
29impl Validity {
30    /// The first moment.
31    #[must_use]
32    pub fn not_before(self) -> Time {
33        self.not_before
34    }
35
36    /// The last moment.
37    #[must_use]
38    pub fn not_after(self) -> Time {
39        self.not_after
40    }
41
42    /// Whether the interval ends no earlier than it begins.
43    ///
44    /// A certificate whose interval runs backwards is never valid at any
45    /// moment. It is reported rather than refused, because a person holding
46    /// such a document is owed an explanation of it.
47    #[must_use]
48    pub fn is_well_ordered(self) -> bool {
49        self.not_before <= self.not_after
50    }
51
52    /// Whether a moment lies in the interval, at either end included.
53    #[must_use]
54    pub fn contains(self, moment: Time) -> bool {
55        self.not_before <= moment && moment <= self.not_after
56    }
57
58    /// Whether the whole of an interval lies inside this one.
59    ///
60    /// This, not [`Self::contains`], is the question the product asks. What is
61    /// known about when a signature was made is an interval, and resolving it
62    /// at one end would report a signature made before a certificate existed,
63    /// or before it was revoked, as one made while it was good.
64    #[must_use]
65    pub fn covers(self, from: Time, to: Time) -> bool {
66        // Endpoints that run backwards do not form an interval, and nothing
67        // covers what does not exist: reversed evidence bounds must not read
68        // as covered just because both moments fall inside the validity.
69        from <= to && self.contains(from) && self.contains(to)
70    }
71}
72
73/// A certificate, read once and kept as it arrived.
74#[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/// The signed part of a certificate: everything the issuer put its name to.
84#[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    /// Reads a document that is one certificate and nothing else.
102    ///
103    /// The parser carries the budget, and outlives the certificate because the
104    /// certificate borrows the document it was read from. Several certificates
105    /// read with one parser share one budget, which is what keeps a structure
106    /// holding a thousand of them from costing a thousand times the work a
107    /// caller allowed.
108    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        // Bytes after the certificate are a second document sharing a file
117        // with the first, and which of them a person is looking at would have
118        // no answer.
119        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    /// Reads a certificate from an element inside a larger structure, which is
130    /// how the ones carried by a signature are read. The parser is taken from
131    /// the parent reader, never passed beside it: it carries the envelope's
132    /// shared budget, the extensions keep it so their decodes stay charged to
133    /// it, and a fresh parser per embedded certificate is unrepresentable.
134    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        // A certificate is DER whatever carries it: RFC 5280 section 4.1
138        // defines it in DER, while the CMS envelope handing it over may be
139        // BER. The element is re-read under DER, header included, so a
140        // spelling only the envelope's leniency accepts, an indefinite or
141        // long-form outer length among them, is refused here rather than
142        // surviving into signature and path validation.
143        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        // The outer identifier is not covered by the signature. Trusting it
171        // over the one inside the signed bytes would let anybody rewrite which
172        // algorithm a certificate is verified with, so the two are required to
173        // agree and the signed one is what the registry is handed.
174        //
175        // The same semantic comparison as a deferred public operation, with
176        // this Reader additionally preserving the parser-local ceiling.
177        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    /// The signed part.
195    #[must_use]
196    pub fn tbs(&self) -> &TbsCertificate<'a> {
197        &self.tbs
198    }
199
200    /// The algorithm named outside the signed bytes, which
201    /// [`Self::read_element`] has already required to agree with the one
202    /// inside them.
203    #[must_use]
204    pub fn signature_algorithm(&self) -> AlgorithmIdentifier<'a> {
205        self.signature_algorithm
206    }
207
208    /// The signature value.
209    #[must_use]
210    pub fn signature(&self) -> BitString<'a> {
211        self.signature
212    }
213
214    /// The whole certificate as it arrived, which is what a fingerprint is
215    /// taken of.
216    #[must_use]
217    pub fn as_bytes(&self) -> &'a [u8] {
218        self.der
219    }
220
221    /// Where the certificate sits in the document it was read from.
222    #[must_use]
223    pub fn span(&self) -> Span {
224        self.span
225    }
226
227    /// The bytes the issuer signed, exactly as they arrived.
228    #[must_use]
229    pub fn signed_bytes(&self) -> &'a [u8] {
230        self.tbs.der
231    }
232}
233
234impl<'a> TbsCertificate<'a> {
235    /// Which version this was written to.
236    #[must_use]
237    pub fn version(&self) -> Version {
238        self.version
239    }
240
241    /// The serial number, as encoded.
242    ///
243    /// Kept as bytes because it identifies the certificate to its issuer and
244    /// to a revocation list, and because it outgrows any integer type. The
245    /// profile requires it to be positive and at most twenty octets; a
246    /// certificate that breaks either rule is read and reports what it says,
247    /// since refusing would leave a person holding a document nothing could
248    /// explain.
249    #[must_use]
250    pub fn serial(&self) -> Integer<'a> {
251        self.serial
252    }
253
254    /// The algorithm named inside the signed bytes.
255    #[must_use]
256    pub fn signature(&self) -> AlgorithmIdentifier<'a> {
257        self.signature
258    }
259
260    /// Who issued it.
261    #[must_use]
262    pub fn issuer(&self) -> &Name<'a> {
263        &self.issuer
264    }
265
266    /// The interval it says it may be relied on within.
267    #[must_use]
268    pub fn validity(&self) -> Validity {
269        self.validity
270    }
271
272    /// Who it was issued to.
273    #[must_use]
274    pub fn subject(&self) -> &Name<'a> {
275        &self.subject
276    }
277
278    /// The public key.
279    #[must_use]
280    pub fn public_key(&self) -> PublicKeyInfo<'a> {
281        self.public_key
282    }
283
284    /// The issuer's unique identifier, which only the older versions carry.
285    #[must_use]
286    pub fn issuer_unique_id(&self) -> Option<BitString<'a>> {
287        self.issuer_unique_id
288    }
289
290    /// The subject's unique identifier, which only the older versions carry.
291    #[must_use]
292    pub fn subject_unique_id(&self) -> Option<BitString<'a>> {
293        self.subject_unique_id
294    }
295
296    /// The extensions, which are empty for anything below version 3.
297    #[must_use]
298    pub fn extensions(&self) -> &Extensions<'a> {
299        &self.extensions
300    }
301
302    /// The signed bytes, exactly as they arrived.
303    #[must_use]
304    pub fn as_bytes(&self) -> &'a [u8] {
305        self.der
306    }
307
308    /// Where the signed bytes sit in the document.
309    #[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    // The version is tagged, so its absence is told from the serial number by
351    // the tag rather than by counting fields.
352    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        // Absent means the first version, which is what a certificate from
359        // before extensions existed writes.
360        _ => 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    // RFC 5280 4.1.2.4: the issuer field must contain a non-empty
379    // distinguished name. An empty subject is allowed when an alternative
380    // name carries the identity (4.1.2.6); an empty issuer names no
381    // authority, and two identically empty names compare equal, so a
382    // certificate carrying one could chain to a CA with an empty subject.
383    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    // A field the certificate's own version says it does not have is a
416    // structure two readers would describe differently, one reading it and one
417    // stopping at the version.
418    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    // The subject may be empty only when the identity lives in the
434    // alternative name, and then that extension must be present and marked
435    // critical (RFC 5280 4.2.1.6). Absent, or present without the mark, the
436    // certificate names nobody while reading as a supplied identity.
437    if subject.is_empty()
438        && !extensions
439            .get(crate::oid::SUBJECT_ALT_NAME, inside.memory())?
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
465/// The three optional fields the signed part ends with.
466struct 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    // The tag number the last field carried. Each of the three is optional
478    // and they are written in the order of their numbers, so a tag at or
479    // below this is a repeat or a field written backwards, and either is a
480    // structure this schema does not have.
481    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                // Tagged explicitly, so the sequence of extensions is inside
503                // this element rather than being it.
504                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        // X.690 11.5: DER omits a component equal to its default, and the
538        // version defaults to v1. A certificate spelling zero out has written
539        // the absent field, which is not DER.
540        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        // A version this crate does not know describes fields it does not
545        // know, and reading it as the newest one it does know would be
546        // guessing at what the issuer meant.
547        _ => 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;