X509 Path Finder is a depth-first search certificate path validator for Rust.
X509 Path Finder rejects the notion of a single "certificate chain." Instead, it searches for the first match out of infinity. Once it finds a path it can validate, the search halts and the path is returned to the caller.
The complexity of the path search is constrained by three factors:
When evaluating a path candidate for validation, X509 Path Finder is implementation-agnostic. Once it finds a path that has terminated, it presents it to be validated by a backend authority. If the authority validates the path, the search halts.
X509 Path Finder provides two validators:
openssl
feature flagBy default, the provided DefaultPathValidator validator and the DefaultCertificate X509 model are available.
text
[dependencies]
x509_path_finder = { version = "0.3"] }
Enable the openssl
feature for access to the provided OpenSSLPathValidator validator and the OpenSSLPathValidator X509 model.
text
[dependencies]
x509_path_finder = { version = "0.3", features = ["openssl"] }
```` rust no_run
use x509pathfinder::api::CertificateStore; use x509pathfinder::provided::certificate::default::DefaultCertificateIterator; use x509pathfinder::provided::store::DefaultCertificateStore; use x509pathfinder::provided::validator::default::DefaultPathValidator; use x509pathfinder::{X509PathFinder, X509PathFinderConfiguration, X509PathFinderResult, AIA, NoAIA}; use std::time::Duration; use rustls::{Certificate as RustlsCertificate, RootCertStore}; use x509cert::Certificate; use x509cert::der::{Decode};
async fn test() -> X509PathFinderResult<()> { // load certificates let intermediate = Certificate::fromder(&[]).unwrap(); let endentity = Certificate::from_der(&[]).unwrap();
// create store, load in intermediates
let store = DefaultCertificateStore::from_iter(vec![intermediate]);
// build Rustls trusted root store for validator
let mut rustls_store = RootCertStore::empty();
// Load root certificate
let root = RustlsCertificate(vec![]);
// Populate Rustls store
rustls_store.add(&root).unwrap();
// Instantiate validator with Rustls store
let validator = DefaultPathValidator::new(rustls_store);
// Instantiate finder with store and validator
let mut finder = X509PathFinder::new(X509PathFinderConfiguration {
limit: Duration::default(),
aia: AIA::None(NoAIA::default()),
store,
validator,
});
// Find a path
let report = finder.find(end_entity).await?;
let path = report.path.unwrap().into_iter().collect::<Vec<Certificate>>();
assert_eq!(2, path.len());
Ok(())
}
````
The X509PathFinderConfiguration
struct has the following fields.
limit
: limit runtime of path search. Actual limit will be N * HTTP timeout. See reqwest::ClientBuilder::timeout
for setting HTTP connection timeout.aia
: AIA
enum to configure Authority Information Access extensions.To enable AIA:
text
AIA::Client(MyX509Client::new())
To disable AIA:
text
AIA::None(NoAIA::default())
* store
- CertificateStore
implementation
* validator
: PathValidator
implementation
Because X509 Path Builder can consume AIA URLs from the web, a call to X509PathFinder::find
could in theory run forever, or be coerced into downloading vast amounts of data. Configuration options for managing X509 Path Finder resources:
limit
duration to non-zero for X509PathFinderConfiguration::limit
reqwest::ClientBuilder::timeout
to a more aggressive valuex509_client::X509ClientConfiguration::limit
to a non-zero valueCall X509PathFinder::find
to start the search.
The returning Report
contains the following fields:
path
: on validate success, Option::Some
holds CertificatePath
iterator.origin
: on validate success, Option::Some
holds a list of CertificateOrigin
valuesduration
: duration of path searchfailures
: any validation failures reported by PathValidator
implementation are held in ValidateFailure
CertificatePath
is an iterator over a list of certificates.
CertificateOrigin
is an enum that describes the origin of each certificate. Can be one of:
Find
: the initial certificate when calling X509PathFinder::find
.Store
: certificate was found in the storeUrl
: certificate was downloaded from a URL (AIA)ValidateFailure
stores any validation failures. Validation failures can occur even though a valid certificate path was eventually found. ValidateFailure
contains the following fields:
path
: the CertificatePath
of where the validation error occurredreason
: human-readable reason for the failureX509 Path Finder can be extended with three traits:
Certificate
- model-agnostic representation of an X509 certificate. Implement this trait to add more certificates modelsCertificateStore
- certificate store API. Implement this trait to make stores with different persistence strategiesPathValidator
- path validator API. Implement this trait to use different backend authorities to validate certificate paths.The following API implementations are provided with the X509 Path Finder crate:
Certificate
and PathValidator