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