#66

fix(providers): use a working CA bundle for urllib requests (#63)

Draftwizardengineerwants to merge intofrom

Setup Codex cannot complete on Binary Ninja, it fails with CERTIFICATE_VERIFY_FAILED. The bundled bnpython3 is a repackaged python.org build, and its OpenSSL is compiled with

OPENSSLDIR: "/Library/Frameworks/Python.framework/Versions/3.10/etc/openssl"

which does not exist unless python.org Python is installed separately. ssl.create_default_context() loads zero CA certificates, so every urllib HTTPS request fails:

$ bnpython3 probe.py
cafile: /Library/Frameworks/Python.framework/Versions/3.10/etc/openssl/cert.pem False
TLS FAIL: [SSL: CERTIFICATE_VERIFY_FAILED] ...

$ SSL_CERT_FILE=/etc/ssl/cert.pem bnpython3 probe.py
TLS OK

Providers on the OpenAI/Anthropic SDKs were never affected, httpx defaults to certifi. Only the urllib sites are. Closes #63.

Adds core/tls.py with one cached context, resolved in this order:

  • An explicitly set SSL_CERT_FILE or SSL_CERT_DIR is used as-is and never supplemented. If someone pins a narrow corporate bundle and the path is wrong, they get a failure rather than the public root set silently substituted underneath them.
  • The interpreter's own store, when it actually has CAs.
  • The certifi bundle, imported opportunistically so it stays a preference and not a new dependency.
  • A platform bundle such as /etc/ssl/cert.pem.

Verification is never disabled. Every path returns a context with check_hostname and CERT_REQUIRED intact, and when nothing is found the default context is returned unchanged so the request fails loudly instead of trusting an unverified peer.

Call sites:

  • All four urlopen calls in codex_provider, including the retry after a 401 refresh. Fixing only the first would have left every token refresh broken.
  • ollama_provider passes a context only for https. On plain http a context bypasses any opener the host installed and buys nothing, and the default base URL is http://localhost:11434.

The tests use a real PEM and the real loader for the repair path, so they assert the trust store actually gains CAs rather than that a mock was called.

Activity

1

This pull request is a draft

Merging is unavailable until it is marked ready for review.