1use 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#[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 #[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 fn from_der(i: &'a [u8]) -> X509Result<'a, Self> {
144 X509CertificateParser::new().parse(i)
146 }
147}
148
149#[derive(Clone, Copy, Debug)]
186pub struct X509CertificateParser {
187 deep_parse_extensions: bool,
188 }
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 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#[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 pub fn version(&self) -> X509Version {
286 self.version
287 }
288
289 #[inline]
291 pub fn subject(&self) -> &X509Name {
292 &self.subject
293 }
294
295 #[inline]
297 pub fn issuer(&self) -> &X509Name {
298 &self.issuer
299 }
300
301 #[inline]
303 pub fn validity(&self) -> &Validity {
304 &self.validity
305 }
306
307 #[inline]
309 pub fn public_key(&self) -> &SubjectPublicKeyInfo {
310 &self.subject_pki
311 }
312
313 #[inline]
315 pub fn extensions(&self) -> &[X509Extension<'a>] {
316 &self.extensions
317 }
318
319 #[inline]
321 pub fn iter_extensions(&self) -> impl Iterator<Item = &X509Extension<'a>> {
322 self.extensions.iter()
323 }
324
325 #[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 #[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 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 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 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 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 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 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 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 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 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 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 pub fn raw_serial(&self) -> &'a [u8] {
502 self.raw_serial
503 }
504
505 pub fn raw_serial_as_string(&self) -> String {
507 format_serial(self.raw_serial)
508 }
509}
510
511fn 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 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#[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#[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 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 self.not_after - now
703 }
704
705 #[inline]
707 pub fn is_valid_at(&self, time: ASN1Time) -> bool {
708 time >= self.not_before && time <= self.not_after
709 }
710
711 #[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 fn from_der_issuer(i: &'a [u8]) -> X509Result<'a, Option<Self>> {
738 Self::parse::<1>(i).map_err(|_| X509Error::InvalidIssuerUID.into())
739 }
740
741 fn from_der_subject(i: &[u8]) -> X509Result<Option<UniqueIdentifier>> {
743 Self::parse::<2>(i).map_err(|_| X509Error::InvalidSubjectUID.into())
744 }
745
746 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 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}