Skip to content

Add X509AuthorityKeyIdentifier to generated leaf certificates - #1899

Open
AronUJVARY wants to merge 1 commit into
dotnet:mainfrom
AronUJVARY:bugfix/add_authority_key_identifier_to_leaf_certificates
Open

AronUJVARY wants to merge 1 commit into
dotnet:mainfrom
AronUJVARY:bugfix/add_authority_key_identifier_to_leaf_certificates

Conversation

@AronUJVARY

Copy link
Copy Markdown

Python starting at 3.13 defaults to using VERIFY_X509_STRICT in its ssl context (https://docs.python.org/3/library/ssl.html, https://gist.github.com/mdehling/350fc63d286a31b2653aef1362c6b0f5/). This leads to python rejecting the leaf certificates of dev-proxy, complaining about missing authority key identifier. Adding the X509AuthorityKeyIdentifierExtension fixes the issue.

@AronUJVARY
AronUJVARY requested a review from a team as a code owner September 29, 2026 09:02
@AronUJVARY

Copy link
Copy Markdown
Author

@dotnet-policy-service agree company="Cinemo"

@AronUJVARY
AronUJVARY force-pushed the bugfix/add_authority_key_identifier_to_leaf_certificates branch from b603f73 to 1932ff5 Compare September 29, 2026 09:04
@waldekmastykarz waldekmastykarz added the pr-bugfix Fixes a bug label Sep 29, 2026
@waldekmastykarz

Copy link
Copy Markdown
Collaborator

Thanks a lot for this @AronUJVARY! 🙏 Great catch. Python 3.13 turning on VERIFY_X509_STRICT by default is exactly the kind of thing that silently breaks people, and you're right that our leaf certs should've had an AKI all along. Really appreciate you tracking it down and sending a fix.

Adding X509AuthorityKeyIdentifierExtension to the leaf is the right fix. There's one catch though: CreateFromCertificate(_ca, includeKeyIdentifier: true, ...) throws when the root doesn't have a Subject Key Identifier. We still load roots created by the previous (Titanium-based) engine, and those don't have an SKI, so for folks upgrading this would fail on every HTTPS request. That's also why the test helper needed the SKI added. The test passes now, but it hides the scenario rather than covering it.

Since this is going into v4, which is a major release, we can do this properly instead of working around old certs. Here's what I'd suggest:

  • Treat roots without an SKI as invalid in TryLoadRoot, same as we do for expired/non-CA roots. We then regenerate the root and purge the leaf cache, which the code already handles. Even with an AKI on the leaf, strict mode also requires the CA to have an SKI, so this is needed for Python to work anyway. Optionally, also check that KeyUsage includes keyCertSign.
  • Invalidate cached leaves without a matching AKI in TryLoadLeaf. Leaves are cached for up to a year, so without this, folks on v4 previews would keep getting old leaves that lack the AKI. Checking that the AKI matches the root's SKI also protects us against leaves signed by a different root.
  • Tests: keep the SKI in the helper, and add tests that (1) a root without an SKI gets regenerated, (2) a cached leaf without an AKI gets re-created, and (3) the leaf's AKI key id matches the root's SKI.

With these changes the root is regenerated on upgrade, so people will need to trust it again. That's fine for v4, and I'll call it out in the release notes.

Would you be up for making these changes? If not, no worries at all, just let me know and we'll take it from here. Thanks again!

This branch has not been deployed

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

Labels

pr-bugfix Fixes a bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants