From 6d75fcbea4088f6595e12215441f91ab28224536 Mon Sep 17 00:00:00 2001 From: lucca Date: Sat, 17 Oct 2026 14:43:10 -0700 Subject: [PATCH] Load system CA certificates once per SSLContext on Linux _configure_context() ran on every wrap_socket()/wrap_bio() and called set_default_verify_paths() on the same context each time. On OpenSSL 3.0 that re-parses the CA file and appends the default cert directory to the X509_LOOKUP_store URI list without deduplication, so every later handshake scans that directory once per previous connection. Co-Authored-By: Claude Opus 5.5 --- src/truststore/_openssl.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/truststore/_openssl.py b/src/truststore/_openssl.py index 1a323258..4b2dbfd2 100644 --- a/src/truststore/_openssl.py +++ b/src/truststore/_openssl.py @@ -3,6 +3,7 @@ import re import ssl import typing +import weakref # candidates based on https://github.com/tiran/certifi-system-store by Christian Heimes _CA_FILE_CANDIDATES = [ @@ -24,9 +25,15 @@ _HASHED_CERT_FILENAME_RE = re.compile(r"^[0-9a-fA-F]{8}\.[0-9]$") +_configured_contexts: weakref.WeakSet[ssl.SSLContext] = weakref.WeakSet() + @contextlib.contextmanager def _configure_context(ctx: ssl.SSLContext) -> typing.Iterator[None]: + if ctx in _configured_contexts: + yield + return + # First, check whether the default locations from OpenSSL # seem like they will give us a usable set of CA certs. # ssl.get_default_verify_paths already takes care of: @@ -54,6 +61,7 @@ def _configure_context(ctx: ssl.SSLContext) -> typing.Iterator[None]: ctx.load_verify_locations(cafile=cafile_or_cadir) break + _configured_contexts.add(ctx) yield