Skip to content
Open
Show file tree
Hide file tree
Changes from 7 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
17 changes: 17 additions & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,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

check-notlocked:
Expand All @@ -48,6 +51,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 +105,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
48 changes: 27 additions & 21 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 -->
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately it seems like this commit is breaking many markdown links in the rendered preview (https://github.com/rusticata/x509-parser/blob/fe005007af027b0cbf24f8a8bd8fadac204df527/README.md)

I think the link targets aren't quite right.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Would also be nice to get #230 merged)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an annoying limitation of cargo rdme: not all intradoc links are supported, for ex [`visitor`] is not replaced.
I found a workaround by giving the full path [`X509Certificate`](crate::certificate::X509Certificate) but now cargo doc is complaining that the path is redundant
If I push a commit to use this workaround, this will add warnings when running cargo doc (and cannot fix all links).

The last solution is to strip the intradoc links when generating the README.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

About #230 , I cherry-picked the commit in this branch with a few changes to resolve the conflicts and change src/lib.rs as well as README.md.

Copy link
Collaborator

@cpu cpu Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an annoying limitation of cargo rdme: not all intradoc links are supported, for ex [visitor] is not replaced.

Bummer :-(

Would you be open to a more direct/dumber solution? We use a small script in rustls that slurps the header rustdoc from lib.rs and inserts it into the README at a fixed location. In CI we run the same script and then error if there's a diff to make sure we always update lib.rs and not the copy in README.md.

I don't think we've had any significant trouble/friction with this approach but it's not quite as polished as a dedicated tool like cargo rdme.

If I push a commit to use this workaround, this will add warnings when running cargo doc (and cannot fix all links).

I wonder if it's possible to silence/allow just that one warning about redundant paths. That seems preferable to allowing all warnings, or stripping links if you want to stick with cargo rdme.


# 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
Loading