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