Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ jobs:
- uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ matrix.rust }}
- name: Cargo update (fix for MSRV)
run: cargo update -p time --precise 0.3.41
if: matrix.rust == '1.67.1'
- run: RUSTFLAGS="-D warnings" cargo check --locked --all-targets --all-features

test:
Expand Down Expand Up @@ -99,6 +102,17 @@ jobs:
components: clippy
- run: cargo clippy --locked --all-features -- -D warnings

readme:
name: Check if README is up to date
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Install stable toolchain
uses: dtolnay/rust-toolchain@stable
- run: |
cargo install cargo-rdme
cargo rdme --check --no-fail-on-warnings

doc:
name: Build documentation
needs: check
Expand Down
26 changes: 26 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,32 @@

### Thanks

## 0.18.0

### Added/Changed

- Update lock file and dependencies
- Fix clippy warnings
- Visitor: add method to visit unknown extension and those with parse errors
- Add new feature `verify-aws` to used `aws-lc-rs` as crypto provider instead of `ring`
- The features are exclusive, so only one should be used
- If both are specified, `aws-lc-rs` is used (but both dependencies are included)
- Add `as_raw` methods to `X509Certificate`, `CertificateRevocationList` and `X509CertificationRequest`
- This method exposes the raw ASN.1 DER bytes used to build the object (#217)

Extensions:
- Add support for SubjectInfoAccess extension
- GeneralName: add a new variant `Invalid` so an invalid entry does not stop
parsing for the entire list of names (for ex in SAN)

### Fixed

- PEM: ignore lines in comments which contain invalid UTF-8 characters (#180)

### Thanks

- Daniel McCarney

## 0.17.0

### Added/Changed/Fixed
Expand Down
10 changes: 5 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "x509-parser"
version = "0.18.0-beta.1"
version = "0.19.0-beta.1"
description = "Parser for the X.509 v3 format (RFC 5280 certificates)"
license = "MIT OR Apache-2.0"
keywords = ["X509","Certificate","parser","nom"]
Expand Down
61 changes: 45 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
<!-- cargo-sync-readme start -->

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE-MIT)
[![Apache License 2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](./LICENSE-APACHE)
[![docs.rs](https://docs.rs/x509-parser/badge.svg)](https://docs.rs/x509-parser)
Expand All @@ -8,6 +6,8 @@
[![Github CI](https://github.com/rusticata/x509-parser/workflows/Continuous%20integration/badge.svg)](https://github.com/rusticata/x509-parser/actions)
[![Minimum rustc version](https://img.shields.io/badge/rustc-1.67.1+-lightgray.svg)](#rust-version-requirements)

<!-- cargo-rdme start -->

# X.509 Parser

A X.509 v3 ([RFC5280]) parser, implemented with the [nom](https://github.com/Geal/nom)
Expand All @@ -22,25 +22,36 @@ and is part of the [Rusticata](https://github.com/rusticata) project.

Certificates are usually encoded in two main formats: PEM (usually the most common format) or
DER. A PEM-encoded certificate is a container, storing a DER object. See the
[`pem`](https://docs.rs/x509-parser/latest/x509_parser/pem/index.html) module for more documentation.
[`pem`] module for more documentation.

To decode a DER-encoded certificate, the main parsing method is
`X509Certificate::from_der` (
part of the [`FromDer`](https://docs.rs/x509-parser/latest/x509_parser/prelude/trait.FromDer.html) trait
), which builds a
[`X509Certificate`](https://docs.rs/x509-parser/latest/x509_parser/certificate/struct.X509Certificate.html) object.
`X509Certificate::parse_der` (from the [`DerParser`](asn1_rs::DerParser) trait)
which builds a [`X509Certificate`] object.

The [`parse_der`](asn1_rs::DerParser) trait takes an [`Input`](asn1_rs::Input)
object, which can be built from the input bytes. This helps tracking offsets (in case of
error).
For convenience,
the [`X509Certificate::from_der`] method (part of the [`FromDer`] trait)
does the same directly on the input bytes, but it can loose the precise error location.

An alternative method is to use [`X509CertificateParser`](https://docs.rs/x509-parser/latest/x509_parser/certificate/struct.X509CertificateParser.html),
which allows specifying parsing options (for example, not automatically parsing option contents).

Similar methods are provided for other X.509 objects:
- [`X509Certificate`] for X.509 Certificates
- [`CertificateRevocationList`] for X.509 v2 Certificate Revocation List (CRL)
- [`X509CertificationRequest`](https://docs.rs/x509-parser/latest/x509_parser/certification_request/struct.X509CertificationRequest.html) for Certification Signing Request (CSR)

The returned objects for parsers follow the definitions of the RFC. This means that accessing
fields is done by accessing struct members recursively. Some helper functions are provided, for
example [`X509Certificate::issuer()`](https://docs.rs/x509-parser/latest/x509_parser/certificate/struct.X509Certificate.html#method.issuer) returns the
example `X509Certificate::issuer()` returns the
same as accessing `<object>.tbs_certificate.issuer`.

For PEM-encoded certificates, use the [`pem`](https://docs.rs/x509-parser/latest/x509_parser/pem/index.html) module.
For PEM-encoded certificates, use the [`pem`] module.

This crate also provides visitor traits: [`X509CertificateVisitor`](crate::visitor::X509CertificateVisitor).
This crate also provides visitor traits: `X509CertificateVisitor`, `CertificateRevocationListVisitor`.
See the [`visitor`] module.

# Examples

Expand All @@ -51,7 +62,8 @@ use x509_parser::prelude::*;

static IGCA_DER: &[u8] = include_bytes!("../assets/IGC_A.der");

let res = X509Certificate::from_der(IGCA_DER);
let input = Input::from(IGCA_DER);
let res = X509Certificate::parse_der(input);
match res {
Ok((rem, cert)) => {
assert!(rem.is_empty());
Expand All @@ -65,9 +77,8 @@ match res {
To parse a CRL and print information about revoked certificates:

```rust
#
#
let res = CertificateRevocationList::from_der(DER);
let input = Input::from(DER);
let res = CertificateRevocationList::parse_der(input);
match res {
Ok((_rem, crl)) => {
for revoked in crl.iter_revoked_certificates() {
Expand All @@ -85,7 +96,7 @@ See also `examples/print-cert.rs`.

- The `verify` and `verify-aws` features adds support for (cryptographic) signature verification, based on `ring` or `aws-lc` respectively.
It adds the
[`X509Certificate::verify_signature()`](https://docs.rs/x509-parser/latest/x509_parser/certificate/struct.X509Certificate.html#method.verify_signature)
[`X509Certificate::verify_signature()`] method
to `X509Certificate`.

```rust
Expand All @@ -99,6 +110,13 @@ pub fn check_signature(cert: &X509Certificate<'_>, issuer: &X509Certificate<'_>)
}
```

- The `verify-aws` feature offers the same support for signature verification, but based on
`aws-lc-rs` instead of `ring`.

- _Note_: if both `verify` and `verify-aws` features are enabled (which happens when using
`--all-features`), the verification will use `aws-lc-rs`. It also has the side-effect of
having a dependency on `ring`, even if it is not used.

- The `validate` features add methods to run more validation functions on the certificate structure
and values using the [`Validate`](https://docs.rs/x509-parser/latest/x509_parser/validate/trait.Validate.html) trait.
It does not validate any cryptographic parameter (see `verify` above).
Expand All @@ -109,7 +127,18 @@ pub fn check_signature(cert: &X509Certificate<'_>, issuer: &X509Certificate<'_>)
dependencies and for proc-macro attributes support.

[RFC5280]: https://tools.ietf.org/html/rfc5280
<!-- cargo-sync-readme end -->

<!-- cargo-rdme end -->

## MSRV policy

This projects tries to maintain compatibility with older version of the rust compiler for the following
durations:
- `master` branch: _12 months_ minimum
- older releases: about 24 months

However, due to dependencies and the fact that some crate writers tend to require very recent
versions of the compiler, this can prove to be difficult. These numbers are given as _best-effort_.

## Changes

Expand Down
6 changes: 3 additions & 3 deletions UPGRADING.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## Upgrading from 0.17 to 0.18
## Upgrading from 0.18 to 0.19

The major changes in version 0.18 are described here.
The major changes in version 0.19 are described here.

### Cargo and dependencies

Expand Down Expand Up @@ -53,4 +53,4 @@ The following changes are not part of this crate, but are exposed in `Any` objec

- Many parsers have been replaced by derive attributes (like `Sequence` or `Choice`) when possible. This reduces risks of errors and makes code more easier to maintain
+ Encoders are not derived for now
- File `extensions/mod.rs` has been split in multiple files
- File `extensions/mod.rs` has been split in multiple files
48 changes: 27 additions & 21 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
//! [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE-MIT)
//! [![Apache License 2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](./LICENSE-APACHE)
//! [![docs.rs](https://docs.rs/x509-parser/badge.svg)](https://docs.rs/x509-parser)
//! [![crates.io](https://img.shields.io/crates/v/x509-parser.svg)](https://crates.io/crates/x509-parser)
//! [![Download numbers](https://img.shields.io/crates/d/x509-parser.svg)](https://crates.io/crates/x509-parser)
//! [![Github CI](https://github.com/rusticata/x509-parser/workflows/Continuous%20integration/badge.svg)](https://github.com/rusticata/x509-parser/actions)
//! [![Minimum rustc version](https://img.shields.io/badge/rustc-1.67.1+-lightgray.svg)](#rust-version-requirements)
//!
//! # X.509 Parser
//!
//! A X.509 v3 ([RFC5280]) parser, implemented with the [nom](https://github.com/Geal/nom)
Expand All @@ -20,25 +12,37 @@
//!
//! Certificates are usually encoded in two main formats: PEM (usually the most common format) or
//! DER. A PEM-encoded certificate is a container, storing a DER object. See the
//! [`pem`](pem/index.html) module for more documentation.
//! [`pem`] module for more documentation.
//!
//! To decode a DER-encoded certificate, the main parsing method is
//! `X509Certificate::from_der` (
//! part of the [`FromDer`](prelude/trait.FromDer.html) trait
//! ), which builds a
//! [`X509Certificate`](certificate/struct.X509Certificate.html) object.
//! `X509Certificate::parse_der` (from the [`DerParser`](asn1_rs::DerParser) trait)
//! which builds a [`X509Certificate`] object.
//!
//! The [`parse_der`](asn1_rs::DerParser) trait takes an [`Input`](asn1_rs::Input)
//! object, which can be built from the input bytes. This helps tracking offsets (in case of
//! error).
//! For convenience,
//! the [`X509Certificate::from_der`] method (part of the [`FromDer`] trait)
//! does the same directly on the input bytes, but it can loose the precise error location.
//!
//! An alternative method is to use [`X509CertificateParser`](certificate/struct.X509CertificateParser.html),
//! An alternative method is to use [`X509CertificateParser`](crate::certificate::X509CertificateParser),
//! which allows specifying parsing options (for example, not automatically parsing option contents).
//!
//! Similar methods are provided for other X.509 objects:
//! - [`X509Certificate`] for X.509 Certificates
//! - [`CertificateRevocationList`] for X.509 v2 Certificate Revocation List (CRL)
//! - [`X509CertificationRequest`](crate::certification_request::X509CertificationRequest) for Certification Signing Request (CSR)

//!
//! The returned objects for parsers follow the definitions of the RFC. This means that accessing
//! fields is done by accessing struct members recursively. Some helper functions are provided, for
//! example [`X509Certificate::issuer()`](certificate/struct.X509Certificate.html#method.issuer) returns the
//! example [`X509Certificate::issuer()`](crate::certificate::TbsCertificate::issuer()) returns the
//! same as accessing `<object>.tbs_certificate.issuer`.
//!
//! For PEM-encoded certificates, use the [`pem`](pem/index.html) module.
//! For PEM-encoded certificates, use the [`pem`] module.
//!
//! This crate also provides visitor traits: [`X509CertificateVisitor`](crate::visitor::X509CertificateVisitor).
//! This crate also provides visitor traits: [`X509CertificateVisitor`](crate::visitor::X509CertificateVisitor), [`CertificateRevocationListVisitor`](crate::visitor::CertificateRevocationListVisitor).
//! See the [`visitor`] module.
//!
//! # Examples
//!
Expand All @@ -50,7 +54,8 @@
//! static IGCA_DER: &[u8] = include_bytes!("../assets/IGC_A.der");
//!
//! # fn main() {
//! let res = X509Certificate::from_der(IGCA_DER);
//! let input = Input::from(IGCA_DER);
//! let res = X509Certificate::parse_der(input);
//! match res {
//! Ok((rem, cert)) => {
//! assert!(rem.is_empty());
Expand All @@ -70,7 +75,8 @@
//! # static DER: &[u8] = include_bytes!("../assets/example.crl");
//! #
//! # fn main() {
//! let res = CertificateRevocationList::from_der(DER);
//! let input = Input::from(DER);
//! let res = CertificateRevocationList::parse_der(input);
//! match res {
//! Ok((_rem, crl)) => {
//! for revoked in crl.iter_revoked_certificates() {
Expand All @@ -89,7 +95,7 @@
//!
//! - The `verify` and `verify-aws` features adds support for (cryptographic) signature verification, based on `ring` or `aws-lc` respectively.
//! It adds the
//! [`X509Certificate::verify_signature()`](certificate/struct.X509Certificate.html#method.verify_signature)
//! [`X509Certificate::verify_signature()`] method
//! to `X509Certificate`.
//!
//! ```rust
Expand All @@ -113,7 +119,7 @@
//! having a dependency on `ring`, even if it is not used.
//!
//! - The `validate` features add methods to run more validation functions on the certificate structure
//! and values using the [`Validate`](validate/trait.Validate.html) trait.
//! and values using the [`Validate`](crate::validate::Validate) trait.
//! It does not validate any cryptographic parameter (see `verify` above).
//!
//! ## Rust version requirements
Expand Down
2 changes: 1 addition & 1 deletion src/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ pub use crate::validate::*;
pub use crate::x509::*;
pub use crate::*;

pub use asn1_rs::{DerParser, FromDer};
pub use asn1_rs::{DerParser, FromDer, Input};