OpenSSL began in December 1998 as a continuation of Eric Young's SSLeay library, when SSLeay 0.9.0b became OpenSSL 0.9.1c. It grew through the 0.9.x, 1.0.x and 1.1.x lines, was rebuilt around pluggable "providers" and relicensed under Apache 2.0 in 3.0 (September 2021), and released 4.0.0 on 14 April 2026, followed by 4.1.0 on 23 October 2026. Today the project ships a feature release every April and October, names a Long Term Support (LTS) release every two years with at least five years of support, and supports regular releases for 13 months. As of 25 October 2026 the publicly supported lines are 3.5 (LTS), 3.6, 4.0 and 4.1.
This post walks through every major line, what each one changed for security, how the support and disclosure policies work, and how to find every copy of OpenSSL on your hosts and in your images so you can map each one to a support status.
Key takeaways
- OpenSSL 0.9.1c (23 December 1998) was the first release under the OpenSSL name, built on SSLeay 0.9.0b, according to the project's own NEWS file.
- TLS 1.2 arrived in 1.0.1 (March 2012), TLS 1.3 in 1.1.1 (September 2018), QUIC in 3.2 and 3.5, the NIST post-quantum algorithms in 3.5 (April 2025), and Encrypted Client Hello in 4.0 (April 2026).
- 3.0 (7 September 2021) replaced engines with providers, moved old algorithms such as MD4 and RC4 into a legacy provider that is not loaded by default, and changed the licence to Apache 2.0, which broke many applications.
- 4.0 removed SSLv3, the SSLv2 compatible Client Hello and the ENGINE API entirely, and disabled deprecated TLS elliptic curves and explicit curves at compile time by default.
- The release strategy page (last modified 7 May 2026) lists 3.5 as LTS until 8 April 2030, 3.6 until 1 November 2026, 4.0 until 14 May 2027, and 3.4 as supported until 22 October 2026. The downloads page lists 4.1 with an end of life of November 2027. 3.0, 1.1.1 and 1.0.2 are out of public support; paid extended support exists for them.
- Security issues are rated Critical, High, Moderate or Low. The project announces the date and severity of a security release about one week ahead, and pre-notifies operating system distributions with details about two weeks ahead for Critical, High and Moderate issues.
- Distribution version strings hide backported fixes, and statically linked or vendored copies in runtimes, wheels and containers are the ones most often missed.
How did OpenSSL start?
OpenSSL did not start from scratch. Its NEWS file, which records major changes between releases, opens its history with an entry titled "Major changes between SSLeay 0.9.0b and OpenSSL 0.9.1c", dated 23 December 1998. SSLeay was a free implementation of SSL and general purpose cryptography written by Eric Young, with contributions from Tim Hudson; the pre-3.0 licence text still carries Eric Young's 1995 to 1998 copyright and the attribution lines for both authors. A group of developers continued that code base under the OpenSSL name, and the same licence file carries a separate copyright line for The OpenSSL Project starting in 1998.
The first OpenSSL release integrated community patches for building without RSA or DSA, added initial compression in the SSL record layer, BIO filters, an extended big number library and RIPEMD-160. Four more releases followed within eighteen months, ending with 0.9.5 on 25 May 2000.
The licence was a dual licence: the OpenSSL License plus the original SSLeay License, both BSD style and both with clauses that require an acknowledgement line in advertising material for products that use the code. The project's licence page confirms that this dual licence still applies to every release before 3.0, including 1.1.1, 1.1.0 and 1.0.2, and to any letter release of those lines no matter when it is made. Everything from 3.0 onward, and the master branch, is under the Apache License 2.0.
How did funding and governance change after 2014?
For most of its first fifteen years, OpenSSL was maintained by a very small group of people. The OpenSSL Foundation's own history page describes the library in early 2014 as still "being maintained by just a few developers" despite exponential growth in use. The April 2014 disclosure of a memory disclosure bug in the TLS heartbeat extension (the extension had shipped in 1.0.1 in 2012) made the funding gap public. The project's vulnerabilities page records that advisory on 7 April 2014. This post does not retell that incident; the point for this history is what changed afterwards.
Three things changed in the years that followed:
- A foundation. The OpenSSL Foundation's history page dates its founding to 2014 and calls that year's events the impetus for creating it, because the world had realised how much infrastructure relied on a handful of people "with almost no funding support".
- A written process. The release strategy page that governs today's support windows was "first issued 23 December 2014", according to its own header. Its security policy and its severity levels, described below, are the other half of that written process.
- A mission and a two entity structure. The same history page records the project team establishing a written OpenSSL Mission in 2023, and the Foundation being re-launched in 2024 "as an independent entity with its own staff and programs", so that it could focus only on its non profit mission. Today the project describes itself as funded "through the OpenSSL Corporation and the OpenSSL Foundation." The Foundation is a non profit that supports the project's public good work and takes donations and sponsorships; the Corporation sells support contracts, sponsored development, FIPS related services and Extended LTS for releases that are past public end of life. The security policy says the Security Response Team is designated by the directors of both the Foundation and the Corporation and includes committers who choose to take part.
The practical effect for users is that the support model now has two tiers. The public tier is the release strategy described below. The paid tier, Extended LTS, gives organisations that cannot move off 1.1.1, 1.0.2 or older 3.x lines continued security fixes while they plan an upgrade.
OpenSSL release timeline: every major line and what it changed
The dates below are the release dates of each line's first release, taken from the NEWS file in the OpenSSL repository and the project's release and advisory timeline. The feature notes come from the same NEWS entries.
| Line | First release | Security relevant changes |
|---|---|---|
| 0.9.1c | 23 Dec 1998 | First OpenSSL release, continuing SSLeay 0.9.0b; RIPEMD-160, BIO filters, SSL record compression |
| 0.9.6 | 10 Oct 2000 | Maintenance line of the early SSLv3 and TLS 1.0 era |
| 0.9.7 | 30 Dec 2002 | New OCSP library, rewritten ASN.1 code, CRL checking in verify, AES, a new elliptic curve library, ENGINE support merged into the main distribution |
| 0.9.8 | 5 Jul 2005 | ECDH and ECDSA through EVP, X.509 and ENGINE; audited and reworked BIGNUM library |
| 1.0.0 | 29 Mar 2010 | RFC 3280 path validation, PKCS#8 as the default private key format, full CMS support, PSK cipher suites, SHA-2 based ECDSA and DSA signatures |
| 1.0.1 | 14 Mar 2012 | TLS 1.1 and TLS 1.2, TLS and DTLS heartbeat, SRP, Next Protocol Negotiation, RSA-PSS in certificates, SCTP |
| 1.0.2 | 22 Jan 2015 | DTLS 1.2, ALPN, Suite B for TLS 1.2, the SSL_CONF configuration API, automatic EC curve selection |
| 1.1.0 | 25 Aug 2016 | Most public structures made opaque, SSLv2 removed, RC4 removed from DEFAULT, 40 and 56 bit ciphers removed, ChaCha20-Poly1305, X25519, security levels, extended master secret, Certificate Transparency, DANE |
| 1.1.1 | 11 Sep 2018 | TLS 1.3 (RFC 8446) on by default, new DRBG based on NIST SP 800-90Ar1, SHA-3, Ed25519 and Ed448, X448, side channel hardening |
| 3.0 | 7 Sep 2021 | Providers, library contexts, legacy and FIPS providers, Apache 2.0 licence, kernel TLS, CMP, SHA-1 signed certificates rejected at security level 1, ENGINE and low level APIs deprecated |
| 3.1 | 14 Mar 2023 | FIPS 140-3 compliance changes, performance work |
| 3.2 | 23 Nov 2023 | Client side QUIC, default security level raised from 1 to 2, Argon2, HPKE, raw public keys, certificate compression, pluggable TLS 1.3 signature algorithms |
| 3.3 | 9 Apr 2024 | QUIC qlog tracing and polling, Y2038 safe session time APIs |
| 3.4 | 22 Oct 2024 | FIPS indicators, optional jitter entropy seed source, PBMAC1 for PKCS#12, attribute certificates |
| 3.5 (LTS) | 8 Apr 2025 | Server side QUIC, ML-KEM, ML-DSA and SLH-DSA, hybrid post-quantum key shares preferred by default, AES-256-CBC as default for req, cms and smime |
| 3.6 | 1 Oct 2025 | LMS signature verification, deterministic ECDSA in the FIPS provider, C99 compiler required |
| 4.0 | 14 Apr 2026 | Encrypted Client Hello, SSLv3 and ENGINE removed, deprecated TLS curves and explicit curves off by default, stricter certificate and CRL checks |
| 4.1 | 23 Oct 2026 | DTLS 1.3 (RFC 9147), GREASE (RFC 8701), DTLS listener API |
The 0.9.x era: 1998 to 2010
The 0.9.x releases ran for more than a decade, a long time for a series that never claimed a 1.0. In those years OpenSSL became the default TLS and crypto library on most Unix like systems.
0.9.7 (December 2002) added an OCSP library for online revocation checks, CRL checking in certificate verification, AES, and brought the ENGINE framework for hardware accelerators and HSMs into the main distribution.
0.9.8 (July 2005) is the release most people remember, mainly for how long it lived. It added elliptic curve Diffie-Hellman and ECDSA, which later became the backbone of forward secret TLS. It also included a major audit and rework of the BIGNUM library, the arithmetic code under RSA, DH and DSA. The NEWS file shows 0.9.8n on 24 March 2010, five days before 1.0.0.
The 1.0.x era: TLS 1.2 arrives
1.0.0 (29 March 2010) was mostly about public key infrastructure: path validation rewritten to pass the PKITS test suite, PKCS#8 as the default private key format, full CMS support and RFC 3161 time stamps.
1.0.1 (14 March 2012) is the line where TLS 1.1 and TLS 1.2 landed. TLS 1.2 brought authenticated encryption suites such as AES-GCM and SHA-256 based handshake integrity, and became the floor for most compliance regimes. 1.0.1 also introduced the TLS and DTLS heartbeat extension, SRP and Next Protocol Negotiation.
1.0.2 (22 January 2015) added ALPN, the extension that HTTP/2 uses to negotiate its protocol, along with DTLS 1.2, Suite B profiles for TLS 1.2 and an API for setting supported signature algorithms and curves. It was the last release before the big structural cleanup. Because so much code was written against its open structures, 1.0.2 stayed in production long after its public end of life, and it still appears today in old appliances and in software that vendors stopped updating.
The 1.1.x era: opaque structures and TLS 1.3
1.1.0 (25 August 2016) was the first release in years that deliberately broke source compatibility. The NEWS file lists the reason in one line: most libcrypto and libssl public structures were made opaque, including RSA, DSA, DH, EC_KEY, BIGNUM, EVP_MD_CTX, EVP_CIPHER_CTX, HMAC_CTX and X509. Code that reached into those structures with rsa->n or similar had to switch to accessor functions. The pain was real, but it gave the maintainers room to change internals without breaking every caller, which made later security fixes and the 3.0 rewrite possible.
1.1.0 also made several security defaults stricter:
- SSLv2 support was removed entirely.
- RC4 was removed from the DEFAULT cipher list, and 40 and 56 bit "export" ciphers were removed from libssl.
- Security levels were introduced, so one setting could forbid small keys, weak digests and old protocol versions together.
- ChaCha20-Poly1305 and X25519 arrived, giving a fast, constant time option for devices without AES hardware.
The NEWS entry for 4.0 confirms that SSLv3 was also "disabled by default since version 1.1.0 (2016)", though the code stayed in the tree until 4.0.
1.1.1 (11 September 2018) was the TLS 1.3 release, and it became the line most of the world ran for the next five years. The NEWS entry describes a "fully compliant implementation of RFC8446 (TLSv1.3) on by default", including early data (0-RTT), post-handshake key update and middlebox compatibility mode. It also rewrote the random number generator around an AES-CTR DRBG following NIST SP 800-90Ar1, with fork safe per thread instances, and added SHA-3, Ed25519, Ed448 and X448.
What did OpenSSL 3.0 change, and why did it break applications?
OpenSSL 3.0.0 shipped on 7 September 2021. The version number jumped from 1.1.1 to 3.0 because, as the NEWS file says, the project "changed our version number scheme and set the next major release to 3.0.0". The NEWS file does not say why 2.x was skipped. The 3.0 design document does refer to the earlier "FIPS Module 2.0.0", the separately validated FIPS module used with the 1.0.x libraries, so a 2.0 version number already meant something in the OpenSSL world.
Providers replace engines
The core idea of the 3.0 design is the provider. A provider is a unit of code that offers implementations of algorithms (digests, ciphers, key exchanges, signatures, KDFs, encoders and decoders) to the rest of the library. Applications ask for an algorithm by name and an optional property query, and the library fetches an implementation from whichever loaded provider offers it. The 3.0 release shipped these providers:
| Provider | Loaded by default | What it contains |
|---|---|---|
| default | Yes, if no other provider is configured | Modern algorithms used by most applications |
| base | No | Encoders and decoders only, for use alongside the FIPS provider |
| fips | No | The algorithms inside the FIPS 140 module boundary, with self tests |
| legacy | No | Algorithms the documentation calls "the retirement home of cryptographic algorithms": MD2, MD4, MDC2, Whirlpool, RIPEMD-160, Blowfish, CAST, single DES and DESX modes, IDEA, RC2, RC4, RC5 (off by default even here), SEED and PBKDF1 |
| null | No | Nothing; used to stop the default provider loading automatically |
A library context (OSSL_LIB_CTX) holds a set of loaded providers and configuration. Most applications use the default context without knowing it; libraries and frameworks that need FIPS behaviour in one part of a process and normal behaviour in another can create separate contexts.
The ENGINE API, which had been the way to plug in hardware since 0.9.7, was deprecated in 3.0 and removed in 4.0.
Why upgrades broke
Most of the breakage from 1.1.1 to 3.0 came from four places:
- Algorithms moved to the legacy provider. An application that read an old PKCS#12 file encrypted with RC2 or 3DES, or hashed with MD4 for an NTLM style protocol, or used RIPEMD-160, suddenly got "unsupported" errors. The fix was to load the legacy provider in the specific place that needs it, not to load it everywhere.
- Deprecated low level APIs. 3.0 deprecated the low level digest, cipher, RSA, DSA, DH and EC functions in favour of the EVP interfaces. Deprecation warnings became build failures in projects that compile with warnings as errors.
- Stricter defaults. SHA-1 signed certificates were no longer accepted at security level 1, which was the default, and SSL 3, TLS 1.0, TLS 1.1 and DTLS 1.0 only worked at security level 0 in most configurations. Old internal certificate authorities and old embedded peers stopped connecting.
- API behaviour. The RAND_DRBG API was removed and key handling moved to
EVP_PKEY, which the official migration guide covers in detail.
The Apache 2.0 licence
The 3.0 NEWS entry includes a one line change with long consequences: "Changed the license to the Apache License v2.0." The downloads page confirms that "since 3.0, the OpenSSL Library has been released under an Apache License v2." It removed the advertising acknowledgement clauses for new releases. For SBOMs it means one package name now carries two different licence identifiers depending on the version, which licence policy checks have to handle correctly: OpenSSL and SSLeay for 1.1.1 and earlier, Apache-2.0 for 3.0 and later.
The 3.x era: QUIC, FIPS 140-3 and post-quantum cryptography
The 3.x line moved to a time based schedule, with a minor release roughly every six months. The timeline table above lists each one; these are the changes with the biggest effect on defaults.
- 3.1 (14 March 2023) carried the code changes needed for FIPS 140-3 validation of the FIPS provider.
- 3.2 (23 November 2023) raised the default security level from 1 to 2. The security level manual page defines level 2 as 112 bits of security: RSA, DSA and DH keys shorter than 2048 bits and ECC keys shorter than 224 bits are prohibited, any cipher suite using RC4 is prohibited, and compression is disabled. It also added client side QUIC, HPKE (RFC 9180), Argon2 and "provider-based pluggable signature algorithms in TLS 1.3", the hook that later post-quantum signatures use.
- 3.4 (22 October 2024) added FIPS indicators, which let an application ask whether an operation was FIPS approved, and marked X25519 and X448 in the FIPS provider as unapproved.
- 3.5 (8 April 2025) is the current LTS and the release where post-quantum cryptography became a default. Its NEWS entry lists ML-KEM, ML-DSA and SLH-DSA, a default groups list that prefers hybrid post-quantum groups, and default key shares of X25519MLKEM768 and X25519. It also added server side QUIC. For the developer view, see OpenSSL 3.5 post-quantum: what developers get.
- 3.6 (1 October 2025) added LMS signature verification (NIST SP 800-208) and FIPS 186-5 deterministic ECDSA in the FIPS provider, and now requires a C99 compiler.
What changed in OpenSSL 4.0?
OpenSSL 4.0.0 was released on 14 April 2026. It is a major release, so the release strategy allows it to break API and ABI compatibility with 3.x. Most of the breaks are removals of things that had been deprecated for years.
Removed protocols and features
- SSLv3 support was removed. The NEWS file notes SSLv3 had been deprecated since 2015 and disabled by default since 1.1.0.
- Support for the SSLv2 compatible Client Hello was removed.
- The ENGINE API was removed. The
no-enginebuild option andOPENSSL_NO_ENGINEmacro are now always present. - Custom
EVP_CIPHER,EVP_MD,EVP_PKEYandEVP_PKEY_ASN1methods were removed; providers are the only extension mechanism. - The fixed version method functions (the ones that pin a connection to one protocol version) were removed.
- The
c_rehashscript was removed in favour ofopenssl rehash.
New secure defaults
- Deprecated elliptic curves for TLS (RFC 8422) are disabled at compile time by default, with an
enable-tls-deprecated-ecoption to bring them back. - Explicit EC curve parameters are disabled at compile time by default, with
enable-ec_explicit_curvesto re-enable them. - Authority Key Identifier checks are enforced when
X509_V_FLAG_X509_STRICTis set, and CRL verification gained several additional checks. - With the FIPS provider,
PKCS5_PBKDF2_HMACnow enforces lower bounds.
New features
- Encrypted Client Hello (ECH, RFC 9849), which hides the server name and other sensitive Client Hello fields from network observers.
- Negotiated FFDHE groups for TLS 1.2 (RFC 7919).
- cSHAKE (NIST SP 800-185) and an ML-DSA-MU digest.
- Deferred FIPS self tests, via
openssl fipsinstall -defer_tests.
Behaviour changes that catch people
OPENSSL_cleanup()now runs in a global destructor, or not at all, and libcrypto no longer frees global data throughatexit(). Tools that report memory leaks at exit may change their output.ASN1_STRINGbecame opaque and many X.509 function signatures gainedconst, which breaks strict C++ builds. Hex dump widths of keys and signatures also changed, which breaks scripts that scrape-textoutput.
What did 4.1 add?
OpenSSL 4.1.0 was released on 23 October 2026, according to the project's timeline and downloads page. Its NEWS entry lists DTLS 1.3 (RFC 9147), GREASE (RFC 8701), DTLS support in the SSL listener API and faster ML-KEM and ML-DSA on more platforms. It ships with several known DTLS 1.3 issues listed in the NEWS file, so read that list before deploying DTLS 1.3.
How does the OpenSSL release and support policy work today?
The release strategy page is the authority here. Its rules, as of its last modification on 7 May 2026:
- Versioning. From 3.0, versions use MAJOR.MINOR.PATCH. API and ABI compatibility is guaranteed within the same major number. Minor releases add features compatibly; patch releases fix bugs, and may backport accessor functions. The page says this "approximately aligns" with semantic versioning but is not strict semver.
- Cadence. A new release every six months, in April and October.
- LTS. Starting with 3.5, an LTS release every two years, supported for at least five years. In the final year an LTS gets security fixes only. The page states that an LTS will be released every April in odd numbered years, so there are always two fully supported LTS releases.
- Regular releases. Non-LTS releases up to 3.4 were supported for at least two years. Non-LTS releases after 3.5 are fully supported for 13 months. At least the two latest releases are always fully supported.
- Major releases. Starting with 5.0 in October 2027, a major release every two years, six months after each LTS, to give dependent projects time to adapt before the previous LTS ends.
- Stability. No public interface can be removed until its replacement has been in an LTS stable release and the original has been documented as deprecated for at least five years.
The current support windows from that page and the downloads page:
| Line | Status on 25 Oct 2026 | Supported until |
|---|---|---|
| 4.1 | Supported | November 2027 (downloads page) |
| 4.0 | Supported | 14 May 2027 |
| 3.6 | Supported | 1 November 2026 |
| 3.5 (LTS) | Supported | 8 April 2030 |
| 3.4 | Ended | 22 October 2026 |
| 3.0, 1.1.1, 1.0.2 | No public support; paid Extended LTS available | Ended |
| 1.1.0, 1.0.1, 1.0.0, 0.9.8 | No support | Ended |
Two observations. First, the release strategy page has not yet been updated to list 4.1, so its LTS sentence ("always two fully supported LTS releases") does not describe today: with 3.0 out of public support, 3.5 is the only LTS until the next April LTS. Second, the 13 month window means anyone who adopts a regular release is signing up for a yearly upgrade. If you want to upgrade every few years, pick the LTS. For the dates and migration steps for the lines ending this autumn, see OpenSSL 3.4 and 3.6 end of life.
Line by line: release, end of support, licence and defaults
| Line | Released | End of public support | Licence | Notable defaults |
|---|---|---|---|---|
| 0.9.8 | 5 Jul 2005 | Ended | OpenSSL and SSLeay | SSLv2 still compiled in |
| 1.0.0 | 29 Mar 2010 | Ended | OpenSSL and SSLeay | PKCS#8 key format |
| 1.0.1 | 14 Mar 2012 | Ended | OpenSSL and SSLeay | TLS 1.2 available, heartbeat on |
| 1.0.2 | 22 Jan 2015 | Ended (Extended LTS paid) | OpenSSL and SSLeay | ALPN, DTLS 1.2 |
| 1.1.0 | 25 Aug 2016 | Ended | OpenSSL and SSLeay | SSLv3 off, RC4 out of DEFAULT, security level 1 |
| 1.1.1 | 11 Sep 2018 | Ended (Extended LTS paid) | OpenSSL and SSLeay | TLS 1.3 on |
| 3.0 | 7 Sep 2021 | Ended (Extended LTS paid) | Apache 2.0 | Providers, legacy not loaded, SHA-1 certs rejected |
| 3.2 | 23 Nov 2023 | Ended | Apache 2.0 | Security level 2 |
| 3.4 | 22 Oct 2024 | 22 Oct 2026 | Apache 2.0 | FIPS indicators |
| 3.5 (LTS) | 8 Apr 2025 | 8 Apr 2030 | Apache 2.0 | X25519MLKEM768 and X25519 key shares |
| 3.6 | 1 Oct 2025 | 1 Nov 2026 | Apache 2.0 | C99 required |
| 4.0 | 14 Apr 2026 | 14 May 2027 | Apache 2.0 | No SSLv3, no engines, deprecated curves off |
| 4.1 | 23 Oct 2026 | Nov 2027 | Apache 2.0 | DTLS 1.3 available |
How does OpenSSL handle security issues?
The security policy defines four severity levels. In summary:
| Severity | What it covers | How it is released |
|---|---|---|
| Critical | Common configurations, likely exploitable: significant server memory disclosure, easy remote private key compromise, likely remote code execution | Kept private; triggers a new release of all supported versions as soon as possible |
| High | Lower risk than critical: less common configurations, client only, or less likely to be exploited | Kept private; new release of all supported versions; aim to keep it private no longer than a month where the project controls timing |
| Moderate | Denial of service only, flaws in less used protocols such as CMP, local flaws | Generally kept private until the next release, which may roll up several such issues |
| Low | Command line tool only, client side or less common protocol denial of service, or multiple unlikely conditions | Handled like Moderate; may be fixed in public before a release |
The pre-notification rules are what most operators feel. When a security release is planned, the project posts the date, time and highest severity to the openssl-announce list, usually one week before. For Critical, High and Moderate issues it also pre-notifies certain organisations with details and patches, usually two weeks before, including vendors of general purpose operating systems on the distributions security contact list and large derived projects with reciprocal arrangements.
The policy also publishes a threat model. Same system side channels, CPU and hardware flaws, physical fault injection and observation, denial of service against the command line tool, and API misuse by applications are out of scope: the project may still ship mitigations, but will not issue CVEs for them. Keep that in mind when you compare old scanner findings with new ones.
The policy states one principle that every operator should keep in mind: many sites run a version of OpenSSL they got from a vendor, usually bundled with an operating system, and "the most effective way for these sites to get protected is to get an updated version from that vendor." That is the bridge to the next section.
All advisories are listed on the vulnerabilities page and summarised on the release and advisory timeline. For example, the timeline shows one advisory on 29 September 2026 published alongside 4.0.3, 3.6.5, 3.5.9 and 3.4.8, and another on 25 August 2026 published alongside 4.0.2, 3.6.4, 3.5.8, 3.4.7 and 3.0.22. For FIPS users, the project also keeps a page that maps CVEs to their impact on each validated FIPS provider.
What does FIPS validation actually cover?
The downloads page lists the OpenSSL FIPS provider versions that hold NIST validations: 3.1.2 under FIPS 140-3, and 3.0.9, 3.0.8 and 3.0.0 under FIPS 140-2. It adds a rule that is often misread: other OpenSSL releases "MAY use the validated FIPS provider, but MUST NOT build and use their own FIPS provider." The example it gives is building OpenSSL 3.4 and using the 3.0.9 FIPS provider with it.
In other words, the validation covers a specific FIPS provider module built from a specific source release following the build instructions in that module's security policy. It does not cover the libssl that does the TLS handshake, the command line tool, or a FIPS provider you compiled from a newer tree.
The NIST certificates also have their own lifecycle. CMVP certificate 4282, for the "OpenSSL FIPS Provider" under FIPS 140-2 with software versions 3.0.8 and 3.0.9, now carries the status Historical, "due to sunsetting", and the certificate page says the module "should not be included by Federal Agencies in new procurements." Teams with a federal requirement should check the certificate status, not just the presence of a FIPS provider, and look at the FIPS 140-3 validated 3.1.2 provider listed on the downloads page for new work. The certificate also lists the exact operating environments that were tested, which is worth comparing with your own.
How do distributions and language runtimes bundle OpenSSL?
There are two very different ways OpenSSL ends up on a machine, and they behave very differently when a fix ships.
The system library. Linux distributions and BSDs ship OpenSSL as shared libraries (libssl and libcrypto) that most packages link against dynamically. When the distribution ships a fixed package and you install it and restart the affected services, every dynamically linked consumer picks up the fix. Distributions usually backport fixes into the version they released with rather than moving to a new upstream release. Debian's security FAQ explains this directly: instead of upgrading to a new release, it backports security fixes to the version shipped in the stable release, so that a security update changes as little as possible. The result is that a distribution package can report an upstream version that looks years old while carrying current fixes.
Bundled or vendored copies. Many runtimes and packages carry their own OpenSSL:
- Python. CPython's
sslmodule wraps OpenSSL. On Linux it usually links the system OpenSSL. PEP 644, which made OpenSSL 1.1.1 the minimum for Python 3.10, notes that the python.org installer and alternative distributions ship with their own recent OpenSSL on macOS and Windows. Thessldocumentation describesssl.OPENSSL_VERSIONas the version string of the OpenSSL library loaded by the interpreter, which is the one you care about. Packages with native code can carry their own copy too: the documentation for the widely usedcryptographypackage says its Windows and macOS wheels are statically linked builds that include their dependencies. - Node.js. The Node.js build guide says that by default "all dependencies are bundled into the Node.js binary itself", OpenSSL included, so the
opensslvalue inprocess.versionsdescribes the copy compiled into thenodebinary, not the system library. Some distributions build Node.js against shared system libraries instead, using configure options for shared dependencies. The same guide notes that Node.js supports FIPS through the OpenSSL 3 provider model whether OpenSSL is linked statically or dynamically. - Containers. Every image carries the OpenSSL of its base image, frozen at build time. A host patch does nothing for a container until the image is rebuilt on a fixed base and redeployed.
- Static binaries and appliances. Anything built with static linking against OpenSSL embeds its own copy, and that copy never changes when the host updates. Network appliances, VPN clients and device firmware often ship an old copy that only the vendor can update.
Why this matters for SBOMs
An SBOM is only useful for OpenSSL if it records each copy where it actually lives. That means the system package in the base image, the copy statically linked into the Node.js binary, the copy inside a Python wheel and the copy in a vendored C library. A good SBOM records:
- the package name and the exact version or distribution release string (for example a distribution package version with its revision, not just the upstream version);
- the supplier, so you can tell a distribution build from an upstream build or a runtime's bundled copy;
- the licence, which changes from the OpenSSL and SSLeay licences to Apache-2.0 at 3.0;
- the relationship, so you know which binary or image contains it.
Vulnerability matching against SBOMs needs care here. A distribution package version will often look vulnerable by upstream version number while the distribution's own advisory says it is fixed. Use the distribution's security tracker or advisory data for system packages, and upstream data for bundled copies.
Step by step: find every OpenSSL copy and plan upgrades
The steps below are read only. They find copies and versions; none of them changes a system.
1. Check the command line tool and the library it uses
openssl version -a
This prints the version, build date, platform, compiler flags, OPENSSLDIR and MODULESDIR. On 3.0 and later, check which providers are active:
openssl list -providers
If you see the legacy provider listed as active on a general purpose host, find out why (see Common mistakes).
2. Query the package manager
# Debian and Ubuntu
dpkg -l | grep -E 'libssl|openssl'
apt-cache policy openssl libssl3
# RHEL, Fedora, Rocky, Alma
rpm -qa | grep -i openssl
rpm -q --changelog openssl | head -40
# Alpine
apk info -vv | grep -i -E 'openssl|libssl|libcrypto'
The changelog query on RPM systems shows which fixes the distribution backported. Debian and Ubuntu publish the same information in their security trackers and changelogs.
3. Find which processes and binaries link libssl
# Binaries that dynamically link libssl
ldd /usr/sbin/nginx | grep -E 'libssl|libcrypto'
# Running processes that have libssl mapped
sudo grep -l -E 'libssl|libcrypto' /proc/[0-9]*/maps 2>/dev/null | cut -d/ -f3 | sort -u
After a library update, a process that still maps the old, deleted library file has not been restarted:
sudo grep -E '(libssl|libcrypto).*\(deleted\)' /proc/[0-9]*/maps 2>/dev/null
4. Find bundled and statically linked copies
# Language runtimes
python3 -c "import ssl; print(ssl.OPENSSL_VERSION)"
node -p "process.versions.openssl"
# Shared objects shipped inside application trees, wheels and node_modules
find / -xdev \( -name 'libssl*.so*' -o -name 'libcrypto*.so*' \) 2>/dev/null
# Static copies leave version strings in the binary
strings -a /path/to/binary | grep -E '^OpenSSL [0-9]+\.[0-9]+\.[0-9]+'
The strings check is a heuristic. It finds embedded version strings, which is usually enough to flag a binary for a closer look.
5. Check container images
# Inspect the OpenSSL packages in an image without running your app
docker run --rm --entrypoint sh your-image:tag -c \
'openssl version 2>/dev/null; (dpkg -l 2>/dev/null || rpm -qa 2>/dev/null || apk info -vv 2>/dev/null) | grep -i -E "openssl|libssl|libcrypto"'
Distroless and scratch images have no shell or package manager, so use an SBOM instead. With Safeguard's CLI, the same scan covers a directory, an image or an existing SBOM file, and writes results as JSON under ./output:
safeguard scan --dir .
safeguard scan --image your-registry/your-image:tag
safeguard scan --sbom ./sbom.cdx.json
6. Search your SBOMs
If you already produce CycloneDX or SPDX documents, search them for every OpenSSL component:
# CycloneDX JSON
jq -r '.components[] | select(.name | test("openssl|libssl|libcrypto"; "i")) | "\(.name) \(.version) \(.purl // "")"' sbom.cdx.json
# SPDX JSON
jq -r '.packages[] | select(.name | test("openssl|libssl|libcrypto"; "i")) | "\(.name) \(.versionInfo)"' sbom.spdx.json
7. Map each copy to a support status and plan
| What you found | Status source | Action |
|---|---|---|
| Distribution package (libssl3, openssl-libs) | Distribution's lifecycle and security tracker | Stay on the distribution's patched package; plan the OS upgrade before the distribution's own end of life |
| Upstream 3.5.x | OpenSSL release strategy: LTS until 8 Apr 2030 | Keep on the latest 3.5 patch release |
| Upstream 3.4.x or 3.6.x | Ended 22 Oct 2026, or ends 1 Nov 2026 | Move to 3.5 LTS or 4.x |
| Upstream 4.0.x | Supported until 14 May 2027 | Plan the move to 4.1 or the next LTS |
| Upstream 3.0, 1.1.1, 1.0.2 or older | No public support | Upgrade, or buy Extended LTS while you migrate |
| Bundled in Node.js or Python | The runtime's release notes | Upgrade the runtime, not the system library |
| Inside a vendor appliance | The vendor | Ask the vendor for its OpenSSL version and support plan |
8. Test before you move to 3.x or 4.x
Run openssl s_client against your internal peers with -tls1_2 and -tls1_3 to see whether they still negotiate at the new security level, and open old PKCS#12 files with openssl pkcs12 -info -noout. If a file only opens with the -legacy option, re-export it with modern algorithms rather than enabling the legacy provider for the whole system.
Common mistakes
- Trusting the version string on distribution packages. A distribution's OpenSSL may report an upstream version that is long out of upstream support while carrying every relevant fix. Read the distribution's advisories before you declare a host vulnerable, and before you declare it safe.
- Missing statically linked and bundled copies. Patching
libsslon the host does nothing for Node.js, which links its own OpenSSL, for wheels that bundle one, for containers built before the fix, or for single file binaries. - Not restarting services. A process keeps the old library mapped until it restarts. Check for deleted library mappings after updates.
- Enabling the legacy provider globally. Adding the legacy provider to the system
openssl.cnfmakes MD4, RC4, single DES and friends available to every application on the host. Load it only in the process or library context that needs it, and plan to retire the data or protocol that needs it. - Assuming FIPS validation covers every build. Only the specific validated FIPS provider module, built as its security policy says, is covered. A FIPS provider you compiled yourself from a newer tree is not validated, and the TLS library around it is never part of the module boundary.
- Picking a regular release for a long lived product. Regular releases from 3.6 onward get 13 months of full support. Firmware and appliances that ship for years should use the LTS line.
- Parsing human readable output. 4.0 changed hex dump widths and removed the extra leading
00:on large moduli. Scripts that scrapeopenssl x509 -textshould use machine readable options instead.
FAQ
When was OpenSSL first released?
The first release under the OpenSSL name was 0.9.1c on 23 December 1998, built from SSLeay 0.9.0b, according to the project's NEWS file.
Is OpenSSL 4.0 released?
Yes. OpenSSL 4.0.0 was released on 14 April 2026, and the latest 4.0 patch release on the downloads page is 4.0.3 from 29 September 2026. OpenSSL 4.1.0 followed on 23 October 2026.
What is the current OpenSSL LTS version?
3.5 is the current LTS. The release strategy page lists it as supported until 8 April 2030. 3.0 is no longer publicly supported.
Why did OpenSSL skip version 2.0?
The project changed its numbering in 3.0 and set the next major release to 3.0.0. The 2.0 number had already been used by the separate OpenSSL FIPS Object Module 2.0, so reusing it would have caused confusion.
What is the legacy provider in OpenSSL 3?
It is a provider that holds old or broken algorithms such as MD4, RC4, RC2, single DES, Blowfish and Whirlpool. It is not loaded by default. Applications that need it should load it explicitly in their own library context.
Is OpenSSL 1.1.1 still supported?
Not publicly. The release strategy page lists 1.1.1 as no longer supported. The OpenSSL Corporation offers paid Extended LTS for 1.1.1, and distributions that shipped it may still patch their own packages under their own lifecycle.
How do I check which OpenSSL Node.js or Python uses?
Run node -p "process.versions.openssl" for Node.js and python3 -c "import ssl; print(ssl.OPENSSL_VERSION)" for Python. Node.js usually reports its own bundled copy; Python on Linux usually reports the system library.
Does OpenSSL support post-quantum cryptography?
Yes. 3.5 added ML-KEM, ML-DSA and SLH-DSA and made the hybrid X25519MLKEM768 key share a default in TLS. 4.1 adds optimised implementations on more platforms.
Why supply chain hygiene still matters here
OpenSSL is maintained upstream and system packages are fixed by your distribution, so Safeguard's role here is indirect: it does not patch host operating systems or validate FIPS modules. It helps with the inventory this post keeps returning to, finding OpenSSL copies in container base images, bundled runtimes and native dependencies, and the projects that contain each version.
Every rebuilt image pulls its base layer and dependencies again, each of which can carry its own OpenSSL, so the inventory question returns with every build. The practices below close the gap between a fixed release and a fixed deployment.
Fix it without waiting for upstream
Whatever the vulnerability, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.
1. Autonomous remediation: pull requests, not tickets
When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation categories include dependencies, licenses, security posture and findings, and each one is set separately. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.
2. Gold Open Source: the safe version in seconds, free
gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds.
3. Gold Registry: start from components that are already fixed
Gold Registry provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs and a completed license check, with signed build provenance (signed with Safeguard's key and verifiable with cosign, SLSA Build Level 3 as the design target) and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.
When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. Ask which packages it covers before you plan around it.
| Your situation | What to use |
|---|---|
| A fixed version exists | Autonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version |
| You need to know today whether you are affected | Gold Open Source lookup and "Am I affected?" checker, free and without login |
| You want vulnerable versions to stop shipping | Safeguard policies and gates in CI |
| Upstream has no fix yet, or will not ship one | A custom Gold request; fork and patch |
| You want to start clean on new projects | Pull hardened components and images from Gold Registry |
One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.
See how Safeguard would help
The first demo shows the local runner: you set it up on your own machine, approve it with its device code, then scan from the terminal. The same flow scans a directory or a container image so you can see which OpenSSL packages and versions each one carries, without uploading the image anywhere first.
Click through it at your own pace, or open it full screen.
The second demo is a real Safeguard CLI session. You ask it to fix a vulnerable dependency, it reads the finding and the advisory, asks before any command that changes something, edits the manifest, runs the install and the tests with your approval, prints a summary and pushes nothing. For OpenSSL the same pattern applies to bumping a Node.js base image, a Python runtime pin or a cryptography version in a requirements file.
Click through it at your own pace, or open it full screen.
The third demo connects Claude to the Safeguard MCP server with OAuth and lets you choose which tools Claude can use. Once connected, you can ask in plain language which of your projects contain a given OpenSSL version, and get answers from your own scan data.
Click through it at your own pace, or open it full screen.
To try it on your own images, download Safeguard and follow the CLI documentation.
Quick check
Which OpenSSL release changed the licence to Apache 2.0 and introduced providers?
OpenSSL 3.0, released on 7 September 2021.
You patched libssl on a host. Is the Node.js process on that host protected?
Not necessarily. Node.js links its own bundled OpenSSL by default, so you need to upgrade Node.js itself and restart the process. Check with node -p "process.versions.openssl".
Sources
- OpenSSL Library: Release Strategy
- OpenSSL Library: Downloads
- OpenSSL Library: Old Releases
- OpenSSL Library: Old 3.0 releases
- OpenSSL Library: Release and Advisory Timeline
- OpenSSL Library: Security Policy
- OpenSSL Library: Vulnerabilities
- OpenSSL Library: CVEs and FIPS
- OpenSSL Library: License
- OpenSSL NEWS.md
- OpenSSL CHANGES.md
- OpenSSL 1.1.1 LICENSE file
- OpenSSL 3.0 Design
- OpenSSL 3.0 migration guide
- OSSL_PROVIDER-legacy manual page
- SSL_CTX_set_security_level manual page
- OpenSSL Foundation
- OpenSSL Foundation: History
- OpenSSL Corporation
- NIST CMVP Certificate 4282
- Python ssl module documentation
- PEP 644: Require OpenSSL 1.1.1 or newer
- Node.js BUILDING.md
- Node.js process documentation
- cryptography installation documentation
- Debian security FAQ
Last reviewed: 25 October 2026.