pub fn build_path(
target: &Certificate,
pool: &CertPool,
anchors: &[TrustAnchor],
) -> Result<Vec<Certificate>>Expand description
Build a certification path from target through certificates in pool
to one of the provided trust anchors.
Returns the ordered chain [target, intermediate..., anchor-issued] ready
for pkix_path::validate_path. Signatures are not verified here;
that is the responsibility of the caller via pkix_path::validate_path.
§Algorithm
Single-pass depth-first search at the configured max_depth. Candidates
at each frame are ordered by AKI/SKI tier (RFC 5280 §4.2.1.1) so
disambiguating bridge-CA / cross-cert topologies succeeds on the first
candidate when AKI/SKI bindings are well-formed. Cycles are detected by
SubjectPublicKeyInfo algorithm OID + raw public-key bits; algorithm
parameters are excluded so RFC 8017 absent-vs-NULL ambiguity in
rsaEncryption SPKIs does not break detection.
This is a thin wrapper over the PathCandidates iterator: it returns
the iterator’s first yield, or invokes a depth+1 probe (with fresh
budget) on None to distinguish Error::NoPathFound from
Error::DepthExceeded.
§Errors
Error::NoPathFound— no topologically valid path throughpoolleads to any of the given trust anchors.Error::DepthExceeded— a path exists topologically but requires more thanPathBuilderConfig::max_depthintermediate certificates.Error::BudgetExceeded— the DFS frame-entry budget was exhausted before a path was found; the pool may be adversarially large or structured to produce exponential search.
§Choosing between build_path, the iterator, and build_first_valid_path
Use this single-shot API when:
- the pool is from a trusted source (in-house cert store, configured intermediate bundle), and
- finding any topologically valid chain is sufficient (the caller does not need to retry with alternate chains if signature verification fails downstream).
Use build_path_candidates (or its _with_config sibling) when you
want full control over candidate iteration — for adversarial pools (CMS
SignedData.certificates bags, federal-bridge cross-cert topologies,
anywhere the wire-order of certs is not under your control) so failed
signature verification can be retried against the next candidate path.
See PathCandidates for the build-then-validate retry-loop pattern.
Use build_first_valid_path (or its _with_config sibling) for the
common case of “iterate candidates until one validates”: it wraps the
iterator + pkix_path::validate_path retry loop and returns the
first chain that survives both topological build and signature
verification. Prefer this over build_path when the pool contains
alternatives whose signatures may be rejected by the verifier (e.g.,
cross-signed intermediates using algorithms outside the verifier’s
dispatch table).
§Limitations
Candidate selection uses AKI/SKI as an ordering heuristic, not a
security gate. When the cert seeking an issuer carries an
AuthorityKeyIdentifier extension with a keyIdentifier field
(RFC 5280 §4.2.1.1), pool candidates whose SubjectKeyIdentifier
(§4.2.1.2) matches are tried before DN-only matches. This is
best-effort disambiguation for bridge-CA and key-rollover topologies
where multiple CA certs share an issuer DN. The signature itself is
not verified by this crate — that happens downstream in
pkix_path::validate_path. Consequences:
- When the AKI heuristic picks the wrong candidate (e.g., AKI is
absent or malformed, multiple candidates share the same SKI, or
the AKI/SKI binding is wrong), the returned chain may fail
validate_pathwithSignatureInvalidrather thanError::NoPathFoundhere. Callers handling adversarial pools should usebuild_path_candidatesto retry alternate chains. - Malformed AKI or SKI extensions are treated as if absent (fail-soft). They do not cause path building to abort; they simply degrade selection to DN-only ranking for that cert.
- The AKI
authorityCertIssuer+authorityCertSerialNumberfields (the rare alternative tokeyIdentifier) are not currently used for ranking. Only thekeyIdentifierfield participates.
Anchor matching is by DN only. When a candidate’s issuer DN matches
any anchor in anchors, path building terminates immediately with that
chain — the anchor’s SubjectPublicKeyInfo is not verified against
what the chain expects.
Shortest-first is no longer guaranteed. Earlier versions of this
crate used iterative-deepening DFS to return the shortest topology
first. The single-pass DFS used now (which shares state with the
PathCandidates iterator) yields paths in depth-first order. For
typical pools the first yielded chain is still the shortest; for
adversarial pools, a deeper chain may be returned first if its branch
is explored before a shallower alternative. If shortest-first matters,
inspect the returned chain length and (rarely) re-run with a tightened
max_depth.
§Security
Pool contents should be from a trusted source. The DFS frame-entry budget enforces a hard cap on search work to prevent denial-of-service via oversized or crafted pools.