Give the frozen exporter a CA bundle when the system offers none - #209
Merged
Merged
Conversation
Sign-in succeeded and then the very next request, the mobileme login at setup.icloud.com, died with CERTIFICATE_VERIFY_FAILED on a minimal Linux desktop (#206). gsa.apple.com chains to the Apple root FindMy.py pins and carries, so it verifies with no trust store; setup.icloud.com presents an ordinary public certificate that needs the platform's CA bundle, and a PyInstaller build has none - its Python looks for one at the build machine's paths, absent on the user's. exporter.certs.ensure_ca_bundle points OpenSSL at certifi's bundled certificates through SSL_CERT_FILE, which is what the reporter set by hand as the workaround, and which ssl.create_default_context reads when FindMy.py builds its context. Both entry points call it before the first request. It only fills a gap: a user's own SSL_CERT_FILE and a machine whose default bundle exists are both left untouched, so from-source runs are unaffected. Closes #206. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes the Linux SSL failure in #206: sign-in works, then the mobileme login at
setup.icloud.comright after the 2FA code fails withCERTIFICATE_VERIFY_FAILED: unable to get local issuer certificate.Why only that one host
Every Apple request is TLS-verified by FindMy.py against the platform's trust store plus Apple's own pinned 2006 root, which the library carries.
gsa.apple.com(sign-in) chains to that pinned root, so it verifies with no system trust store at all.setup.icloud.com(the mobileme login) presents an ordinary public certificate — issued byApple Public Server ECC CA 1 - G1— that needs the platform's CA bundle like any website.A PyInstaller build carries no trust store, and its Python looks for one at the paths OpenSSL was compiled with on the build machine, which do not exist on the user's. So sign-in succeeded against the pinned root and the very next request died. The reporter confirmed
export SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crtfixed it.The fix
exporter.certs.ensure_ca_bundle()does that workaround portably: it pointsSSL_CERT_FILEatcertifi's bundled certificates (already a dependency), whichssl.create_default_context()reads when FindMy.py builds its context. Both entry points (cli.main,wizard.__main__) call it before the first request.It only fills a gap — it leaves a user's own
SSL_CERT_FILEand a machine with a working default bundle untouched — so from-source runs are unaffected.Verification
certifi's bundle verifiessetup.icloud.comfrom this machine (the failing host).python/test/test_certs.py, 4 tests: respects an existingSSL_CERT_FILE, leaves a working system store alone, fills the gap from certifi when the default is missing, and sets nothing when certifi is absent.Not touched: the app (Chaquopy on Android has a working system store — the app's failure in that thread is a 429, a separate problem).
🤖 Generated with Claude Code