Skip to content

core: Find Python-bundled libcrypto on Windows - #319

Open
djdarcy wants to merge 1 commit into
petertodd:masterfrom
djdarcy:core-windows-bundled-libcrypto
Open

core: Find Python-bundled libcrypto on Windows#319
djdarcy wants to merge 1 commit into
petertodd:masterfrom
djdarcy:core-windows-bundled-libcrypto

Conversation

@djdarcy

@djdarcy djdarcy commented May 14, 2026

Copy link
Copy Markdown

Howdy @petertodd on Python 3.8+ Windows, ctypes.util.find_library() can't see Python's own DLLs/ directory because it's no longer on the default DLL search path. So even though Python ships libcrypto-3.dll in <sys.base_prefix>/DLLs/, every candidate in the existing chain ('ssl.35', 'ssl', 'libeay32', 'libcrypto' from #306) returns None, and _ssl = ctypes.cdll.LoadLibrary(None) raises TypeError: argument of type 'NoneType' is not iterable on import.

This set of changes adds a 4th fallback, as _find_bundled_libcrypto(), that checks sys.base_prefix/DLLs/ and sys.prefix/DLLs/ directly for any libcrypto-*.dll file. On a fresh Python 3.10+/3.11+/3.12+ Windows install where the bundled OpenSSL is the only one available, import should now work without requiring users to install OpenSSL system-wide.

FWIW: the BN_* / EC_* functions this module actually calls live in libcrypto, not libssl. On Linux/macOS libssl typically re-exports libcrypto symbols so loading libssl works; on Windows they are in separate DLLs, hence preferring libcrypto-*.dll.

No behavior change on Linux/macOS -- _find_bundled_libcrypto() returns None early when sys.platform != 'win32'.

Relates to #318, which takes a different approach (raises EnvironmentError when nothing is found). The two PRs should be complementary: this fix tries to actually find OpenSSL, and #318's EnvironmentError would be the right thing if even this fallback finds nothing. Happy to defer or combine in any order you prefer.

Closes #316.

Ran a basic test on Python 3.12 + Win11 with bitcoin/tests/test_key.py passing (1/1).

On Python 3.8+ Windows, ctypes.util.find_library() can't see Python's
own DLLs/ dir because it's no longer on the DLL search path. Fall back
to scanning sys.{base_,}prefix/DLLs for libcrypto-*.dll before
LoadLibrary(None) raises TypeError.

Layered on top of petertodd#306, which only works on systems that already have
libcrypto.dll in system32 from another package.

Closes petertodd#316.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant