Skip to content

Fix model downloads on machines with a broken system trust store - #181

Merged
chanshing merged 1 commit into
mainfrom
fix/windows-openssl-cert
Aug 4, 2026
Merged

Fix model downloads on machines with a broken system trust store#181
chanshing merged 1 commit into
mainfrom
fix/windows-openssl-cert

Conversation

@chanshing

Copy link
Copy Markdown
Member

Fix model downloads on machines with a broken system trust store (+ download hardening)

Problem

On Windows with recent OpenSSL (the CVE-2026-34180 ASN.1 change), constructing
Python's default HTTPS context can raise while loading the OS certificate store,
even with valid certificates:

ssl.SSLError: [ASN1: NOT_ENOUGH_DATA] not enough data

Because this happens inside ssl.create_default_context(), it breaks every
HTTPS download in the process — both the model files and the torch.hub fetch of
the ssl-wearables repo — so stepcount fails at "Loading model..." on a fresh
install. It is not specific to any one machine; it affects the OpenSSL builds
carrying that hardening.

Fix

When the default HTTPS context can't be built, fall back to certifi's CA bundle
for the process (which sidesteps the OS trust store), and harden the model
downloader while touching it.

setup.py

  • Add certifi>=2024.7.4 to install_requires. The floor clears CVE-2024-39689
    (removal of a distrusted CA); the upper bound is left open so the trust bundle
    stays current. Verified compatible across the supported Python range
    (>=3.8,<3.11) — every certifi release still supports 3.8.

src/stepcount/stepcount.py

  • On startup, if the default HTTPS context can't be built, switch the process to
    a certifi-backed context so downloads work. Gated: a no-op when the trust
    store is healthy, and it defers to a custom HTTPS hook already installed by
    an embedding application (e.g. a corporate CA bundle) instead of overwriting
    it. Because it patches the process-wide context factory, it covers both the
    model download and the torch.hub fetch.
  • Route both model-download sites through one shared atomic helper: download to a
    per-process temp file with a connection timeout, verify the checksum,
    then os.replace() into place, cleaning up on failure. This replaces the two
    duplicated blocks and fixes two latent issues — a stalled server could hang the
    process indefinitely (no timeout), and concurrent first-run/batch downloads
    shared one temp filename and could clobber each other.

tests/test_stepcount.py

  • TestDownloadToFile — the atomic download helper: timeout applied, temp
    cleanup on success and on failure, checksum mismatch raises without leaving a
    file, and an existing good file is preserved when a download fails mid-stream.
  • TestEnsureDownloadSSLContext — the HTTPS fallback: certifi bundle is used
    with verification preserved (check_hostname/verify_mode), a custom hook
    is respected, and it's a no-op when certifi is unavailable. Tests are
    host-independent (they don't depend on the CI machine's real trust store).

…download hardening

On Windows with recent OpenSSL (the CVE-2026-34180 ASN.1 change), constructing
the default HTTPS context can fail while loading the OS certificate store, which
breaks every model and torch.hub download. Add a gated fallback and harden the
downloader.

setup.py:
- Add certifi to install_requires (>=2024.7.4; floor clears CVE-2024-39689,
  upper left open to stay current).

src/stepcount/stepcount.py:
- When the default HTTPS context can't be built, switch this process to a
  certifi-backed context so downloads work. Gated: a no-op when the trust store
  is healthy, and it defers to a custom HTTPS hook already installed rather than
  overwriting it. Armed once at CLI startup.
- Route both model-download sites through a shared atomic helper: download to a
  per-process temp file with a connection timeout, verify the checksum, then
  replace in place, cleaning up on failure. A stalled server no longer hangs
  indefinitely and concurrent first-run downloads no longer clobber each other.

tests/test_stepcount.py:
- Cover the download helper (timeout applied, temp cleanup on success and
  failure, checksum mismatch, existing file preserved) and the HTTPS fallback
  (certifi bundle used with verification preserved, custom hook respected,
  no-op when certifi is absent); make the SSL tests host-independent.
@chanshing
chanshing merged commit c694d0c into main Aug 4, 2026
15 checks passed
@chanshing
chanshing deleted the fix/windows-openssl-cert branch August 4, 2026 16:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant