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