Skip to content

Conversation

benburkert
Copy link

Address a few inefficiencies in std.http.Client. By default, the client loads the systems' CA bundle every time a new TLS/HTTPS connection is established. That's a good thing on the first connection attempt because it avoids loading the bundle if it's not going to be used. But by default, it's reloading the bundle on every new TLS connection, which can end up reading a lot of files from disk. It would be more efficient to only rescan the system CA bundle when the issuer certificate is not found in the current hashmap. But the difficulty with that approach is that rescanning requires an allocator, and the verify method is called by std.crypto.tls.Client.init, which does not have an allocator.

It's possible to workaround this in std.http.Client by introducing a verify callback function to std.crypto.Certificate.Bundle. (It's analogous to OpenSSL's SSL_CTX_set_cert_verify_callback.) Building on #25261, adding a callback source that takes a function pointer adds a mechanism for the std.http.Client to intercept verify calls to a Bundle, and call verifyRescan instead, passing in it's allocator. The verifyRescan only rescans the system when a matching issuer can't be found in the loaded certificates.

The callback source also allows for some further cleanup of no_verification & self_signed CA verification behavior, which can be implement now in specific callback functions.

Comment on lines +471 to +473
// TODO: return the original error if it's part of VerifyError set
client.ca_bundle.verifyRescan(client.allocator, subject, now_sec) catch
return error.CertificateIssuerNotFound;
Copy link
Author

Choose a reason for hiding this comment

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

I think there's two ways to go here: a) return the VerifyError or CertificateIssuerNotFound for any rescan error, or b) add the rescan errors to VerifyError's set. I'm not sure what's preferable.

Copy link
Author

Choose a reason for hiding this comment

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

3rd option: add error.CertificateBundleLoadFailure to VerifyError, and return that here instead of CertificateIssuerNotFound.

@truemedian
Copy link
Contributor

The premise of the first half of this issue is flawed, CA Bundle rescanning only happens once for every time next_https_rescan_certs is set to true. After scanning the CA Bundle next_https_rescan_certs is set to false so that it doesn't rescan on every TLS request.

That's what the atomic load, rescan, and atomic store in that you removed from request are for.

@andrewrk andrewrk closed this Sep 18, 2025
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