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    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    /// Reads a document that is one certificate and nothing else.
103    ///
104    /// The parser carries the budget, and outlives the certificate because the
105    /// certificate borrows the document it was read from. Several certificates
106    /// read with one parser share one budget, which is what keeps a structure
107    /// holding a thousand of them from costing a thousand times the work a
108    /// caller allowed.
109    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        // Bytes after the certificate are a second document sharing a file
118        // with the first, and which of them a person is looking at would have
119        // no answer.
120        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    /// Reads a certificate from an element inside a larger structure, which is
131    /// how the ones carried by a signature are read. The parser is taken from
132    /// the parent reader, never passed beside it: it carries the envelope's
133    /// shared budget, the extensions keep it so their decodes stay charged to
134    /// it, and a fresh parser per embedded certificate is unrepresentable.
135    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        // A certificate is DER whatever carries it: RFC 5280 section 4.1
139        // defines it in DER, while the CMS envelope handing it over may be
140        // BER. The element is re-read under DER, header included, so a
141        // spelling only the envelope's leniency accepts, an indefinite or
142        // long-form outer length among them, is refused here rather than
143        // surviving into signature and path validation.
144        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        // The outer identifier is not covered by the signature. Trusting it
172        // over the one inside the signed bytes would let anybody rewrite which
173        // algorithm a certificate is verified with, so the two are required to
174        // agree and the signed one is what the registry is handed.
175        //
176        // The same semantic comparison as a deferred public operation, with
177        // this Reader additionally preserving the parser-local ceiling.
178        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    /// The signed part.
196    #[must_use]
197    pub fn tbs(&self) -> &TbsCertificate<'a> {
198        &self.tbs
199    }
200
201    /// The algorithm named outside the signed bytes, which
202    /// [`Self::read_element`] has already required to agree with the one
203    /// inside them.
204    #[must_use]
205    pub fn signature_algorithm(&self) -> AlgorithmIdentifier<'a> {
206        self.signature_algorithm
207    }
208
209    /// The signature value.
210    #[must_use]
211    pub fn signature(&self) -> BitString<'a> {
212        self.signature.bit_string()
213    }
214
215    /// Signature bytes with original source context for deferred decoding.
216    #[must_use]
217    pub fn signature_value(&self) -> SignatureValue<'a> {
218        self.signature
219    }
220
221    /// The whole certificate as it arrived, which is what a fingerprint is
222    /// taken of.
223    #[must_use]
224    pub fn as_bytes(&self) -> &'a [u8] {
225        self.der
226    }
227
228    /// Where the certificate sits in the document it was read from.
229    #[must_use]
230    pub fn span(&self) -> Span {
231        self.span
232    }
233
234    /// The bytes the issuer signed, exactly as they arrived.
235    #[must_use]
236    pub fn signed_bytes(&self) -> &'a [u8] {
237        self.tbs.der
238    }
239
240    /// Borrow the original certificate's execution under the current operation.
241    ///
242    /// Deferred metadata, catalogue growth and comparisons must retain the
243    /// producing local ceiling as well as the current operation/account. This
244    /// reuses the original algorithm provenance without reading parameters,
245    /// opening a signature payload, allocating, or cloning an account owner.
246    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    /// Which version this was written to.
259    #[must_use]
260    pub fn version(&self) -> Version {
261        self.version
262    }
263
264    /// The serial number, as encoded.
265    ///
266    /// Kept as bytes because it identifies the certificate to its issuer and
267    /// to a revocation list, and because it outgrows any integer type. The
268    /// profile requires it to be positive and at most twenty octets; a
269    /// certificate that breaks either rule is read and reports what it says,
270    /// since refusing would leave a person holding a document nothing could
271    /// explain.
272    #[must_use]
273    pub fn serial(&self) -> Integer<'a> {
274        self.serial
275    }
276
277    /// The algorithm named inside the signed bytes.
278    #[must_use]
279    pub fn signature(&self) -> AlgorithmIdentifier<'a> {
280        self.signature
281    }
282
283    /// Who issued it.
284    #[must_use]
285    pub fn issuer(&self) -> &Name<'a> {
286        &self.issuer
287    }
288
289    /// The interval it says it may be relied on within.
290    #[must_use]
291    pub fn validity(&self) -> Validity {
292        self.validity
293    }
294
295    /// Who it was issued to.
296    #[must_use]
297    pub fn subject(&self) -> &Name<'a> {
298        &self.subject
299    }
300
301    /// The public key.
302    #[must_use]
303    pub fn public_key(&self) -> PublicKeyInfo<'a> {
304        self.public_key
305    }
306
307    /// The issuer's unique identifier, which only the older versions carry.
308    #[must_use]
309    pub fn issuer_unique_id(&self) -> Option<BitString<'a>> {
310        self.issuer_unique_id
311    }
312
313    /// The subject's unique identifier, which only the older versions carry.
314    #[must_use]
315    pub fn subject_unique_id(&self) -> Option<BitString<'a>> {
316        self.subject_unique_id
317    }
318
319    /// The extensions, which are empty for anything below version 3.
320    #[must_use]
321    pub fn extensions(&self) -> &Extensions<'a> {
322        &self.extensions
323    }
324
325    /// The signed bytes, exactly as they arrived.
326    #[must_use]
327    pub fn as_bytes(&self) -> &'a [u8] {
328        self.der
329    }
330
331    /// Where the signed bytes sit in the document.
332    #[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    // The version is tagged, so its absence is told from the serial number by
374    // the tag rather than by counting fields.
375    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        // Absent means the first version, which is what a certificate from
382        // before extensions existed writes.
383        _ => 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    // RFC 5280 4.1.2.4: the issuer field must contain a non-empty
402    // distinguished name. An empty subject is allowed when an alternative
403    // name carries the identity (4.1.2.6); an empty issuer names no
404    // authority, and two identically empty names compare equal, so a
405    // certificate carrying one could chain to a CA with an empty subject.
406    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    // A field the certificate's own version says it does not have is a
439    // structure two readers would describe differently, one reading it and one
440    // stopping at the version.
441    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    // The subject may be empty only when the identity lives in the
457    // alternative name, and then that extension must be present and marked
458    // critical (RFC 5280 4.2.1.6). Absent, or present without the mark, the
459    // certificate names nobody while reading as a supplied identity.
460    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
488/// The three optional fields the signed part ends with.
489struct 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    // The tag number the last field carried. Each of the three is optional
501    // and they are written in the order of their numbers, so a tag at or
502    // below this is a repeat or a field written backwards, and either is a
503    // structure this schema does not have.
504    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                // Tagged explicitly, so the sequence of extensions is inside
526                // this element rather than being it.
527                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        // X.690 11.5: DER omits a component equal to its default, and the
561        // version defaults to v1. A certificate spelling zero out has written
562        // the absent field, which is not DER.
563        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        // A version this crate does not know describes fields it does not
568        // know, and reading it as the newest one it does know would be
569        // guessing at what the issuer meant.
570        _ => 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;