x509_parser/
certificate.rs

1//! X.509 Certificate object definitions and operations
2
3use crate::error::{X509Error, X509Result};
4use crate::extensions::*;
5use crate::time::ASN1Time;
6use crate::utils::format_serial;
7#[cfg(feature = "validate")]
8use crate::validate::*;
9use crate::x509::{
10    parse_serial, parse_signature_value, AlgorithmIdentifier, SubjectPublicKeyInfo, X509Name,
11    X509Version,
12};
13
14#[cfg(feature = "verify")]
15use crate::verify::verify_signature;
16use asn1_rs::{BitString, FromDer, OptTaggedImplicit};
17use core::ops::Deref;
18use der_parser::ber::Tag;
19use der_parser::der::*;
20use der_parser::error::*;
21use der_parser::num_bigint::BigUint;
22use der_parser::*;
23use nom::{Offset, Parser};
24use oid_registry::Oid;
25use oid_registry::*;
26use std::collections::HashMap;
27use time::Duration;
28
29/// An X.509 v3 Certificate.
30///
31/// X.509 v3 certificates are defined in [RFC5280](https://tools.ietf.org/html/rfc5280), section
32/// 4.1. This object uses the same structure for content, so for ex the subject can be accessed
33/// using the path `x509.tbs_certificate.subject`.
34///
35/// `X509Certificate` also contains convenience methods to access the most common fields (subject,
36/// issuer, etc.). These are provided using `Deref<Target = TbsCertificate>`, so documentation for
37/// these methods can be found in the [`TbsCertificate`] object.
38///
39/// A `X509Certificate` is a zero-copy view over a buffer, so the lifetime is the same as the
40/// buffer containing the binary representation.
41///
42/// ```rust
43/// # use x509_parser::prelude::FromDer;
44/// # use x509_parser::certificate::X509Certificate;
45/// #
46/// # static DER: &'static [u8] = include_bytes!("../assets/IGC_A.der");
47/// #
48/// fn display_x509_info(x509: &X509Certificate<'_>) {
49///      let subject = x509.subject();
50///      let issuer = x509.issuer();
51///      println!("X.509 Subject: {}", subject);
52///      println!("X.509 Issuer: {}", issuer);
53///      println!("X.509 serial: {}", x509.tbs_certificate.raw_serial_as_string());
54/// }
55/// #
56/// # fn main() {
57/// # let res = X509Certificate::from_der(DER);
58/// # match res {
59/// #     Ok((_rem, x509)) => {
60/// #         display_x509_info(&x509);
61/// #     },
62/// #     _ => panic!("x509 parsing failed: {:?}", res),
63/// # }
64/// # }
65/// ```
66#[derive(Clone, Debug, PartialEq)]
67pub struct X509Certificate<'a> {
68    pub tbs_certificate: TbsCertificate<'a>,
69    pub signature_algorithm: AlgorithmIdentifier<'a>,
70    pub signature_value: BitString<'a>,
71}
72
73impl<'a> X509Certificate<'a> {
74    /// Verify the cryptographic signature of this certificate
75    ///
76    /// `public_key` is the public key of the **signer**. For a self-signed certificate,
77    /// (for ex. a public root certificate authority), this is the key from the certificate,
78    /// so you can use `None`.
79    ///
80    /// For a leaf certificate, this is the public key of the certificate that signed it.
81    /// It is usually an intermediate authority.
82    ///
83    /// Not all algorithms are supported, this function is limited to what `ring` supports.
84    #[cfg(feature = "verify")]
85    #[cfg_attr(docsrs, doc(cfg(feature = "verify")))]
86    pub fn verify_signature(
87        &self,
88        public_key: Option<&SubjectPublicKeyInfo>,
89    ) -> Result<(), X509Error> {
90        let spki = public_key.unwrap_or_else(|| self.public_key());
91        verify_signature(
92            spki,
93            &self.signature_algorithm,
94            &self.signature_value,
95            self.tbs_certificate.raw,
96        )
97    }
98}
99
100impl<'a> Deref for X509Certificate<'a> {
101    type Target = TbsCertificate<'a>;
102
103    fn deref(&self) -> &Self::Target {
104        &self.tbs_certificate
105    }
106}
107
108impl<'a> FromDer<'a, X509Error> for X509Certificate<'a> {
109    /// Parse a DER-encoded X.509 Certificate, and return the remaining of the input and the built
110    /// object.
111    ///
112    /// The returned object uses zero-copy, and so has the same lifetime as the input.
113    ///
114    /// Note that only parsing is done, not validation.
115    ///
116    /// <pre>
117    /// Certificate  ::=  SEQUENCE  {
118    ///         tbsCertificate       TBSCertificate,
119    ///         signatureAlgorithm   AlgorithmIdentifier,
120    ///         signatureValue       BIT STRING  }
121    /// </pre>
122    ///
123    /// # Example
124    ///
125    /// To parse a certificate and print the subject and issuer:
126    ///
127    /// ```rust
128    /// # use x509_parser::parse_x509_certificate;
129    /// #
130    /// # static DER: &'static [u8] = include_bytes!("../assets/IGC_A.der");
131    /// #
132    /// # fn main() {
133    /// let res = parse_x509_certificate(DER);
134    /// match res {
135    ///     Ok((_rem, x509)) => {
136    ///         let subject = x509.subject();
137    ///         let issuer = x509.issuer();
138    ///         println!("X.509 Subject: {}", subject);
139    ///         println!("X.509 Issuer: {}", issuer);
140    ///     },
141    ///     _ => panic!("x509 parsing failed: {:?}", res),
142    /// }
143    /// # }
144    /// ```
145    fn from_der(i: &'a [u8]) -> X509Result<Self> {
146        // run parser with default options
147        X509CertificateParser::new().parse(i)
148    }
149}
150
151/// X.509 Certificate parser
152///
153/// This object is a parser builder, and allows specifying parsing options.
154/// Currently, the only option is to control deep parsing of X.509v3 extensions:
155/// a parser can decide to skip deep-parsing to be faster (the structure of extensions is still
156/// parsed, and the contents can be parsed later using the [`from_der`](FromDer::from_der)
157/// method from individual extension objects).
158///
159/// This object uses the `nom::Parser` trait, which must be imported.
160///
161/// # Example
162///
163/// To parse a certificate without parsing extensions:
164///
165/// ```rust
166/// use x509_parser::certificate::X509CertificateParser;
167/// use x509_parser::nom::Parser;
168///
169/// # static DER: &'static [u8] = include_bytes!("../assets/IGC_A.der");
170/// #
171/// # fn main() {
172/// // create a parser that will not parse extensions
173/// let mut parser = X509CertificateParser::new()
174///     .with_deep_parse_extensions(false);
175/// let res = parser.parse(DER);
176/// match res {
177///     Ok((_rem, x509)) => {
178///         let subject = x509.subject();
179///         let issuer = x509.issuer();
180///         println!("X.509 Subject: {}", subject);
181///         println!("X.509 Issuer: {}", issuer);
182///     },
183///     _ => panic!("x509 parsing failed: {:?}", res),
184/// }
185/// # }
186/// ```
187#[derive(Clone, Copy, Debug)]
188pub struct X509CertificateParser {
189    deep_parse_extensions: bool,
190    // strict: bool,
191}
192
193impl X509CertificateParser {
194    #[inline]
195    pub const fn new() -> Self {
196        X509CertificateParser {
197            deep_parse_extensions: true,
198        }
199    }
200
201    #[inline]
202    pub const fn with_deep_parse_extensions(self, deep_parse_extensions: bool) -> Self {
203        X509CertificateParser {
204            deep_parse_extensions,
205        }
206    }
207}
208
209impl<'a> Parser<&'a [u8], X509Certificate<'a>, X509Error> for X509CertificateParser {
210    fn parse(&mut self, input: &'a [u8]) -> IResult<&'a [u8], X509Certificate<'a>, X509Error> {
211        parse_der_sequence_defined_g(|i, _| {
212            // pass options to TbsCertificate parser
213            let mut tbs_parser =
214                TbsCertificateParser::new().with_deep_parse_extensions(self.deep_parse_extensions);
215            let (i, tbs_certificate) = tbs_parser.parse(i)?;
216            let (i, signature_algorithm) = AlgorithmIdentifier::from_der(i)?;
217            let (i, signature_value) = parse_signature_value(i)?;
218            let cert = X509Certificate {
219                tbs_certificate,
220                signature_algorithm,
221                signature_value,
222            };
223            Ok((i, cert))
224        })(input)
225    }
226}
227
228#[allow(deprecated)]
229#[cfg(feature = "validate")]
230#[cfg_attr(docsrs, doc(cfg(feature = "validate")))]
231impl Validate for X509Certificate<'_> {
232    fn validate<W, E>(&self, warn: W, err: E) -> bool
233    where
234        W: FnMut(&str),
235        E: FnMut(&str),
236    {
237        X509StructureValidator.validate(self, &mut CallbackLogger::new(warn, err))
238    }
239}
240
241/// The sequence `TBSCertificate` contains information associated with the
242/// subject of the certificate and the CA that issued it.
243///
244/// RFC5280 definition:
245///
246/// <pre>
247///   TBSCertificate  ::=  SEQUENCE  {
248///        version         [0]  EXPLICIT Version DEFAULT v1,
249///        serialNumber         CertificateSerialNumber,
250///        signature            AlgorithmIdentifier,
251///        issuer               Name,
252///        validity             Validity,
253///        subject              Name,
254///        subjectPublicKeyInfo SubjectPublicKeyInfo,
255///        issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
256///                             -- If present, version MUST be v2 or v3
257///        subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,
258///                             -- If present, version MUST be v2 or v3
259///        extensions      [3]  EXPLICIT Extensions OPTIONAL
260///                             -- If present, version MUST be v3
261///        }
262/// </pre>
263#[derive(Clone, Debug, PartialEq)]
264pub struct TbsCertificate<'a> {
265    pub version: X509Version,
266    pub serial: BigUint,
267    pub signature: AlgorithmIdentifier<'a>,
268    pub issuer: X509Name<'a>,
269    pub validity: Validity,
270    pub subject: X509Name<'a>,
271    pub subject_pki: SubjectPublicKeyInfo<'a>,
272    pub issuer_uid: Option<UniqueIdentifier<'a>>,
273    pub subject_uid: Option<UniqueIdentifier<'a>>,
274    extensions: Vec<X509Extension<'a>>,
275    pub(crate) raw: &'a [u8],
276    pub(crate) raw_serial: &'a [u8],
277}
278
279impl<'a> TbsCertificate<'a> {
280    /// Get the version of the encoded certificate
281    pub fn version(&self) -> X509Version {
282        self.version
283    }
284
285    /// Get the certificate subject.
286    #[inline]
287    pub fn subject(&self) -> &X509Name {
288        &self.subject
289    }
290
291    /// Get the certificate issuer.
292    #[inline]
293    pub fn issuer(&self) -> &X509Name {
294        &self.issuer
295    }
296
297    /// Get the certificate validity.
298    #[inline]
299    pub fn validity(&self) -> &Validity {
300        &self.validity
301    }
302
303    /// Get the certificate public key information.
304    #[inline]
305    pub fn public_key(&self) -> &SubjectPublicKeyInfo {
306        &self.subject_pki
307    }
308
309    /// Returns the certificate extensions
310    #[inline]
311    pub fn extensions(&self) -> &[X509Extension<'a>] {
312        &self.extensions
313    }
314
315    /// Returns an iterator over the certificate extensions
316    #[inline]
317    pub fn iter_extensions(&self) -> impl Iterator<Item = &X509Extension<'a>> {
318        self.extensions.iter()
319    }
320
321    /// Searches for an extension with the given `Oid`.
322    ///
323    /// Return `Ok(Some(extension))` if exactly one was found, `Ok(None)` if none was found,
324    /// or an error `DuplicateExtensions` if the extension is present twice or more.
325    #[inline]
326    pub fn get_extension_unique(&self, oid: &Oid) -> Result<Option<&X509Extension<'a>>, X509Error> {
327        get_extension_unique(&self.extensions, oid)
328    }
329
330    /// Searches for an extension with the given `Oid`.
331    ///
332    /// ## Duplicate extensions
333    ///
334    /// Note: if there are several extensions with the same `Oid`, the first one is returned, masking other values.
335    ///
336    /// RFC5280 forbids having duplicate extensions, but does not specify how errors should be handled.
337    ///
338    /// **Because of this, the `find_extension` method is not safe and should not be used!**
339    /// The [`get_extension_unique`](Self::get_extension_unique) method checks for duplicate extensions and should be
340    /// preferred.
341    #[deprecated(
342        since = "0.13.0",
343        note = "Do not use this function (duplicate extensions are not checked), use `get_extension_unique`"
344    )]
345    pub fn find_extension(&self, oid: &Oid) -> Option<&X509Extension<'a>> {
346        self.extensions.iter().find(|&ext| ext.oid == *oid)
347    }
348
349    /// Builds and returns a map of extensions.
350    ///
351    /// If an extension is present twice, this will fail and return `DuplicateExtensions`.
352    pub fn extensions_map(&self) -> Result<HashMap<Oid, &X509Extension<'a>>, X509Error> {
353        self.extensions
354            .iter()
355            .try_fold(HashMap::new(), |mut m, ext| {
356                if m.contains_key(&ext.oid) {
357                    return Err(X509Error::DuplicateExtensions);
358                }
359                m.insert(ext.oid.clone(), ext);
360                Ok(m)
361            })
362    }
363
364    /// Attempt to get the certificate Basic Constraints extension
365    ///
366    /// Return `Ok(Some(extension))` if exactly one was found, `Ok(None)` if none was found,
367    /// or an error if the extension is present twice or more.
368    pub fn basic_constraints(
369        &self,
370    ) -> Result<Option<BasicExtension<&BasicConstraints>>, X509Error> {
371        let r = self
372            .get_extension_unique(&OID_X509_EXT_BASIC_CONSTRAINTS)?
373            .and_then(|ext| match ext.parsed_extension {
374                ParsedExtension::BasicConstraints(ref bc) => {
375                    Some(BasicExtension::new(ext.critical, bc))
376                }
377                _ => None,
378            });
379        Ok(r)
380    }
381
382    /// Attempt to get the certificate Key Usage extension
383    ///
384    /// Return `Ok(Some(extension))` if exactly one was found, `Ok(None)` if none was found,
385    /// or an error if the extension is invalid, or is present twice or more.
386    pub fn key_usage(&self) -> Result<Option<BasicExtension<&KeyUsage>>, X509Error> {
387        self.get_extension_unique(&OID_X509_EXT_KEY_USAGE)?
388            .map_or(Ok(None), |ext| match ext.parsed_extension {
389                ParsedExtension::KeyUsage(ref value) => {
390                    Ok(Some(BasicExtension::new(ext.critical, value)))
391                }
392                _ => Err(X509Error::InvalidExtensions),
393            })
394    }
395
396    /// Attempt to get the certificate Extended Key Usage extension
397    ///
398    /// Return `Ok(Some(extension))` if exactly one was found, `Ok(None)` if none was found,
399    /// or an error if the extension is invalid, or is present twice or more.
400    pub fn extended_key_usage(
401        &self,
402    ) -> Result<Option<BasicExtension<&ExtendedKeyUsage>>, X509Error> {
403        self.get_extension_unique(&OID_X509_EXT_EXTENDED_KEY_USAGE)?
404            .map_or(Ok(None), |ext| match ext.parsed_extension {
405                ParsedExtension::ExtendedKeyUsage(ref value) => {
406                    Ok(Some(BasicExtension::new(ext.critical, value)))
407                }
408                _ => Err(X509Error::InvalidExtensions),
409            })
410    }
411
412    /// Attempt to get the certificate Policy Constraints extension
413    ///
414    /// Return `Ok(Some(extension))` if exactly one was found, `Ok(None)` if none was found,
415    /// or an error if the extension is invalid, or is present twice or more.
416    pub fn policy_constraints(
417        &self,
418    ) -> Result<Option<BasicExtension<&PolicyConstraints>>, X509Error> {
419        self.get_extension_unique(&OID_X509_EXT_POLICY_CONSTRAINTS)?
420            .map_or(Ok(None), |ext| match ext.parsed_extension {
421                ParsedExtension::PolicyConstraints(ref value) => {
422                    Ok(Some(BasicExtension::new(ext.critical, value)))
423                }
424                _ => Err(X509Error::InvalidExtensions),
425            })
426    }
427
428    /// Attempt to get the certificate Policy Constraints extension
429    ///
430    /// Return `Ok(Some(extension))` if exactly one was found, `Ok(None)` if none was found,
431    /// or an error if the extension is invalid, or is present twice or more.
432    pub fn inhibit_anypolicy(
433        &self,
434    ) -> Result<Option<BasicExtension<&InhibitAnyPolicy>>, X509Error> {
435        self.get_extension_unique(&OID_X509_EXT_INHIBITANT_ANY_POLICY)?
436            .map_or(Ok(None), |ext| match ext.parsed_extension {
437                ParsedExtension::InhibitAnyPolicy(ref value) => {
438                    Ok(Some(BasicExtension::new(ext.critical, value)))
439                }
440                _ => Err(X509Error::InvalidExtensions),
441            })
442    }
443
444    /// Attempt to get the certificate Policy Mappings extension
445    ///
446    /// Return `Ok(Some(extension))` if exactly one was found, `Ok(None)` if none was found,
447    /// or an error if the extension is invalid, or is present twice or more.
448    pub fn policy_mappings(&self) -> Result<Option<BasicExtension<&PolicyMappings>>, X509Error> {
449        self.get_extension_unique(&OID_X509_EXT_POLICY_MAPPINGS)?
450            .map_or(Ok(None), |ext| match ext.parsed_extension {
451                ParsedExtension::PolicyMappings(ref value) => {
452                    Ok(Some(BasicExtension::new(ext.critical, value)))
453                }
454                _ => Err(X509Error::InvalidExtensions),
455            })
456    }
457
458    /// Attempt to get the certificate Subject Alternative Name extension
459    ///
460    /// Return `Ok(Some(extension))` if exactly one was found, `Ok(None)` if none was found,
461    /// or an error if the extension is invalid, or is present twice or more.
462    pub fn subject_alternative_name(
463        &self,
464    ) -> Result<Option<BasicExtension<&SubjectAlternativeName<'a>>>, X509Error> {
465        self.get_extension_unique(&OID_X509_EXT_SUBJECT_ALT_NAME)?
466            .map_or(Ok(None), |ext| match ext.parsed_extension {
467                ParsedExtension::SubjectAlternativeName(ref value) => {
468                    Ok(Some(BasicExtension::new(ext.critical, value)))
469                }
470                _ => Err(X509Error::InvalidExtensions),
471            })
472    }
473
474    /// Attempt to get the certificate Name Constraints extension
475    ///
476    /// Return `Ok(Some(extension))` if exactly one was found, `Ok(None)` if none was found,
477    /// or an error if the extension is invalid, or is present twice or more.
478    pub fn name_constraints(&self) -> Result<Option<BasicExtension<&NameConstraints>>, X509Error> {
479        self.get_extension_unique(&OID_X509_EXT_NAME_CONSTRAINTS)?
480            .map_or(Ok(None), |ext| match ext.parsed_extension {
481                ParsedExtension::NameConstraints(ref value) => {
482                    Ok(Some(BasicExtension::new(ext.critical, value)))
483                }
484                _ => Err(X509Error::InvalidExtensions),
485            })
486    }
487
488    /// Returns true if certificate has `basicConstraints CA:true`
489    pub fn is_ca(&self) -> bool {
490        self.basic_constraints()
491            .unwrap_or(None)
492            .map(|ext| ext.value.ca)
493            .unwrap_or(false)
494    }
495
496    /// Get the raw bytes of the certificate serial number
497    pub fn raw_serial(&self) -> &'a [u8] {
498        self.raw_serial
499    }
500
501    /// Get a formatted string of the certificate serial number, separated by ':'
502    pub fn raw_serial_as_string(&self) -> String {
503        format_serial(self.raw_serial)
504    }
505}
506
507/// Searches for an extension with the given `Oid`.
508///
509/// Note: if there are several extensions with the same `Oid`, an error `DuplicateExtensions` is returned.
510fn get_extension_unique<'a, 'b>(
511    extensions: &'a [X509Extension<'b>],
512    oid: &Oid,
513) -> Result<Option<&'a X509Extension<'b>>, X509Error> {
514    let mut res = None;
515    for ext in extensions {
516        if ext.oid == *oid {
517            if res.is_some() {
518                return Err(X509Error::DuplicateExtensions);
519            }
520            res = Some(ext);
521        }
522    }
523    Ok(res)
524}
525
526impl<'a> AsRef<[u8]> for TbsCertificate<'a> {
527    #[inline]
528    fn as_ref(&self) -> &[u8] {
529        self.raw
530    }
531}
532
533impl<'a> FromDer<'a, X509Error> for TbsCertificate<'a> {
534    /// Parse a DER-encoded TbsCertificate object
535    ///
536    /// <pre>
537    /// TBSCertificate  ::=  SEQUENCE  {
538    ///      version         [0]  Version DEFAULT v1,
539    ///      serialNumber         CertificateSerialNumber,
540    ///      signature            AlgorithmIdentifier,
541    ///      issuer               Name,
542    ///      validity             Validity,
543    ///      subject              Name,
544    ///      subjectPublicKeyInfo SubjectPublicKeyInfo,
545    ///      issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
546    ///                           -- If present, version MUST be v2 or v3
547    ///      subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,
548    ///                           -- If present, version MUST be v2 or v3
549    ///      extensions      [3]  Extensions OPTIONAL
550    ///                           -- If present, version MUST be v3 --  }
551    /// </pre>
552    fn from_der(i: &'a [u8]) -> X509Result<TbsCertificate<'a>> {
553        let start_i = i;
554        parse_der_sequence_defined_g(move |i, _| {
555            let (i, version) = X509Version::from_der_tagged_0(i)?;
556            let (i, serial) = parse_serial(i)?;
557            let (i, signature) = AlgorithmIdentifier::from_der(i)?;
558            let (i, issuer) = X509Name::from_der(i)?;
559            let (i, validity) = Validity::from_der(i)?;
560            let (i, subject) = X509Name::from_der(i)?;
561            let (i, subject_pki) = SubjectPublicKeyInfo::from_der(i)?;
562            let (i, issuer_uid) = UniqueIdentifier::from_der_issuer(i)?;
563            let (i, subject_uid) = UniqueIdentifier::from_der_subject(i)?;
564            let (i, extensions) = parse_extensions(i, Tag(3))?;
565            let len = start_i.offset(i);
566            let tbs = TbsCertificate {
567                version,
568                serial: serial.1,
569                signature,
570                issuer,
571                validity,
572                subject,
573                subject_pki,
574                issuer_uid,
575                subject_uid,
576                extensions,
577
578                raw: &start_i[..len],
579                raw_serial: serial.0,
580            };
581            Ok((i, tbs))
582        })(i)
583    }
584}
585
586/// `TbsCertificate` parser builder
587#[derive(Clone, Copy, Debug)]
588pub struct TbsCertificateParser {
589    deep_parse_extensions: bool,
590}
591
592impl TbsCertificateParser {
593    #[inline]
594    pub const fn new() -> Self {
595        TbsCertificateParser {
596            deep_parse_extensions: true,
597        }
598    }
599
600    #[inline]
601    pub const fn with_deep_parse_extensions(self, deep_parse_extensions: bool) -> Self {
602        TbsCertificateParser {
603            deep_parse_extensions,
604        }
605    }
606}
607
608impl<'a> Parser<&'a [u8], TbsCertificate<'a>, X509Error> for TbsCertificateParser {
609    fn parse(&mut self, input: &'a [u8]) -> IResult<&'a [u8], TbsCertificate<'a>, X509Error> {
610        let start_i = input;
611        parse_der_sequence_defined_g(move |i, _| {
612            let (i, version) = X509Version::from_der_tagged_0(i)?;
613            let (i, serial) = parse_serial(i)?;
614            let (i, signature) = AlgorithmIdentifier::from_der(i)?;
615            let (i, issuer) = X509Name::from_der(i)?;
616            let (i, validity) = Validity::from_der(i)?;
617            let (i, subject) = X509Name::from_der(i)?;
618            let (i, subject_pki) = SubjectPublicKeyInfo::from_der(i)?;
619            let (i, issuer_uid) = UniqueIdentifier::from_der_issuer(i)?;
620            let (i, subject_uid) = UniqueIdentifier::from_der_subject(i)?;
621            let (i, extensions) = if self.deep_parse_extensions {
622                parse_extensions(i, Tag(3))?
623            } else {
624                parse_extensions_envelope(i, Tag(3))?
625            };
626            let len = start_i.offset(i);
627            let tbs = TbsCertificate {
628                version,
629                serial: serial.1,
630                signature,
631                issuer,
632                validity,
633                subject,
634                subject_pki,
635                issuer_uid,
636                subject_uid,
637                extensions,
638
639                raw: &start_i[..len],
640                raw_serial: serial.0,
641            };
642            Ok((i, tbs))
643        })(input)
644    }
645}
646
647#[allow(deprecated)]
648#[cfg(feature = "validate")]
649#[cfg_attr(docsrs, doc(cfg(feature = "validate")))]
650impl Validate for TbsCertificate<'_> {
651    fn validate<W, E>(&self, warn: W, err: E) -> bool
652    where
653        W: FnMut(&str),
654        E: FnMut(&str),
655    {
656        TbsCertificateStructureValidator.validate(self, &mut CallbackLogger::new(warn, err))
657    }
658}
659
660/// Basic extension structure, used in search results
661#[derive(Debug, PartialEq, Eq)]
662pub struct BasicExtension<T> {
663    pub critical: bool,
664    pub value: T,
665}
666
667impl<T> BasicExtension<T> {
668    pub const fn new(critical: bool, value: T) -> Self {
669        Self { critical, value }
670    }
671}
672
673#[derive(Clone, Debug, PartialEq, Eq)]
674pub struct Validity {
675    pub not_before: ASN1Time,
676    pub not_after: ASN1Time,
677}
678
679impl Validity {
680    /// The time left before the certificate expires.
681    ///
682    /// If the certificate is not currently valid, then `None` is
683    /// returned.  Otherwise, the `Duration` until the certificate
684    /// expires is returned.
685    pub fn time_to_expiration(&self) -> Option<Duration> {
686        let now = ASN1Time::now();
687        if !self.is_valid_at(now) {
688            return None;
689        }
690        // Note that the duration below is guaranteed to be positive,
691        // since we just checked that now < na
692        self.not_after - now
693    }
694
695    /// Check the certificate time validity for the provided date/time
696    #[inline]
697    pub fn is_valid_at(&self, time: ASN1Time) -> bool {
698        time >= self.not_before && time <= self.not_after
699    }
700
701    /// Check the certificate time validity
702    #[inline]
703    pub fn is_valid(&self) -> bool {
704        self.is_valid_at(ASN1Time::now())
705    }
706}
707
708impl<'a> FromDer<'a, X509Error> for Validity {
709    fn from_der(i: &[u8]) -> X509Result<Self> {
710        parse_der_sequence_defined_g(|i, _| {
711            let (i, not_before) = ASN1Time::from_der(i)?;
712            let (i, not_after) = ASN1Time::from_der(i)?;
713            let v = Validity {
714                not_before,
715                not_after,
716            };
717            Ok((i, v))
718        })(i)
719    }
720}
721
722#[derive(Clone, Debug, PartialEq, Eq)]
723pub struct UniqueIdentifier<'a>(pub BitString<'a>);
724
725impl<'a> UniqueIdentifier<'a> {
726    // issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL
727    fn from_der_issuer(i: &'a [u8]) -> X509Result<Option<Self>> {
728        Self::parse::<1>(i).map_err(|_| X509Error::InvalidIssuerUID.into())
729    }
730
731    // subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL
732    fn from_der_subject(i: &[u8]) -> X509Result<Option<UniqueIdentifier>> {
733        Self::parse::<2>(i).map_err(|_| X509Error::InvalidSubjectUID.into())
734    }
735
736    // Parse a [tag] UniqueIdentifier OPTIONAL
737    //
738    // UniqueIdentifier  ::=  BIT STRING
739    fn parse<const TAG: u32>(i: &[u8]) -> BerResult<Option<UniqueIdentifier>> {
740        let (rem, unique_id) = OptTaggedImplicit::<BitString, Error, TAG>::from_der(i)?;
741        let unique_id = unique_id.map(|u| UniqueIdentifier(u.into_inner()));
742        Ok((rem, unique_id))
743    }
744}
745
746#[cfg(test)]
747mod tests {
748    use super::*;
749
750    #[test]
751    fn check_validity_expiration() {
752        let mut v = Validity {
753            not_before: ASN1Time::now(),
754            not_after: ASN1Time::now(),
755        };
756        assert_eq!(v.time_to_expiration(), None);
757        v.not_after = (v.not_after + Duration::new(60, 0)).unwrap();
758        assert!(v.time_to_expiration().is_some());
759        assert!(v.time_to_expiration().unwrap() <= Duration::new(60, 0));
760        // The following assumes this timing won't take 10 seconds... I
761        // think that is safe.
762        assert!(v.time_to_expiration().unwrap() > Duration::new(50, 0));
763    }
764
765    #[test]
766    fn extension_duplication() {
767        let extensions = vec![
768            X509Extension::new(oid! {1.2}, true, &[], ParsedExtension::Unparsed),
769            X509Extension::new(oid! {1.3}, true, &[], ParsedExtension::Unparsed),
770            X509Extension::new(oid! {1.2}, true, &[], ParsedExtension::Unparsed),
771            X509Extension::new(oid! {1.4}, true, &[], ParsedExtension::Unparsed),
772            X509Extension::new(oid! {1.4}, true, &[], ParsedExtension::Unparsed),
773        ];
774
775        let r2 = get_extension_unique(&extensions, &oid! {1.2});
776        assert!(r2.is_err());
777        let r3 = get_extension_unique(&extensions, &oid! {1.3});
778        assert!(r3.is_ok());
779        let r4 = get_extension_unique(&extensions, &oid! {1.4});
780        assert!(r4.is_err());
781    }
782}