fix(ssl_guard): tolerate truststore SSLContext.get_ca_certs() NotImplementedError on Windows
On Windows, truststore.inject_into_ssl() replaces ssl.SSLContext with an OS-trust-store-backed context whose get_ca_certs() raises NotImplementedError (empty message). The ssl_guard's _validate_bundle_path() called get_ca_certs() unguarded, crashing every fresh agent init with an opaque 'Failed to initialize OpenAI client:' error. create_default_context(cafile=...) already validates that the bundle is parseable, so we skip the post-load introspection rather than treat the NotImplementedError as a failure. Cherry-picked from PR #49945 with comment trimmed. Co-authored-by: WolftacDigital <jonathan@wolftacdigital.com>
This commit is contained in:
+7
-1
@@ -55,7 +55,13 @@ def _validate_bundle_path(label: str, value: str, *, require_substantial: bool =
|
||||
ctx = ssl.create_default_context(cafile=str(path))
|
||||
except Exception as exc:
|
||||
raise _ssl_err(f"{label} CA bundle at {value} cannot be loaded: {exc}") from exc
|
||||
if not ctx.get_ca_certs():
|
||||
try:
|
||||
loaded_certs = ctx.get_ca_certs()
|
||||
except NotImplementedError:
|
||||
# truststore-backed SSLContext (Windows OS trust store) doesn't
|
||||
# implement get_ca_certs(); bundle was already validated above.
|
||||
return
|
||||
if not loaded_certs:
|
||||
raise _ssl_err(f"{label} CA bundle at {value} did not load any certificates")
|
||||
|
||||
|
||||
|
||||
@@ -19,8 +19,6 @@ def test_healthy_bundle_passes(monkeypatch):
|
||||
verify_ca_bundle()
|
||||
|
||||
|
||||
|
||||
|
||||
def test_empty_certifi_bundle_raises_ssl_error(monkeypatch, tmp_path):
|
||||
"""Empty file is treated as a corrupted bundle."""
|
||||
fake = tmp_path / "empty.pem"
|
||||
@@ -44,7 +42,33 @@ def test_missing_explicit_ca_bundle_env_raises_before_httpx(monkeypatch, tmp_pat
|
||||
assert "force-reinstall" in message
|
||||
|
||||
|
||||
def test_truststore_get_ca_certs_not_implemented_is_accepted(monkeypatch, tmp_path):
|
||||
"""A truststore-backed SSLContext (Windows OS trust store) raises
|
||||
NotImplementedError from get_ca_certs(). The guard must accept the
|
||||
already-loaded bundle rather than fail.
|
||||
|
||||
Regression for the empty-message ``Failed to initialize OpenAI client:``
|
||||
seen on every fresh agent init on Windows (str(NotImplementedError()) == "").
|
||||
"""
|
||||
from agent import ssl_guard
|
||||
|
||||
bundle = tmp_path / "bundle.pem"
|
||||
bundle.write_text(
|
||||
"-----BEGIN CERTIFICATE-----\nfake\n-----END CERTIFICATE-----\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
class _TruststoreLikeContext:
|
||||
def get_ca_certs(self, binary_form=False): # noqa: ARG002 - mirror ssl API
|
||||
raise NotImplementedError()
|
||||
|
||||
# create_default_context(cafile=...) loads the bundle fine; only the
|
||||
# post-load introspection is unsupported under truststore.
|
||||
monkeypatch.setattr(
|
||||
ssl_guard.ssl, "create_default_context", lambda *a, **k: _TruststoreLikeContext()
|
||||
)
|
||||
monkeypatch.setenv("SSL_CERT_FILE", str(bundle))
|
||||
|
||||
# Must not raise on the explicit env bundle nor the certifi check.
|
||||
verify_ca_bundle()
|
||||
verify_ca_bundle_with_fallback()
|
||||
|
||||
Reference in New Issue
Block a user