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::ber::Tag;
19use der_parser::der::*;
20use der_parser::error::*;
21use der_parser::num_bigint::BigUint;
22use der_parser::*;
23use nom::{Offset, Parser};
24use oid_registry::Oid;
25use oid_registry::*;
26use std::collections::HashMap;
27use time::Duration;
28
29#[derive(Clone, Debug, PartialEq)]
67pub struct X509Certificate<'a> {
68 pub tbs_certificate: TbsCertificate<'a>,
69 pub signature_algorithm: AlgorithmIdentifier<'a>,
70 pub signature_value: BitString<'a>,
71}
72
73impl<'a> X509Certificate<'a> {
74 #[cfg(feature = "verify")]
85 #[cfg_attr(docsrs, doc(cfg(feature = "verify")))]
86 pub fn verify_signature(
87 &self,
88 public_key: Option<&SubjectPublicKeyInfo>,
89 ) -> Result<(), X509Error> {
90 let spki = public_key.unwrap_or_else(|| self.public_key());
91 verify_signature(
92 spki,
93 &self.signature_algorithm,
94 &self.signature_value,
95 self.tbs_certificate.raw,
96 )
97 }
98}
99
100impl<'a> Deref for X509Certificate<'a> {
101 type Target = TbsCertificate<'a>;
102
103 fn deref(&self) -> &Self::Target {
104 &self.tbs_certificate
105 }
106}
107
108impl<'a> FromDer<'a, X509Error> for X509Certificate<'a> {
109 fn from_der(i: &'a [u8]) -> X509Result<Self> {
146 X509CertificateParser::new().parse(i)
148 }
149}
150
151#[derive(Clone, Copy, Debug)]
188pub struct X509CertificateParser {
189 deep_parse_extensions: bool,
190 }
192
193impl X509CertificateParser {
194 #[inline]
195 pub const fn new() -> Self {
196 X509CertificateParser {
197 deep_parse_extensions: true,
198 }
199 }
200
201 #[inline]
202 pub const fn with_deep_parse_extensions(self, deep_parse_extensions: bool) -> Self {
203 X509CertificateParser {
204 deep_parse_extensions,
205 }
206 }
207}
208
209impl<'a> Parser<&'a [u8], X509Certificate<'a>, X509Error> for X509CertificateParser {
210 fn parse(&mut self, input: &'a [u8]) -> IResult<&'a [u8], X509Certificate<'a>, X509Error> {
211 parse_der_sequence_defined_g(|i, _| {
212 let mut tbs_parser =
214 TbsCertificateParser::new().with_deep_parse_extensions(self.deep_parse_extensions);
215 let (i, tbs_certificate) = tbs_parser.parse(i)?;
216 let (i, signature_algorithm) = AlgorithmIdentifier::from_der(i)?;
217 let (i, signature_value) = parse_signature_value(i)?;
218 let cert = X509Certificate {
219 tbs_certificate,
220 signature_algorithm,
221 signature_value,
222 };
223 Ok((i, cert))
224 })(input)
225 }
226}
227
228#[allow(deprecated)]
229#[cfg(feature = "validate")]
230#[cfg_attr(docsrs, doc(cfg(feature = "validate")))]
231impl Validate for X509Certificate<'_> {
232 fn validate<W, E>(&self, warn: W, err: E) -> bool
233 where
234 W: FnMut(&str),
235 E: FnMut(&str),
236 {
237 X509StructureValidator.validate(self, &mut CallbackLogger::new(warn, err))
238 }
239}
240
241#[derive(Clone, Debug, PartialEq)]
264pub struct TbsCertificate<'a> {
265 pub version: X509Version,
266 pub serial: BigUint,
267 pub signature: AlgorithmIdentifier<'a>,
268 pub issuer: X509Name<'a>,
269 pub validity: Validity,
270 pub subject: X509Name<'a>,
271 pub subject_pki: SubjectPublicKeyInfo<'a>,
272 pub issuer_uid: Option<UniqueIdentifier<'a>>,
273 pub subject_uid: Option<UniqueIdentifier<'a>>,
274 extensions: Vec<X509Extension<'a>>,
275 pub(crate) raw: &'a [u8],
276 pub(crate) raw_serial: &'a [u8],
277}
278
279impl<'a> TbsCertificate<'a> {
280 pub fn version(&self) -> X509Version {
282 self.version
283 }
284
285 #[inline]
287 pub fn subject(&self) -> &X509Name {
288 &self.subject
289 }
290
291 #[inline]
293 pub fn issuer(&self) -> &X509Name {
294 &self.issuer
295 }
296
297 #[inline]
299 pub fn validity(&self) -> &Validity {
300 &self.validity
301 }
302
303 #[inline]
305 pub fn public_key(&self) -> &SubjectPublicKeyInfo {
306 &self.subject_pki
307 }
308
309 #[inline]
311 pub fn extensions(&self) -> &[X509Extension<'a>] {
312 &self.extensions
313 }
314
315 #[inline]
317 pub fn iter_extensions(&self) -> impl Iterator<Item = &X509Extension<'a>> {
318 self.extensions.iter()
319 }
320
321 #[inline]
326 pub fn get_extension_unique(&self, oid: &Oid) -> Result<Option<&X509Extension<'a>>, X509Error> {
327 get_extension_unique(&self.extensions, oid)
328 }
329
330 #[deprecated(
342 since = "0.13.0",
343 note = "Do not use this function (duplicate extensions are not checked), use `get_extension_unique`"
344 )]
345 pub fn find_extension(&self, oid: &Oid) -> Option<&X509Extension<'a>> {
346 self.extensions.iter().find(|&ext| ext.oid == *oid)
347 }
348
349 pub fn extensions_map(&self) -> Result<HashMap<Oid, &X509Extension<'a>>, X509Error> {
353 self.extensions
354 .iter()
355 .try_fold(HashMap::new(), |mut m, ext| {
356 if m.contains_key(&ext.oid) {
357 return Err(X509Error::DuplicateExtensions);
358 }
359 m.insert(ext.oid.clone(), ext);
360 Ok(m)
361 })
362 }
363
364 pub fn basic_constraints(
369 &self,
370 ) -> Result<Option<BasicExtension<&BasicConstraints>>, X509Error> {
371 let r = self
372 .get_extension_unique(&OID_X509_EXT_BASIC_CONSTRAINTS)?
373 .and_then(|ext| match ext.parsed_extension {
374 ParsedExtension::BasicConstraints(ref bc) => {
375 Some(BasicExtension::new(ext.critical, bc))
376 }
377 _ => None,
378 });
379 Ok(r)
380 }
381
382 pub fn key_usage(&self) -> Result<Option<BasicExtension<&KeyUsage>>, X509Error> {
387 self.get_extension_unique(&OID_X509_EXT_KEY_USAGE)?
388 .map_or(Ok(None), |ext| match ext.parsed_extension {
389 ParsedExtension::KeyUsage(ref value) => {
390 Ok(Some(BasicExtension::new(ext.critical, value)))
391 }
392 _ => Err(X509Error::InvalidExtensions),
393 })
394 }
395
396 pub fn extended_key_usage(
401 &self,
402 ) -> Result<Option<BasicExtension<&ExtendedKeyUsage>>, X509Error> {
403 self.get_extension_unique(&OID_X509_EXT_EXTENDED_KEY_USAGE)?
404 .map_or(Ok(None), |ext| match ext.parsed_extension {
405 ParsedExtension::ExtendedKeyUsage(ref value) => {
406 Ok(Some(BasicExtension::new(ext.critical, value)))
407 }
408 _ => Err(X509Error::InvalidExtensions),
409 })
410 }
411
412 pub fn policy_constraints(
417 &self,
418 ) -> Result<Option<BasicExtension<&PolicyConstraints>>, X509Error> {
419 self.get_extension_unique(&OID_X509_EXT_POLICY_CONSTRAINTS)?
420 .map_or(Ok(None), |ext| match ext.parsed_extension {
421 ParsedExtension::PolicyConstraints(ref value) => {
422 Ok(Some(BasicExtension::new(ext.critical, value)))
423 }
424 _ => Err(X509Error::InvalidExtensions),
425 })
426 }
427
428 pub fn inhibit_anypolicy(
433 &self,
434 ) -> Result<Option<BasicExtension<&InhibitAnyPolicy>>, X509Error> {
435 self.get_extension_unique(&OID_X509_EXT_INHIBITANT_ANY_POLICY)?
436 .map_or(Ok(None), |ext| match ext.parsed_extension {
437 ParsedExtension::InhibitAnyPolicy(ref value) => {
438 Ok(Some(BasicExtension::new(ext.critical, value)))
439 }
440 _ => Err(X509Error::InvalidExtensions),
441 })
442 }
443
444 pub fn policy_mappings(&self) -> Result<Option<BasicExtension<&PolicyMappings>>, X509Error> {
449 self.get_extension_unique(&OID_X509_EXT_POLICY_MAPPINGS)?
450 .map_or(Ok(None), |ext| match ext.parsed_extension {
451 ParsedExtension::PolicyMappings(ref value) => {
452 Ok(Some(BasicExtension::new(ext.critical, value)))
453 }
454 _ => Err(X509Error::InvalidExtensions),
455 })
456 }
457
458 pub fn subject_alternative_name(
463 &self,
464 ) -> Result<Option<BasicExtension<&SubjectAlternativeName<'a>>>, X509Error> {
465 self.get_extension_unique(&OID_X509_EXT_SUBJECT_ALT_NAME)?
466 .map_or(Ok(None), |ext| match ext.parsed_extension {
467 ParsedExtension::SubjectAlternativeName(ref value) => {
468 Ok(Some(BasicExtension::new(ext.critical, value)))
469 }
470 _ => Err(X509Error::InvalidExtensions),
471 })
472 }
473
474 pub fn name_constraints(&self) -> Result<Option<BasicExtension<&NameConstraints>>, X509Error> {
479 self.get_extension_unique(&OID_X509_EXT_NAME_CONSTRAINTS)?
480 .map_or(Ok(None), |ext| match ext.parsed_extension {
481 ParsedExtension::NameConstraints(ref value) => {
482 Ok(Some(BasicExtension::new(ext.critical, value)))
483 }
484 _ => Err(X509Error::InvalidExtensions),
485 })
486 }
487
488 pub fn is_ca(&self) -> bool {
490 self.basic_constraints()
491 .unwrap_or(None)
492 .map(|ext| ext.value.ca)
493 .unwrap_or(false)
494 }
495
496 pub fn raw_serial(&self) -> &'a [u8] {
498 self.raw_serial
499 }
500
501 pub fn raw_serial_as_string(&self) -> String {
503 format_serial(self.raw_serial)
504 }
505}
506
507fn get_extension_unique<'a, 'b>(
511 extensions: &'a [X509Extension<'b>],
512 oid: &Oid,
513) -> Result<Option<&'a X509Extension<'b>>, X509Error> {
514 let mut res = None;
515 for ext in extensions {
516 if ext.oid == *oid {
517 if res.is_some() {
518 return Err(X509Error::DuplicateExtensions);
519 }
520 res = Some(ext);
521 }
522 }
523 Ok(res)
524}
525
526impl<'a> AsRef<[u8]> for TbsCertificate<'a> {
527 #[inline]
528 fn as_ref(&self) -> &[u8] {
529 self.raw
530 }
531}
532
533impl<'a> FromDer<'a, X509Error> for TbsCertificate<'a> {
534 fn from_der(i: &'a [u8]) -> X509Result<TbsCertificate<'a>> {
553 let start_i = i;
554 parse_der_sequence_defined_g(move |i, _| {
555 let (i, version) = X509Version::from_der_tagged_0(i)?;
556 let (i, serial) = parse_serial(i)?;
557 let (i, signature) = AlgorithmIdentifier::from_der(i)?;
558 let (i, issuer) = X509Name::from_der(i)?;
559 let (i, validity) = Validity::from_der(i)?;
560 let (i, subject) = X509Name::from_der(i)?;
561 let (i, subject_pki) = SubjectPublicKeyInfo::from_der(i)?;
562 let (i, issuer_uid) = UniqueIdentifier::from_der_issuer(i)?;
563 let (i, subject_uid) = UniqueIdentifier::from_der_subject(i)?;
564 let (i, extensions) = parse_extensions(i, Tag(3))?;
565 let len = start_i.offset(i);
566 let tbs = TbsCertificate {
567 version,
568 serial: serial.1,
569 signature,
570 issuer,
571 validity,
572 subject,
573 subject_pki,
574 issuer_uid,
575 subject_uid,
576 extensions,
577
578 raw: &start_i[..len],
579 raw_serial: serial.0,
580 };
581 Ok((i, tbs))
582 })(i)
583 }
584}
585
586#[derive(Clone, Copy, Debug)]
588pub struct TbsCertificateParser {
589 deep_parse_extensions: bool,
590}
591
592impl TbsCertificateParser {
593 #[inline]
594 pub const fn new() -> Self {
595 TbsCertificateParser {
596 deep_parse_extensions: true,
597 }
598 }
599
600 #[inline]
601 pub const fn with_deep_parse_extensions(self, deep_parse_extensions: bool) -> Self {
602 TbsCertificateParser {
603 deep_parse_extensions,
604 }
605 }
606}
607
608impl<'a> Parser<&'a [u8], TbsCertificate<'a>, X509Error> for TbsCertificateParser {
609 fn parse(&mut self, input: &'a [u8]) -> IResult<&'a [u8], TbsCertificate<'a>, X509Error> {
610 let start_i = input;
611 parse_der_sequence_defined_g(move |i, _| {
612 let (i, version) = X509Version::from_der_tagged_0(i)?;
613 let (i, serial) = parse_serial(i)?;
614 let (i, signature) = AlgorithmIdentifier::from_der(i)?;
615 let (i, issuer) = X509Name::from_der(i)?;
616 let (i, validity) = Validity::from_der(i)?;
617 let (i, subject) = X509Name::from_der(i)?;
618 let (i, subject_pki) = SubjectPublicKeyInfo::from_der(i)?;
619 let (i, issuer_uid) = UniqueIdentifier::from_der_issuer(i)?;
620 let (i, subject_uid) = UniqueIdentifier::from_der_subject(i)?;
621 let (i, extensions) = if self.deep_parse_extensions {
622 parse_extensions(i, Tag(3))?
623 } else {
624 parse_extensions_envelope(i, Tag(3))?
625 };
626 let len = start_i.offset(i);
627 let tbs = TbsCertificate {
628 version,
629 serial: serial.1,
630 signature,
631 issuer,
632 validity,
633 subject,
634 subject_pki,
635 issuer_uid,
636 subject_uid,
637 extensions,
638
639 raw: &start_i[..len],
640 raw_serial: serial.0,
641 };
642 Ok((i, tbs))
643 })(input)
644 }
645}
646
647#[allow(deprecated)]
648#[cfg(feature = "validate")]
649#[cfg_attr(docsrs, doc(cfg(feature = "validate")))]
650impl Validate for TbsCertificate<'_> {
651 fn validate<W, E>(&self, warn: W, err: E) -> bool
652 where
653 W: FnMut(&str),
654 E: FnMut(&str),
655 {
656 TbsCertificateStructureValidator.validate(self, &mut CallbackLogger::new(warn, err))
657 }
658}
659
660#[derive(Debug, PartialEq, Eq)]
662pub struct BasicExtension<T> {
663 pub critical: bool,
664 pub value: T,
665}
666
667impl<T> BasicExtension<T> {
668 pub const fn new(critical: bool, value: T) -> Self {
669 Self { critical, value }
670 }
671}
672
673#[derive(Clone, Debug, PartialEq, Eq)]
674pub struct Validity {
675 pub not_before: ASN1Time,
676 pub not_after: ASN1Time,
677}
678
679impl Validity {
680 pub fn time_to_expiration(&self) -> Option<Duration> {
686 let now = ASN1Time::now();
687 if !self.is_valid_at(now) {
688 return None;
689 }
690 self.not_after - now
693 }
694
695 #[inline]
697 pub fn is_valid_at(&self, time: ASN1Time) -> bool {
698 time >= self.not_before && time <= self.not_after
699 }
700
701 #[inline]
703 pub fn is_valid(&self) -> bool {
704 self.is_valid_at(ASN1Time::now())
705 }
706}
707
708impl<'a> FromDer<'a, X509Error> for Validity {
709 fn from_der(i: &[u8]) -> X509Result<Self> {
710 parse_der_sequence_defined_g(|i, _| {
711 let (i, not_before) = ASN1Time::from_der(i)?;
712 let (i, not_after) = ASN1Time::from_der(i)?;
713 let v = Validity {
714 not_before,
715 not_after,
716 };
717 Ok((i, v))
718 })(i)
719 }
720}
721
722#[derive(Clone, Debug, PartialEq, Eq)]
723pub struct UniqueIdentifier<'a>(pub BitString<'a>);
724
725impl<'a> UniqueIdentifier<'a> {
726 fn from_der_issuer(i: &'a [u8]) -> X509Result<Option<Self>> {
728 Self::parse::<1>(i).map_err(|_| X509Error::InvalidIssuerUID.into())
729 }
730
731 fn from_der_subject(i: &[u8]) -> X509Result<Option<UniqueIdentifier>> {
733 Self::parse::<2>(i).map_err(|_| X509Error::InvalidSubjectUID.into())
734 }
735
736 fn parse<const TAG: u32>(i: &[u8]) -> BerResult<Option<UniqueIdentifier>> {
740 let (rem, unique_id) = OptTaggedImplicit::<BitString, Error, TAG>::from_der(i)?;
741 let unique_id = unique_id.map(|u| UniqueIdentifier(u.into_inner()));
742 Ok((rem, unique_id))
743 }
744}
745
746#[cfg(test)]
747mod tests {
748 use super::*;
749
750 #[test]
751 fn check_validity_expiration() {
752 let mut v = Validity {
753 not_before: ASN1Time::now(),
754 not_after: ASN1Time::now(),
755 };
756 assert_eq!(v.time_to_expiration(), None);
757 v.not_after = (v.not_after + Duration::new(60, 0)).unwrap();
758 assert!(v.time_to_expiration().is_some());
759 assert!(v.time_to_expiration().unwrap() <= Duration::new(60, 0));
760 assert!(v.time_to_expiration().unwrap() > Duration::new(50, 0));
763 }
764
765 #[test]
766 fn extension_duplication() {
767 let extensions = vec![
768 X509Extension::new(oid! {1.2}, true, &[], ParsedExtension::Unparsed),
769 X509Extension::new(oid! {1.3}, true, &[], ParsedExtension::Unparsed),
770 X509Extension::new(oid! {1.2}, true, &[], ParsedExtension::Unparsed),
771 X509Extension::new(oid! {1.4}, true, &[], ParsedExtension::Unparsed),
772 X509Extension::new(oid! {1.4}, true, &[], ParsedExtension::Unparsed),
773 ];
774
775 let r2 = get_extension_unique(&extensions, &oid! {1.2});
776 assert!(r2.is_err());
777 let r3 = get_extension_unique(&extensions, &oid! {1.3});
778 assert!(r3.is_ok());
779 let r4 = get_extension_unique(&extensions, &oid! {1.4});
780 assert!(r4.is_err());
781 }
782}