Skip to content

fix(legacy): preserve Windows CA store semantics - #146

Merged
pjcdawkins merged 5 commits into
mainfrom
fix/windows-ca-store-followups
Aug 11, 2026
Merged

fix(legacy): preserve Windows CA store semantics#146
pjcdawkins merged 5 commits into
mainfrom
fix/windows-ca-store-followups

Conversation

@bojanz

@bojanz bojanz commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

Summary

Follow-up to #142.

  • Preserve effective Windows certificate purposes when copying system roots into the PHP CA bundle. Windows combines encoded EKUs with store-only EKU properties, so roots restricted away from TLS server authentication are now excluded instead of becoming unconstrained PEM trust anchors.
  • Compare the complete cached CA bundle before deciding not to rewrite it. A same-size certificate rotation can change bytes before the final 32 KiB, which the previous optimization did not inspect.
  • Remove the unused PEM representation from the Windows certificate-store test fixture.

Tests

  • go test ./internal/legacy ./internal/file
  • Windows amd64 test-binary cross-compilation
  • Windows amd64 go vet for internal/legacy and internal/file
  • golangci-lint for the Windows target (0 issues)

Copilot AI lite review requested due to automatic review settings August 10, 2026 13:25
Comment thread internal/legacy/ca_bundle_windows.go Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR is a follow-up improvement to the Windows legacy-PHP trust bootstrap: it refines how Windows system roots are exported into the PHP CA bundle so that Windows-specific EKU constraints are preserved, and it fixes a cache-write optimization that could miss same-size CA bundle rotations.

Changes:

  • Filter Windows ROOT-store certificates by their effective EKUs (including store-only EKU properties) so roots not valid for TLS server auth aren’t exported as unconstrained PEM anchors.
  • Replace the CA-bundle cache “probably matches” write optimization with a full-content comparison to detect same-size changes.
  • Simplify Windows cert-store test fixtures by removing an unused PEM field and add a unit test around Windows EKU semantics.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
internal/legacy/php_manager_windows.go Switch CA bundle write path to full-content change detection.
internal/legacy/cert_store_windows_test.go Remove unused PEM representation from the Windows cert-store fixture.
internal/legacy/ca_bundle_windows.go Export only store roots that effectively allow TLS server authentication (EKU-aware).
internal/legacy/ca_bundle_windows_test.go Add coverage for Windows EKU behavior when determining TLS-root suitability.
internal/file/file.go Add WriteIfChanged helper for full-content equality checks before writing.
internal/file/file_test.go Add regression test ensuring WriteIfChanged checks the whole file and avoids rewrites on identical content.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread internal/legacy/ca_bundle_windows.go Outdated
Comment thread internal/file/file.go
WriteIfChanged read the whole destination file to compare it, even when
its size already showed the contents had changed. It now compares the
size first, so only a file which could still match is read.

The test for the purposes Windows reports for a certificate now covers
the EKU extension as well as the store property, and the two together.
Windows reports the purposes on both lists, so a property can withdraw
the server authentication an extension grants, which is what decides
whether a root belongs in the bundle. Setting the property outright
rather than adding to it keeps the combined cases unambiguous.

The test for leaving an unchanged file alone compared modification
times a few milliseconds apart, which the clock can be too coarse to
distinguish, so a rewrite could have gone unnoticed. It now backdates
the file and checks that the older time survives.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@bojanz
bojanz force-pushed the fix/windows-ca-store-followups branch from 3a2ec31 to 521c9f7 Compare August 10, 2026 13:56
Reading the purposes Windows reports can fail for one certificate in
the store, and that error stopped the whole enumeration. The bundle
then held nothing but the shipped certificates, so a single unreadable
root cost the machine every root its organization had added, leaving
the CLI unable to reach a server behind TLS inspection. Such a
certificate is now left out on its own, and its fingerprint and the
reason are reported, so the bundle keeps every other root in the store.

The bundle is now assembled whether or not all of the store could be
read, which is what lets a partial failure keep the roots it did read.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@bojanz
bojanz force-pushed the fix/windows-ca-store-followups branch from 521c9f7 to c2c18b5 Compare August 10, 2026 14:04
@pjcdawkins
pjcdawkins merged commit 11a9c66 into main Aug 11, 2026
6 checks passed
@pjcdawkins
pjcdawkins deleted the fix/windows-ca-store-followups branch August 11, 2026 16:42
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.

3 participants