Skip to content

PKIX validation scope and roadmap

This file is the canonical support boundary, claim-language guide, and forward-work backlog for the PKIX-facing surface.

Standards status

AreaStatusNotes
RFC 5280 path validationpartialcore path validation, supported-form name constraints, initial subtree inputs, RFC 9618 policy processing, malformed-DER coverage, and broad PKITS harness coverage ship; revocation stays a separate API and broader conformance evidence is still incomplete
RFC 6960 OCSPpartialrequest/response parsing, signature checks, responder binding/authorization, nonce/request matching, freshness checks, and full request coverage ship; local responder-policy acceptance is still incomplete
RFC 6125 service identitypartialmatchServiceIdentity() ships DNS-ID, IP-ID, URI-ID, SRV-ID, wildcard, IDNA, and opt-in CN-compat checks; verification helpers still wire DNS/IP identities only
RFC 9618 policy validationpartialRFC 9618-style policy state, enforcement, outputs, and broad PKITS harness coverage ship; broader conformance evidence is still incomplete

Current conformance evidence:

1. Define the boundary up front

  • Treat certification path validation as a function over a prospective certification path plus validation inputs, not as “build whatever chain you can find and hope for the best.”
    RFC 5280 Section 6.1.1 defines the algorithm in terms of a candidate path and nine inputs. (IETF Datatracker^rfc5280)
  • Keep path building/discovery separate from path validation.
  • Keep service identity matching separate from path validation.
  • Keep revocation separate from path validation.

2. Required inputs for RFC 5280-style path validation

  • Prospective certification path.
  • Validation time.
  • Trust anchor information: trusted issuer name, trusted public key algorithm, trusted public key, and optional trusted key parameters.
  • User-initial-policy-set.
  • Initial policy-mapping inhibit flag.
  • Initial explicit-policy flag.
  • Initial anyPolicy-inhibit flag.
  • Initial permitted subtrees.
  • Initial excluded subtrees. (IETF Datatracker^rfc5280)

3. Core certificate/path checks

  • Parse DER strictly enough to reject malformed certificates.
  • Verify issuer/subject chaining across the candidate path.
  • Verify each certificate signature using the evolving working public key.
  • Check validity time (notBefore / notAfter) against the chosen validation time.
  • Enforce basicConstraints for CA certificates.
  • Enforce pathLenConstraint where applicable.
  • Enforce keyUsage, especially keyCertSign for CAs used to sign subordinate certs.
  • Process self-issued vs non-self-issued certs correctly for path length and name constraints.
  • Reject the path if any required path-processing step fails. (IETF Datatracker^rfc5280)

4. Extension handling

  • Parse and preserve all extensions, including unknown ones.
  • Reject certificates containing an unsupported critical extension or a critical extension whose contents cannot be processed.
  • Process recognized non-critical extensions when relevant to path processing.
  • Expose raw extension data so callers can layer application-specific policy on top. (IETF Datatracker^rfc5280)

5. Name constraints

  • Support nameConstraints on CA certificates.
  • Support initial permitted/excluded subtrees as validator inputs.
  • Apply constraints across supported name forms, not just DNS SANs.
  • Handle self-issued certificates correctly when evaluating constraints. (IETF Datatracker^rfc5280)

Current GeneralName matrix for nameConstraints:

FormParser roleValidator roleStatus
rfc822Name / dNSNamedecode to typed email/DNS valuesenforcepartial
uniformResourceIdentifierdecode to typed URI valuesenforce host-based matchingpartial
iPAddressdecode to address+mask bytesenforcepartial
directoryNamepreserve structured DN payloadenforce with RFC 5280 semantic comparepartial
otherNamedo not silently discard in final designfail closed if criticalnot yet
x400Addressdo not silently discard in final designfail closed if criticalnot yet
ediPartyNamedo not silently discard in final designfail closed if criticalnot yet
registeredIDdo not silently discard in final designfail closed if criticalnot yet
  • Parser responsibility: preserve enough tag/type information that validation can make a deterministic supported-vs-unsupported decision.
  • Validator responsibility: enforce supported forms and reject critical under-enforced cases instead of silently widening trust.

6. Certificate policy processing

  • Support certificatePolicies.
  • Support policyConstraints.
  • Support policyMappings.
  • Support inhibitAnyPolicy.
  • Use the RFC 9618 update rather than the older RFC 5280 policy-tree algorithm, because RFC 9618 replaced it with an equivalent, more efficient algorithm to avoid worst-case exponential blowups and DoS risk. (IETF Datatracker^rfc9618)
  • Keep public wording at partial until broader conformance evidence lands.

