Skip to content

feat: validate local certificate chains - #544

Open
robjtede wants to merge 1 commit into
mainfrom
validate-local-chains
Open

robjtede wants to merge 1 commit into
mainfrom
validate-local-chains

Conversation

@robjtede

@robjtede robjtede commented Oct 8, 2026 •

Copy link
Copy Markdown
Member

Local PEM chains can be inspected and checked for expiry, but their trust and hostname are not checked. Add --check --hostname for files and stdin, with system roots and repeatable --ca-file inputs.

Check certificate signatures, validity dates, hostname, CA signing usage, path length, name constraints, and critical extensions. Report results in text and JSON. Keep the existing date-based exit codes and field selection. Revocation is explicitly reported as not checked.

This is layer 1 of 4. Remote validation, supplied CRLs, and CRL downloads follow in separate PRs.

Validation on macOS: just test (72 passed) and nix develop -c just check (formatting and Clippy passed).

Summary by CodeRabbit

  • New Features
    • Added local certificate-chain validation with --check --hostname, supporting PEM input from files or stdin.
    • Validation checks trust, certificate signatures and dates, hostname matching, and CA constraints. System trust roots are used by default; repeatable --ca-file options add custom roots.
    • Validation results are available in text and JSON output. Revocation status is reported as unchecked.
  • Bug Fixes
    • Local validation results do not change the existing date-check exit codes.

@robjtede
robjtede added this pull request to stack #547 October 8, 2026 04:55
@robjtede robjtede changed the title validate local chains feat: validate local certificate chains Oct 8, 2026
@coderabbitai

coderabbitai Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 6c3da800-3d49-4fb4-be90-8faffae124a4
📥 Commits

Reviewing files that changed from the base of the PR and between 08b024b and 458add0.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (8)
  • CHANGELOG.md
  • Cargo.toml
  • README.md
  • src/main.rs
  • src/report.rs
  • src/validation.rs
  • tests/remote_timeout.rs
  • tests/validation.rs

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The CLI adds local PEM-chain validation when --check and --hostname are used. It checks trust, signatures, dates, hostname, and CA constraints with system roots and optional CA files. Text and JSON reports include validation results without changing existing date-based exit codes.

Changes

Local chain validation

Layer / File(s) Summary
Trust roots and certificate-path validation
Cargo.toml, src/validation.rs, tests/validation.rs
The verifier combines custom CA files with native roots and validates server-auth certificate paths, including intermediate CA signing usage. Tests cover trust roots, intermediates, constraints, alternative paths, and invalid CA files.
Validation reporting and CLI integration
src/main.rs, src/report.rs, src/validation.rs, tests/validation.rs, tests/remote_timeout.rs, README.md, CHANGELOG.md
The CLI accepts hostname and CA-file options, validates local input, and writes text or JSON results. Tests cover validation statuses, dates, stdin, arguments, and output. Documentation describes the options, results, and date-based exit codes.

Priority: ➖ Normal

Estimated code review effort: 4 (Complex) | ~45 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant Verifier as validation::Verifier
  participant ValidationReport as validation::Report
  participant OutputReport as report::Report
  CLI->>Verifier: Build verifier from configured roots
  CLI->>ValidationReport: Check certificate chain and hostname
  CLI->>OutputReport: Include optional validation results
Loading

Merge Risk: ⚪ Minimal · up to 458ad

This adds local certificate-chain validation reporting for PEM files and stdin, and existing exit-code behavior is unchanged. No concrete merge-blocking risk was identified from the supplied evidence.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 48.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 50 functions across 5 files. (3 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: adding validation for local certificate chains.
Full details: Docstring Coverage

Explanation

Docstring coverage is 48.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 50 functions across 5 files. (3 skipped: 3 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@robjtede

robjtede commented Oct 8, 2026

Copy link
Copy Markdown
Member Author

Reproducible examples for 458add0, using the real example.com chain. Captured on macOS on 2026-10-08.

Build this PR:

gh pr checkout 544
cargo build --locked
ICC="$PWD/target/debug/inspect-cert-chain"

Save the public chain with curl. These commands were run with curl 8.7.1; use a build that supports %{certs}:

curl --fail --silent --show-error --max-time 30 \
  --output /dev/null --write-out '%{certs}' https://example.com \
  | sed -n '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/p' \
  > example-chain.pem

Check the expected hostname:

"$ICC" --file example-chain.pem --check --hostname example.com --fields subject

Validation excerpt from the captured output:

Certificate chain: VALID
Path validation: VALID
Hostname (example.com): VALID
Certificate 1 dates: VALID
Certificate 2 dates: VALID
Certificate 3 dates: VALID
Certificate 4 dates: VALID
Revocation (leaf): NOT CHECKED

Check the same chain against a different hostname:

"$ICC" --file example-chain.pem --check --hostname wrong.example --fields subject
Certificate chain: INVALID
Path validation: VALID
Hostname (wrong.example): INVALID (hostname does not match certificate names)
Certificate 1 dates: VALID
Certificate 2 dates: VALID
Certificate 3 dates: VALID
Certificate 4 dates: VALID
Revocation (leaf): NOT CHECKED

Both commands returned exit code 0: the existing --check exit code reflects dates, while trust and hostname results are reported separately. Revocation is not checked in this layer. The public chain and certificate count can change as the site renews its certificates.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant