Parse PEM-encoded certificates
masterx509_parser::pem module.repository·master·Indexed 42 days ago
https://github.com/rusticata/x509-parserA high-performance, zero-copy X.509 v3 (RFC 5280) parser implemented in pure Rust using the nom framework. It supports DER and PEM formats and provides tools for parsing certificates, Certificate Revocation Lists (CRL), and Certification Signing Requests (CSR). Version 0.19.0-beta.1 requires Rustc 1.85 or greater. Optional features include structural validation via the 'validate' feature and cryptographic signature verification via 'verify' (ring), 'verify-aws' (aws-lc-rs), or 'verify-aws-fips'.
x509_parser::pem module.x509-parser requires Rustc version 1.85 or greater.You can generate self-signed X.509 certificates using RSA-PSS padding for testing purposes with OpenSSL. The following commands generate DER-encoded certificates using SHA-256, SHA-384, and SHA-512 respectively.
Key flags used:
-sigopt rsa_padding_mode:pss: Specifies RSA-PSS padding.-sigopt rsa_pss_saltlen:-1: Sets the salt length to the maximum possible.-outform der: Ensures the output is in DER format.# Generate SHA-256 certificate
openssl req -new -x509 -newkey rsa:2048 -keyout /dev/null -nodes -sigopt rsa_padding_mode:pss -sha256 -sigopt rsa_pss_saltlen:-1 -outform der -out self_signed_sha256.der -batch
# Generate SHA-384 certificate
openssl req -new -x509 -newkey rsa:2048 -keyout /dev/null -nodes -sigopt rsa_padding_mode:pss -sha384 -sigopt rsa_pss_saltlen:-1 -outform der -out self_signed_sha384.der -batch
# Generate SHA-512 certificate
openssl req -new -x509 -newkey rsa:2048 -keyout /dev/null -nodes -sigopt rsa_padding_mode:pss -sha512 -sigopt rsa_pss_saltlen:-1 -outform der -out self_signed_sha512.der -batchnom to 8.0 and asn1-rs to 0.8, and the removal of the der-parser dependency and re-export.The X509CertificateVisitor trait implements the Visitor pattern to allow traversing the components of an X509Certificate without manual field access.
visit_extension method for any X509Extension. It also provides specific methods for standard extensions (e.g., visit_extension_aki for AuthorityKeyIdentifier).visit_extension_parse_error is invoked.use x509_parser::prelude::*;
use x509_parser::visitor::X509CertificateVisitor;
#[derive(Debug, Default)]
struct MyVisitor {
issuer: String,
is_ca: bool,
}
impl X509CertificateVisitor for MyVisitor {
fn visit_issuer(&mut self, name: &X509Name<'_>) {
self.issuer = name.to_string();
}
fn visit_extension_basic_constraints(&mut self, bc: &BasicConstraints) {
self.is_ca = bc.ca;
}
}
// Usage:
// let mut visitor = MyVisitor::default();
// x509.walk(&mut visitor);The verify feature adds support for cryptographic signature verification using the ring crate. It provides the X509Certificate::verify_signature() method.
To verify if a certificate was signed by an issuer, you can use the issuer's public key:
#[cfg(any(feature = "verify", feature = "verify-aws", feature = "verify-aws-fips"))]
use x509_parser::certificate::X509Certificate;
#[cfg(any(feature = "verify", feature = "verify-aws", feature = "verify-aws-fips"))]
pub fn check_signature(cert: &X509Certificate<'_>, issuer: &X509Certificate<'_>) -> bool {
let issuer_public_key = issuer.public_key();
cert
.verify_signature(Some(issuer_public_key))
.is_ok()
}The CertificateRevocationListVisitor trait allows you to traverse a CertificateRevocationList (CRL) by implementing specific callback methods. This is useful for extracting specific data (like revoked certificate serial numbers) or inspecting extensions without manually navigating the entire tree structure.
visit_extension) and specific methods for recognized extensions (e.g., visit_extension_aki). A specific method is only called if the extension OID matches and the content is successfully parsed.visit_revoked_certificates vs visit_revoked_certificate). If you implement a trait that provides multiple visitor methods, be aware that the same extension might be visited multiple times..walk(&mut visitor) method on a CertificateRevocationList instance to begin traversal.use asn1_rs::num_bigint::BigUint;
use x509_parser::prelude::*;
use x509_parser::visitor::CertificateRevocationListVisitor;
#[derive(Debug, Default)]
struct RevokedCertsVisitor {
certificates: Vec<BigUint>,
}
impl CertificateRevocationListVisitor for RevokedCertsVisitor {
fn visit_revoked_certificate(&mut self, certificate: &RevokedCertificate<'_>) {
self.certificates.push(certificate.user_certificate.clone());
}
}When a file contains multiple PEM blocks (like a certificate chain), use Pem::iter_from_buffer or Pem::iter_from_reader to get a PemIterator.
This iterator skips any text outside of valid -----BEGIN ...----- and -----END ...----- blocks. Each call to next() returns a Result<Pem, PEMError>. The iterator terminates when no more blocks are found or when PEMError::MissingHeader is encountered.
To enable cryptographic signature verification, you must enable one of the following features:
verify: Uses the ring crate for signature verification. Adds the X509Certificate::verify_signature() method.verify-aws: Uses the aws-lc-rs crate for signature verification. Adds the X509Certificate::verify_signature() method.verify-aws-fips: Uses the FIPS-approved crypto module of aws-lc-rs. Requires CMake, Go, and an executable temporary directory on the host system.Note: If both verify and verify-aws (or verify-aws-fips) are enabled, aws-lc-rs will be used for verification, but ring will still be included as a dependency.
An X509Certificate is a wrapper around a TbsCertificate (To-Be-Signed certificate) and the signature data.
X509Certificate: Contains the tbs_certificate, the signature_algorithm, and the signature_value. It provides a zero-copy view of the entire signed certificate.TbsCertificate: Contains the core identity and validity information defined in RFC5280, including the version, serial number, issuer, validity period, subject, and extensions.Because X509Certificate implements Deref<Target = TbsCertificate>, you can call TbsCertificate methods (like .subject() or .issuer()) directly on an X509Certificate instance.
The DistributionPointName is a CHOICE type used to identify the location of a CRL. It can take one of two forms:
FullName(Vec<GeneralName>): A list of GeneralName objects (typically URIs).NameRelativeToCRLIssuer(RelativeDistinguishedName): A distinguished name relative to the CRL issuer.This type uses implicit tagging in its ASN.1 definition.
validate feature adds methods to run validation functions on the certificate structure and values using the Validate trait. Note that this feature does not perform cryptographic parameter validation; use the verify features for that.