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