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 pub(crate) raw: &'a [u8],
72}
73
74impl<'a> X509Certificate<'a> {
75 pub fn as_raw(&self) -> &'a [u8] {
82 self.raw
83 }
84
85 #[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 fn from_der(i: &'a [u8]) -> X509Result<'a, Self> {
163 X509CertificateParser::new().parse(i)
165 }
166}
167
168#[derive(Clone, Copy, Debug)]
205pub struct X509CertificateParser {
206 deep_parse_extensions: bool,
207 }
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 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#[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 pub fn version(&self) -> X509Version {
310 self.version
311 }
312
313 #[inline]
315 pub fn subject(&self) -> &X509Name<'_> {
316 &self.subject
317 }
318
319 #[inline]
321 pub fn issuer(&self) -> &X509Name<'_> {
322 &self.issuer
323 }
324
325 #[inline]
327 pub fn validity(&self) -> &Validity {
328 &self.validity
329 }
330
331 #[inline]
333 pub fn public_key(&self) -> &SubjectPublicKeyInfo<'_> {
334 &self.subject_pki
335 }
336
337 #[inline]
339 pub fn extensions(&self) -> &[X509Extension<'a>] {
340 &self.extensions
341 }
342
343 #[inline]
345 pub fn iter_extensions(&self) -> impl Iterator<Item = &X509Extension<'a>> {
346 self.extensions.iter()
347 }
348
349 #[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 #[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 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 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 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 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 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 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 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 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 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 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 pub fn raw_serial(&self) -> &'a [u8] {
530 self.raw_serial
531 }
532
533 pub fn raw_serial_as_string(&self) -> String {
535 format_serial(self.raw_serial)
536 }
537}
538
539fn 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 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#[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#[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 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 self.not_after - now
731 }
732
733 #[inline]
735 pub fn is_valid_at(&self, time: ASN1Time) -> bool {
736 time >= self.not_before && time <= self.not_after
737 }
738
739 #[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 fn from_der_issuer(i: &'a [u8]) -> X509Result<'a, Option<Self>> {
766 Self::parse::<1>(i).map_err(|_| X509Error::InvalidIssuerUID.into())
767 }
768
769 fn from_der_subject(i: &[u8]) -> X509Result<'_, Option<UniqueIdentifier<'_>>> {
771 Self::parse::<2>(i).map_err(|_| X509Error::InvalidSubjectUID.into())
772 }
773
774 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 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}