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::signature::SignatureValue;
9use crate::time::{self, Time};
10use structured_asn1::{BitString, Element, Integer, Parser, Reader, Span, Tag, universal};
11
12/// Which version of the structure a certificate was written to.
13#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
14pub enum Version {
15    /// The original, with no extensions and no unique identifiers.
16    V1,
17    /// Adds the unique identifiers.
18    V2,
19    /// Adds extensions, and is what every certificate in use is.
20    V3,
21}
22
23/// The interval a certificate says it may be relied on within.
24#[derive(Debug, Clone, Copy, PartialEq, Eq)]
25pub struct Validity {
26    not_before: Time,
27    not_after: Time,
28}
29
30impl Validity {
31    /// The first moment.
32    #[must_use]
33    pub fn not_before(self) -> Time {
34        self.not_before
35    }
36
37    /// The last moment.
38    #[must_use]
39    pub fn not_after(self) -> Time {
40        self.not_after
41    }
42
43    /// Whether the interval ends no earlier than it begins.
44    ///
45    /// A certificate whose interval runs backwards is never valid at any
46    /// moment. It is reported rather than refused, because a person holding
47    /// such a document is owed an explanation of it.
48    #[must_use]
49    pub fn is_well_ordered(self) -> bool {
50        self.not_before <= self.not_after
51    }
52
53    /// Whether a moment lies in the interval, at either end included.
54    #[must_use]
55    pub fn contains(self, moment: Time) -> bool {
56        self.not_before <= moment && moment <= self.not_after
57    }
58
59    /// Whether the whole of an interval lies inside this one.
60    ///
61    /// This, not [`Self::contains`], is the question the product asks. What is
62    /// known about when a signature was made is an interval, and resolving it
63    /// at one end would report a signature made before a certificate existed,
64    /// or before it was revoked, as one made while it was good.
65    #[must_use]
66    pub fn covers(self, from: Time, to: Time) -> bool {
67        // Endpoints that run backwards do not form an interval, and nothing
68        // covers what does not exist: reversed evidence bounds must not read
69        // as covered just because both moments fall inside the validity.
70        from <= to && self.contains(from) && self.contains(to)
71    }
72}
73
74/// A certificate, read once and kept as it arrived.
75#[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/// The signed part of a certificate: everything the issuer put its name to.
85#[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    /// Reads a document that is one certificate and nothing else.
104    ///
105    /// The parser carries the budget, and outlives the certificate because the
106    /// certificate borrows the document it was read from. Several certificates
107    /// read with one parser share one budget, which is what keeps a structure
108    /// holding a thousand of them from costing a thousand times the work a
109    /// caller allowed.
110    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        // Bytes after the certificate are a second document sharing a file
119        // with the first, and which of them a person is looking at would have
120        // no answer.
121        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    /// Reads a certificate from an element inside a larger structure, which is
132    /// how the ones carried by a signature are read. The parser is taken from
133    /// the parent reader, never passed beside it: it carries the envelope's
134    /// shared budget, the extensions keep it so their decodes stay charged to
135    /// it, and a fresh parser per embedded certificate is unrepresentable.
136    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        // A certificate is DER whatever carries it: RFC 5280 section 4.1
140        // defines it in DER, while the CMS envelope handing it over may be
141        // BER. The element is re-read under DER, header included, so a
142        // spelling only the envelope's leniency accepts, an indefinite or
143        // long-form outer length among them, is refused here rather than
144        // surviving into signature and path validation.
145        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        // The outer identifier is not covered by the signature. Trusting it
173        // over the one inside the signed bytes would let anybody rewrite which
174        // algorithm a certificate is verified with, so the two are required to
175        // agree and the signed one is what the registry is handed.
176        //
177        // The same semantic comparison as a deferred public operation, with
178        // this Reader additionally preserving the parser-local ceiling.
179        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    /// The signed part.
197    #[must_use]
198    pub fn tbs(&self) -> &TbsCertificate<'a> {
199        &self.tbs
200    }
201
202    /// The algorithm named outside the signed bytes, which
203    /// [`Self::read_element`] has already required to agree with the one
204    /// inside them.
205    #[must_use]
206    pub fn signature_algorithm(&self) -> AlgorithmIdentifier<'a> {
207        self.signature_algorithm
208    }
209
210    /// The signature value.
211    #[must_use]
212    pub fn signature(&self) -> BitString<'a> {
213        self.signature.bit_string()
214    }
215
216    /// Signature bytes with original source context for deferred decoding.
217    #[must_use]
218    pub fn signature_value(&self) -> SignatureValue<'a> {
219        self.signature
220    }
221
222    /// The whole certificate as it arrived, which is what a fingerprint is
223    /// taken of.
224    #[must_use]
225    pub fn as_bytes(&self) -> &'a [u8] {
226        self.der
227    }
228
229    /// Where the certificate sits in the document it was read from.
230    #[must_use]
231    pub fn span(&self) -> Span {
232        self.span
233    }
234
235    /// The bytes the issuer signed, exactly as they arrived.
236    #[must_use]
237    pub fn signed_bytes(&self) -> &'a [u8] {
238        self.tbs.der
239    }
240
241    /// Borrow the original certificate's execution under the current operation.
242    ///
243    /// Deferred metadata, catalogue growth and comparisons must retain the
244    /// producing local ceiling as well as the current operation/account. This
245    /// reuses the original algorithm provenance without reading parameters,
246    /// opening a signature payload, allocating, or cloning an account owner.
247    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    /// Which version this was written to.
277    #[must_use]
278    pub fn version(&self) -> Version {
279        self.version
280    }
281
282    /// The serial number, as encoded.
283    ///
284    /// Kept as bytes because it identifies the certificate to its issuer and
285    /// to a revocation list, and because it outgrows any integer type. The
286    /// profile requires it to be positive and at most twenty octets; a
287    /// certificate that breaks either rule is read and reports what it says,
288    /// since refusing would leave a person holding a document nothing could
289    /// explain.
290    #[must_use]
291    pub fn serial(&self) -> Integer<'a> {
292        self.serial
293    }
294
295    /// The algorithm named inside the signed bytes.
296    #[must_use]
297    pub fn signature(&self) -> AlgorithmIdentifier<'a> {
298        self.signature
299    }
300
301    /// Who issued it.
302    #[must_use]
303    pub fn issuer(&self) -> &Name<'a> {
304        &self.issuer
305    }
306
307    /// The interval it says it may be relied on within.
308    #[must_use]
309    pub fn validity(&self) -> Validity {
310        self.validity
311    }
312
313    /// Who it was issued to.
314    #[must_use]
315    pub fn subject(&self) -> &Name<'a> {
316        &self.subject
317    }
318
319    /// The public key.
320    #[must_use]
321    pub fn public_key(&self) -> PublicKeyInfo<'a> {
322        self.public_key
323    }
324
325    /// The issuer's unique identifier, which only the older versions carry.
326    #[must_use]
327    pub fn issuer_unique_id(&self) -> Option<BitString<'a>> {
328        self.issuer_unique_id
329    }
330
331    /// The subject's unique identifier, which only the older versions carry.
332    #[must_use]
333    pub fn subject_unique_id(&self) -> Option<BitString<'a>> {
334        self.subject_unique_id
335    }
336
337    /// The extensions, which are empty for anything below version 3.
338    #[must_use]
339    pub fn extensions(&self) -> &Extensions<'a> {
340        &self.extensions
341    }
342
343    /// The signed bytes, exactly as they arrived.
344    #[must_use]
345    pub fn as_bytes(&self) -> &'a [u8] {
346        self.der
347    }
348
349    /// Where the signed bytes sit in the document.
350    #[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    // The version is tagged, so its absence is told from the serial number by
392    // the tag rather than by counting fields.
393    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        // Absent means the first version, which is what a certificate from
400        // before extensions existed writes.
401        _ => 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    // RFC 5280 4.1.2.4: the issuer field must contain a non-empty
420    // distinguished name. An empty subject is allowed when an alternative
421    // name carries the identity (4.1.2.6); an empty issuer names no
422    // authority, and two identically empty names compare equal, so a
423    // certificate carrying one could chain to a CA with an empty subject.
424    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    // A field the certificate's own version says it does not have is a
457    // structure two readers would describe differently, one reading it and one
458    // stopping at the version.
459    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    // The subject may be empty only when the identity lives in the
475    // alternative name, and then that extension must be present and marked
476    // critical (RFC 5280 4.2.1.6). Absent, or present without the mark, the
477    // certificate names nobody while reading as a supplied identity.
478    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
507/// The three optional fields the signed part ends with.
508struct 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    // The tag number the last field carried. Each of the three is optional
520    // and they are written in the order of their numbers, so a tag at or
521    // below this is a repeat or a field written backwards, and either is a
522    // structure this schema does not have.
523    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                // Tagged explicitly, so the sequence of extensions is inside
545                // this element rather than being it.
546                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        // X.690 11.5: DER omits a component equal to its default, and the
580        // version defaults to v1. A certificate spelling zero out has written
581        // the absent field, which is not DER.
582        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        // A version this crate does not know describes fields it does not
587        // know, and reading it as the newest one it does know would be
588        // guessing at what the issuer meant.
589        _ => 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;