7. Trust-anchor model

  • Accept trust anchors as structured input, not only as “root cert PEM”.
  • Allow trust anchor info to come from a self-signed certificate as a convenience, but treat the trust anchor as out-of-band trust input.
  • Do not assume every self-signed cert is a trust anchor. (IETF Datatracker^rfc5280)

8. Application/service identity checks

  • Keep hostname/service-name matching in a separate API from path validation.
  • For currently supported identity types (dNSName, iPAddress), match subjectAltName entries of the corresponding type first.
  • matchServiceIdentity() supports dNSName, iPAddress, URI-ID, and SRV-ID matching with wildcard and IDNA coverage.
  • Only support CN fallback as an explicit compatibility mode, because RFC 6125 treats CN-ID usage as existing practice and prefers subjectAltName; CN comparison is deprecated. (IETF Datatracker^rfc6125)
  • Make wildcard behavior explicit and test it hard.

Focused RFC 6125 identity fixtures live in test/identity-fixtures.test.ts.

9. EKU / purpose checks

  • Keep EKU checks separate from raw path validity.
  • Allow callers to request purposes such as serverAuth, clientAuth, etc.
  • Distinguish “certificate is path-valid” from “certificate is acceptable for this application”.

10. OCSP support checklist

  • Build CertID from issuer name hash, issuer key hash, serial number, and hash algorithm.
  • Discover the responder from AIA id-ad-ocsp or let callers provide a responder URL explicitly.
  • Parse and verify BasicOCSPResponse.
  • Check that the response fully and correctly refers to the requested certificate set.
  • Validate the OCSP response signature.
  • Validate responder authorization exhaustively.
    • Land RFC 6960 §4.2.2.2 criterion 1: explicit local signer acceptance scoped to the issuing CA.
    • Decide and enforce responder-certificate revocation policy — see §11 for the canonical breakdown.
    • Add fixture coverage for configured-responder accept/reject and historical-time validation.
  • Enforce response freshness using thisUpdate / nextUpdate and configurable clock skew.
  • Return good, revoked, and unknown distinctly.
  • Support optional nonce handling if you want replay binding between request and response. RFC 9654 defines the updated nonce extension details. (IETF Datatracker^rfc6960)

11. OCSP responder authorization rules

  • Accept an OCSP response signer if it matches local responder configuration for the certificate in question.
    • Add a validation input binding trusted responder certs to issuer CA scopes.
    • Thread local responder policy through validateOcspResponse() before falling back to issuer-cert or delegated-responder rules.
    • Add positive and negative fixtures for locally authorized signer scope.
  • Accept it if the signer is the issuing CA certificate itself.
  • Accept it if the signer cert contains EKU id-kp-OCSPSigning and was issued directly by the CA that issued the target certificate.
  • Reject the response if the signer certificate meets none of those conditions.
  • Decide and document responder-certificate revocation policy (RFC 6960 §4.2.2.2.1).
    • Parse and expose id-pkix-ocsp-nocheck.
    • Define validator policy knobs: honor nocheck, require CRL/OCSP evidence, or caller-local override.
    • Add fixtures for each policy branch.
    • Pass caller evaluation time through delegated responder chain validation.

Focused OCSP auth/completeness/freshness fixtures live in test/ocsp-fixtures.test.ts.

12. CRL support checklist

  • Treat CRL validation as a separate revocation subsystem.
  • Parse CRLs and CRL extensions.
  • Verify CRL signatures and issuer linkage.
  • Enforce CRL time/freshness semantics.
  • Parse CRL distribution points and enforce distribution-point scope during CRL applicability; CRL discovery/fetch hooks are not shipped.
  • Add delta CRL handling only if you actually want to live in that swamp. RFC 5280 defines CRL validation separately from path validation. (IETF Datatracker^rfc5280)

13. API design checklist

  • Keep path building separate from path validation.
  • Keep service identity matching in a separate API from path validation.
  • Keep revocation checking separate from path validation.
  • Expose structured validation inputs instead of hiding policy/name-constraint knobs.
  • Return typed failure reasons for currently implemented path-validation, CRL, and OCSP checks.
  • Distinguish hard validation failure from revocation status unknown in revocation orchestration; chain, CRL, and OCSP validators still return binary success/failure results.

14. Test/conformance checklist

  • Add fixed RFC-style test vectors for builders, parsers, and validators.
  • Add round-trip tests for certs, CSRs, names, and extensions.
  • Add a PKITS harness for shipped path-validation claims and gap reporting. See test/pkits.test.ts.
  • Add malformed DER / fuzz tests.
  • Differential-test against at least one mature implementation. See test/differential.test.ts.
  • Run the validator against NIST PKITS as a gap-report harness, which NIST describes as a comprehensive X.509 path validation test suite for relying parties. (NIST Computer Security Resource Center^x-509-path-validation)

Last updated:

Released under the MIT License.