The command-line build may differ from the application

The official OpenSSL download page records version 4.1.0 as released on 23 October 2026. The project roadmap gives different support horizons for different branches; not every release is an LTS release. Reviewed on 27 October, this tutorial explains how to identify the actual library in use and assess a dated support calendar. A release announcement alone does not establish that replacing a dependency in an existing service is appropriate.

The system command, Python interpreter, web service and a container can each use different builds. The inventory therefore records Python's linked library separately from the command-line result. Different answers are not automatically a configuration error. To evaluate another application, collect evidence from its actual process, package or container. An administrator's workstation inventory cannot prove which library is executing inside a separate production service or whether that service has loaded a recently installed package.

Separate support dates from vendor package status

The example policy records support dates for reviewed branches and stops trusting its assessment after a review deadline. Unrecognized builds and version formats are not guessed. Upstream support status also differs from a distribution's maintained packages and backported fixes. An operational package decision needs vendor advisories, the package revision and application compatibility as well as the upstream library number. Keep those separate evidence sources visible instead of treating a simple string comparison as a complete security decision.

Save the four files and run python -m unittest test_version.py. The tests cover an ended branch, an approaching deadline, a reviewed supported version, an unknown build and policy expiry. Run python inventory_ssl.py > ssl-inventory.json followed by python check_version.py ssl-inventory.json. If the openssl command is unavailable, its inventory field remains empty while Python's linked-library information is still reported. None of these commands installs or replaces the machine's libraries.

A lifecycle result is not a certificate-chain test or a comprehensive verification of every cryptographic setting an application uses. After selecting an upgrade route, exercise actual connections, hostname validation, native dependencies and the consuming library in isolation. Passing the dated branch policy does not establish that the newest patch is installed or that all service settings have been approved. Those acceptance conditions require evidence from the application's real communication paths.

Complete executable files

The four files are complete. The article provides prerequisites, command order and verification; code is neither shortened nor hidden.

1. Complete inventory_ssl.py

Save this entire file beside the others using the exact filename.

import json
import ssl
import subprocess


def inventory():
    result = {'pythonLibrary': ssl.OPENSSL_VERSION, 'commandLine': None}
    try:
        command = subprocess.run(['openssl', 'version'], check=True, capture_output=True, text=True, timeout=5)
        result['commandLine'] = command.stdout.strip()
    except (OSError, subprocess.SubprocessError):
        pass
    return result


if __name__ == '__main__': print(json.dumps(inventory()))

The execution section explains this file’s command, expected outcome and limits.

2. Complete support_policy.json

Save this entire file beside the others using the exact filename.

{
  "reviewed": "2026-10-27",
  "reviewBy": "2026-11-10",
  "source": "https://www.openssl-library.org/roadmap/",
  "branches": {
    "3.4": {"until": "2026-10-22", "type": "non-LTS"},
    "3.5": {"until": "2030-04-08", "type": "LTS"},
    "3.6": {"until": "2026-11-01", "type": "non-LTS"},
    "4.0": {"until": "2027-05-14", "type": "non-LTS"},
    "4.1": {"until": "2027-11-23", "type": "non-LTS"}
  }
}

The execution section explains this file’s command, expected outcome and limits.

3. Complete check_version.py

Save this entire file beside the others using the exact filename.

from datetime import date
import json
from pathlib import Path
import re
import sys


def assess(version, policy, today):
    if not date.fromisoformat(policy['reviewed']) <= today <= date.fromisoformat(policy['reviewBy']):
        return 'review-policy-date'
    match = re.match(r'^OpenSSL (\d+\.\d+)\.\d+(?:\s|$)', version or '')
    branch = policy['branches'].get(match[1]) if match else None
    if branch is None:
        return 'unknown-build-review-vendor'
    remaining = (date.fromisoformat(branch['until']) - today).days
    if remaining < 0: return 'upstream-support-ended-review-vendor'
    if remaining <= 30: return 'upstream-support-ending-plan-migration'
    return 'supported-branch-check-patches-and-application'


if __name__ == '__main__':
    data = json.loads(Path(sys.argv[1]).read_text(encoding='utf-8'))
    policy = json.loads(Path(__file__).with_name('support_policy.json').read_text())
    print(json.dumps({name: assess(version, policy, date.today()) for name, version in data.items()}))

The execution section explains this file’s command, expected outcome and limits.

4. Complete test_version.py

Save this entire file beside the others using the exact filename.

from datetime import date
import json
from pathlib import Path
import unittest
from check_version import assess


class OpenSSLTests(unittest.TestCase):
    def test_lifecycle_and_unknown_build(self):
        policy = json.loads(Path(__file__).with_name('support_policy.json').read_text())
        today = date(2026, 10, 27)
        self.assertIn('ended', assess('OpenSSL 3.4.8 29 Sep 2026', policy, today))
        self.assertIn('ending', assess('OpenSSL 3.6.5 29 Sep 2026', policy, today))
        self.assertIn('supported-branch', assess('OpenSSL 4.1.0 23 Oct 2026', policy, today))
        self.assertIn('unknown-build', assess('LibreSSL 4.0', policy, today))
        self.assertEqual(assess('OpenSSL 4.1.0', policy, date(2026, 11, 11)), 'review-policy-date')


if __name__ == '__main__': unittest.main()

The execution section explains this file’s command, expected outcome and limits.

Run inventory and boundary-condition tests

For deployment, obtain packages and verify checksums through the supported process for the actual environment. Define rollback criteria and whether the previous runtime can still operate before making a change. Revisit the official calendar when the policy expires, because support information can change. The useful outcome is a documented decision based on the real application and its package source, rather than an automatic upgrade triggered simply by discovering a larger upstream version number.

Implementation checklist

  • Inventory each actual service library.
  • Do not silently extend policy review dates.
  • Review distribution package advisories separately.
  • Exercise real connections after a change.

References

Editorial guidance: Liyan Knowledge.