Skip to main content

ValidatedPath

Struct ValidatedPath 

Source
#[non_exhaustive]
pub struct ValidatedPath { pub anchor_index: usize, pub depth: usize, pub leaf_subject: Name, pub leaf_issuer: Name, pub leaf_serial: SerialNumber, pub leaf_spki: SubjectPublicKeyInfoOwned, pub valid_policy_tree: Option<Vec<PolicyTreeNode>>, }
Expand description

The result of a successful certificate path validation.

A ValidatedPath is only produced when validate_path succeeds, which requires the input chain to contain at least one certificate. Callers may therefore rely on chain[0] being valid after a successful validation.

Fields are pub for direct read access. #[non_exhaustive] prevents external code from constructing ValidatedPath directly and from pattern-matching exhaustively, preserving the ability to add fields in future minor versions without a breaking change.

§Copy removal in 0.3.0

ValidatedPath is no longer Copy. The struct now carries owned heap-backed fields exposing RFC 5280 §6.1.5 wrap-up outputs (the leaf’s subject DN, issuer DN, serial number, and SubjectPublicKeyInfo) so consumers can read the validated leaf identity without re-parsing chain[0]. These fields cannot satisfy the Copy bound; pre-0.3 callers that relied on bit-copy semantics need to add .clone() or pass &ValidatedPath instead.

§§6.1.5 wrap-up outputs

RFC 5280 §6.1.5 specifies that successful path validation produces several outputs identifying the validated leaf certificate. The four leaf-intrinsic outputs (subject, issuer, serial, SPKI) are surfaced here as convenience accessors; consumers no longer need to re-parse chain[0] to obtain them.

Other §6.1.5 outputs that depend on validation state (the final working_public_key_parameters, the valid_policy_tree) are not yet surfaced. Future minor versions may add them; callers should pattern match with .. rest patterns on this #[non_exhaustive] struct.

Hash is no longer derived because none of the new field types (x509_cert::name::Name, x509_cert::serial_number::SerialNumber, spki::SubjectPublicKeyInfoOwned) implement Hash upstream. No in-tree consumer used ValidatedPath as a HashMap/HashSet key, so dropping the derive is observable but should not require code changes for any existing user.

Fields (Non-exhaustive)§

This struct is marked as non-exhaustive
Non-exhaustive structs could have additional fields added in future. Therefore, non-exhaustive structs cannot be constructed in external crates using the traditional Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.
§anchor_index: usize

Index into the anchors slice of the trust anchor that terminated the path.

§depth: usize

Number of certificates in the validated chain minus one (chain.len() - 1).

For a single self-signed certificate, depth == 0. For a leaf + one intermediate, depth == 1. This equals chain.len().saturating_sub(1).

Note: this counts all certificates except the trust anchor — including self-issued intermediates that RFC 5280 §4.2.1.9 excludes from the pathLenConstraint count. For chains with self-issued intermediates the depth field may be larger than the RFC 5280 path length.

Do not compare depth directly against a certificate’s BasicConstraints pathLenConstraint value. RFC 5280 §4.2.1.9 defines pathLenConstraint as the number of non-self-issued intermediates below the issuing CA, which differs from this field’s total certificate count. Use the RFC 5280 §6.1.4(b) accounting performed by chain_walk instead.

§leaf_subject: Name

Subject DN of the validated leaf certificate (chain[0].subject).

RFC 5280 §6.1.5 names this output indirectly: a successful path validation produces the leaf’s identity (subject + serial uniquely identify a certificate). This field is a convenience accessor — callers could equivalently read chain[0].tbs_certificate.subject, but threading the chain to every consumer that needs the leaf’s DN is awkward. The clone is owned to free the validated value from any lifetime tie to the input chain.

§leaf_issuer: Name

Issuer DN of the validated leaf certificate (chain[0].issuer).

This is the §6.1.5(f) working_issuer_name output as observed at the leaf cert (which is the first cert processed by the §6.1 algorithm, so the leaf’s issuer is the initial value of working_issuer_name before iteration begins; for a successfully validated chain it identifies the directly-signing CA).

§leaf_serial: SerialNumber

Serial number of the validated leaf certificate (chain[0].serial_number).

Together with Self::leaf_issuer this forms the RFC 5280 §4.1.2.2 unique certificate identifier ({ issuer, serial }), which downstream code commonly needs for revocation lookups, audit logging, or de-duplication.

§leaf_spki: SubjectPublicKeyInfoOwned

SubjectPublicKeyInfo of the validated leaf certificate.

This is the §6.1.5(c)(d)(e) working_public_key / working_public_key_algorithm / working_public_key_parameters outputs, bundled into the canonical SPKI form. Downstream code (e.g. application-layer signature verification using the validated leaf as a trust delegate) needs the full SPKI rather than only the algorithm identifier or only the public-key bits.

Note: this field reflects the leaf’s encoded SPKI as it appeared in the certificate, not a normalized/canonicalized form. PSS parameters, RSA parameters: NULL vs parameters: absent ambiguities, etc. are preserved verbatim.

§valid_policy_tree: Option<Vec<PolicyTreeNode>>

The final RFC 5280 §6.1.5 valid_policy_tree, or None if the tree was reduced to NULL during validation.

Some(tree) is the post-§6.1.5(g)(iii) state of the tree (i.e. after intersection with initial_policy_set and post-pruning). None means the path validated under explicit_policy == 0 without any policy constraint — semantically “no policies asserted or required”. Callers that want to enforce a specific policy OID (or extract qualifiers attached to a specific policy) should inspect this field and treat None as “no policy information available”, not as a validation failure.

Each node carries its policy qualifiers (RFC 5280 §6.1.2(a)) in the upstream PolicyQualifierInfo form (a (qualifier_id_oid, raw_any_value) pair, no decoding of qualifier). See PolicyTreeNode for the per-node shape.

For convenience, Self::policy_qualifiers iterates (policy_oid, qualifier) pairs across all tree nodes.

Implementations§

Source§

impl ValidatedPath

Source

pub fn policy_qualifiers( &self, ) -> impl Iterator<Item = (&ObjectIdentifier, &PolicyQualifierInfo)> + '_

Iterate (policy_oid, qualifier) pairs across every node in the final policy tree.

Returns an empty iterator if the tree is None (either the chain validated under explicit_policy == 0 with no policy assertions, or the tree was reduced to NULL during validation).

Each yielded pair is (node.valid_policy, &qualifier) — the qualifier is a reference into the tree, valid for the borrow duration. Multiple qualifiers attached to the same policy yield multiple pairs with equal first elements; multiple nodes with the same policy OID (possible in pathological policy-mapping cases) also yield multiple pairs.

Callers commonly need to:

  1. Filter by policy_qualifier_id to find a specific qualifier type (CPS pointer or user notice).
  2. Read qualifier.qualifier (an Option<der::Any>) and decode according to the policy_qualifier_id. See PolicyTreeNode::qualifiers for why we do not decode upstream-side.

Trait Implementations§

Source§

impl Clone for ValidatedPath

Source§

fn clone(&self) -> ValidatedPath

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ValidatedPath

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'de> Deserialize<'de> for ValidatedPath

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Eq for ValidatedPath

Source§

impl PartialEq for ValidatedPath

Source§

fn eq(&self, other: &ValidatedPath) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Serialize for ValidatedPath

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl StructuralPartialEq for ValidatedPath

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V