-
Notifications
You must be signed in to change notification settings - Fork 134
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
doc: describe OpenSSL maintenance strategy
PR-URL: #677 Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
- Loading branch information
1 parent
2fc508c
commit 03c36e1
Showing
1 changed file
with
356 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,356 @@ | ||
# Node.js OpenSSL Strategy | ||
|
||
This policy document describes for each release line: | ||
|
||
* Which versions of OpenSSL Node.js will include. | ||
* Which versions of a "shared" OpenSSL Node.js will support. | ||
* What version of TLS will be supported | ||
- by default, | ||
- with run-time configuration. | ||
* Whether FIPS will be supported. | ||
|
||
It also gives background on OpenSSL release lifetimes, TLS1.3, and FIPS support, | ||
as they affect Node.js. | ||
|
||
|
||
## Node.js version-specific strategy | ||
|
||
### Node.js version 4.x (EOL 2018-04-30) | ||
|
||
No longer maintained. Not discussed further. | ||
|
||
|
||
### Node.js versions 6.x (EOL 2019-04-30) and 8.x (EOL 2019-12-31) | ||
|
||
Node.js 6.x and 8.x have the same OpenSSL versions and policies. | ||
|
||
Node.js 8.x is unusual because it's end-of-life would normally be April, 2020, | ||
but it was moved earlier to conincide with the end-of-life of OpenSSL 1.0.2. | ||
|
||
* OpenSSL version: 1.0.2 (kept up-to-date with latest) | ||
* Allowed shared OpenSSL version: 1.0.2x | ||
* Default minimum TLS version is TLSv1, default maximum is TLSv1.2. No other | ||
TLS versions are supported by this version of OpenSSL or Node.js. | ||
* FIPS: supports being configured to build against OpenSSL FIPS 2.0. FIPS | ||
configuration is not default, and OpenSSL FIPS 2.0 is not included in | ||
Node.js. | ||
|
||
|
||
### Node.js version 10.x (EOL April-2021) | ||
|
||
OpenSSL LTS support timing, the lack of OpenSSL LTS planning and the lack of a | ||
clear timeframe for a new FIPS module complicates Node.js 10. | ||
|
||
For Node.js < 10.16.0: | ||
* OpenSSL version: 1.1.0 | ||
* Allowed shared OpenSSL version: 1.1.0 | ||
* Default minimum TLS version is TLSv1, default maximum is TLSv1.2. No other | ||
TLS versions are supported by this version of OpenSSL or Node.js. | ||
* FIPS: not supported | ||
|
||
For Node.js >= 10.16.0: | ||
* OpenSSL version: 1.1.1 | ||
* Allowed shared OpenSSL version: 1.1.0 or 1.1.1 | ||
* Default minimum TLS version is TLSv1, default maximum is TLSv1.2. It is | ||
expected that TLS1.3 support will be backported to 10.x, but it will *not* be | ||
supported by default, only by explicit run-time configuration. | ||
* FIPS: not supported | ||
|
||
The plan described above is to: | ||
|
||
* Remain backward-compatible with OpenSSL 1.1.0 via dynamic linking for the | ||
lifetime of Node.js 10. This will cease being an _official_ policy at the | ||
OpenSSL 1.1.0 EOL date (2019-09-11), which will occur long before Node.js 10.x | ||
enters Maintenance LTS (April 2020) or EOL (April 2021). Node.js does _not | ||
officially support_ EOL versions of OpenSSL, but support for a shared OpenSSL | ||
1.1.0 will be maintained as long as it does not cause security problems and | ||
there are contributors available to maintain such support. The lack of a | ||
passing test suite with Node.js 10 compiled against OpenSSL 1.1.0 past the | ||
OpenSSL EOL date will not hold up further releases of Node 10. | ||
* Upgrade to OpenSSL 1.1.1 when made generally available and Node.js 10 can | ||
retain ABI and API compatibility. OpenSSL 1.1.1 is claimed by the OpenSSL | ||
project to be API and ABI compatible with 1.1.0, and Node.js experiments | ||
indicates that it is, see | ||
https://github.com/nodejs/node/issues/18770#issuecomment-446785733. | ||
* **No support for FIPS** The latest [OpenSSL 3.0 and FIPS Update][] does not | ||
predict that an OpenSSL 1.1.1 ABI compatible library with FIPS support will | ||
ever exist. Without such a library, Node.js 10.x cannot support FIPS. | ||
|
||
This plan must be communicated to users of Node.js 10 early and often. There is | ||
potential for instability and a change in default OpenSSL version is | ||
unprecedented and therefore unexpected. The potential for breaking API and/or | ||
ABI may also cause disruption, potentially requiring an increment of | ||
`NODE_MODULE_VERSION`, which will also be unprecedented within a single release | ||
line. There is no indication yet that this will happen when OpenSSL 1.1.1 is | ||
included in Node.js 10.x, but it is important that users be aware of this | ||
possibility. | ||
|
||
|
||
### Node.js version 11.x (EOL June-2019) | ||
|
||
This release will not be designated LTS. It was updated to include OpenSSL 1.1.1 | ||
in [11.9.0](https://nodejs.org/en/blog/release/v11.9.0/). | ||
|
||
For Node.js < 11.9.0: | ||
* OpenSSL version: 1.1.0 | ||
* Allowed shared OpenSSL version: 1.1.0 | ||
* Default minimum TLS version is TLSv1, default maximum is TLSv1.2. No other | ||
TLS versions are supported by this version of OpenSSL or Node.js. | ||
* FIPS: not supported | ||
|
||
For Node.js >= 11.9.0: | ||
* OpenSSL version: 1.1.0 | ||
* Allowed shared OpenSSL version: 1.1.0 or 1.1.1 | ||
* Default minimum TLS version is TLSv1, default maximum is TLSv1.2. It is | ||
expected that TLS1.3 support will be backported to 11.x, but it will *not* be | ||
supported by default, only by explicit run-time configuration. | ||
* FIPS: not supported | ||
|
||
|
||
### Node.js version master, 12.x (release expected April-2019, EOL April-2022) | ||
|
||
* OpenSSL version: 1.1.1 | ||
* Allowed shared OpenSSL version: 1.1.1 | ||
* Default minimum TLS version is TLSv1.2, default maximum is TLSv1.3. TLSv1 | ||
and TLSv1.1 are *not* supported by default, only by explicit run-time | ||
configuration. | ||
* FIPS: not supported | ||
|
||
|
||
### Node.js version 13.x | ||
|
||
It's too early to discuss in detail, but this is the first version that may | ||
possibly support OpenSSL 3.0.0, and OpenSSL 3.0.0 is the next version of OpenSSL | ||
that is planned to support FIPS. See [OpenSSL 3.0.0 and FIPS][]. | ||
|
||
|
||
## Background | ||
|
||
The Node.js source tree contains a copy of OpenSSL (as it does all of its | ||
dependencies). | ||
|
||
All maintained Node.js release lines are kept up-to-date with the latest OpenSSL | ||
patch release of the OpenSSL version they include. | ||
|
||
By default, Node.js compiles and statically links its own copy of OpenSSL. It | ||
can be configured to an external "shared" OpenSSL library, or a non-OpenSSL | ||
library that has a sufficiently OpenSSL-compatible API. See [OpenSSL Forks][] | ||
for more information about OpenSSL-compatible libraries. | ||
|
||
Shared OpenSSL libraries will lack our floating patches, and may also not be the | ||
latest OpenSSL patch release. Node.js supports being configured to build against | ||
a shared OpenSSL library. Node.js does *not* support the resulting Node.js | ||
binaries built with this non-default configuration, doing so is the | ||
responsibility of the distributor. | ||
|
||
There are different configurations in use by distributors for linking Node.js to | ||
OpenSSL. The most notable distributors and the configurations used are: | ||
|
||
* **nodejs.org**: Binaries produced by the Node.js Build infrastructure across | ||
all supported architectures use the default configuration for OpenSSL and | ||
therefore compile and statically link in the OpenSSL source as it ships with | ||
Node.js. It should be noted that nodejs.org is the source of binaries for | ||
**nvm** which is in heavy client use and is also used by Travis-CI to fetch | ||
and install Node.js. | ||
* **Linux Distributions**: Binaries shipped with Debian, Ubuntu, CentOS, RHEL, | ||
Fedora and the majority of other Linux distributions follow a standard policy | ||
of separating dependencies and dynamically linking wherever possible. The | ||
Node.js packages on these systems are linked via the packaging dependency | ||
mechanisms to OpenSSL 1.0.2 packages and the `node` binaries that ship by | ||
default on these platforms use the shared OpenSSL 1.0.2 library installed by | ||
those packages. Therefore, the floating patches do not apply and it is | ||
possible that a different version of OpenSSL 1.0.2 is in use by Node.js than | ||
the version that was shipped in the source tree. | ||
* **NodeSource Builds**: Binaries | ||
[distributed](https://github.com/nodesource/distributions) by NodeSource are | ||
heavily used, and do not follow the Linux distribution policyof dependency | ||
seperation. NodeSource uses the Node.js defaults for `configure` and compile | ||
and statically link in the OpenSSL source shipped bundled with Node.js. | ||
* **Homebrew**: The | ||
[formula](https://github.com/Homebrew/homebrew-core/blob/master/Formula/node.rb) | ||
for Node.js as distributed on macOS by the popular `brew` command, by default, | ||
will compile using the default `configure` configuration. It is possible to | ||
override this using a `with-openssl` option which will compile against the | ||
version of OpenSSL that was most recently installed with `brew` but this is | ||
not believed to be in common use. | ||
|
||
|
||
|
||
## OpenSSL release lines | ||
|
||
Currently, there are three supported versions of OpenSSL as per the | ||
[OpenSSL Release Strategy][]. | ||
|
||
* Version 1.0.2: supported until 2019-12-31, designated Long-term Support (LTS) | ||
* Version 1.1.0: supported until 2019-09-11, not a LTS release line | ||
* Version 1.1.1: supported until 2023-09-11, designated Long-term Support (LTS) | ||
|
||
### OpenSSL 1.0.2 and FIPS | ||
|
||
OpenSSL 1.0.2 is included with Node.js 6.x and 8.x. Those Node.js versions will | ||
continue to get patch updates to 1.0.2, but will not be updated past 1.0.2. | ||
|
||
As the 1.0.2 support timeframe does not extend for the entirety of what should | ||
be the support timeframe for Node.js version 8 (2020-04), the version 8.x EOL | ||
date has been [contracted](https://github.com/nodejs/release#release-schedule) | ||
to coincide with the OpenSSL 1.0.2 EOL date at the end of 2019. | ||
|
||
[Federal Information Processing Standard](https://en.wikipedia.org/wiki/FIPS_140-2), | ||
"FIPS", is managed by the NIST. Publication 140-2 is a US government standard | ||
used to approve cryptographic software. | ||
|
||
Various organizations rely on the FIPS standard and mandate that software that | ||
they use conform appropriately. OpenSSL itself is not FIPS "validated", instead | ||
a separate "software component" called the "OpenSSL FIPS Object Module" has | ||
been created for the purpose of validation. It is a drop-in replacement for | ||
OpenSSL such that software using the OpenSSL API can be adapted to use it. In | ||
order to retain FIPS compliance, the OpenSSL FIPS Object Module source code | ||
must be obtained via a secure path as dictated by a security policy and the | ||
source must be compiled according to specific steps without variation. | ||
|
||
Node.js compiled against the OpenSSL FIPS Object Module does not make Node.js | ||
itself FIPS validated. Instructions for compiling Node.js against the Object | ||
Module along with links to further documentation are detailed in | ||
[BUILDING.md](https://github.com/nodejs/node/blob/master/BUILDING.md#building-nodejs-with-fips-compliant-openssl). | ||
|
||
The OpenSSL FIPS Object Module is compatible with OpenSSL 1.0.2 and Node.js has | ||
been able to build with this module since 2015, prior to Node.js 4.x. It | ||
requires some modification of the Node.js internals (see `git grep FIPS -- lib/ | ||
src/`) for this to work properly. | ||
|
||
OpenSSL 1.0.2 is the only current version of OpenSSL that supports FIPS, which | ||
means that Node.js 6.x and 8.x are the only versions of Node.js that currently | ||
support FIPS. | ||
|
||
In particular, note that Node.js 10.x, the most recent Node.js LTS release | ||
line, does not and *will not* support FIPS. | ||
|
||
Aside from some manual configuration that is | ||
required in order to support GYP builds (instead of the Perl-based Configure | ||
script that OpenSSL ships) as described in | ||
[deps/openssl/doc/UPGRADING.md](https://github.com/nodejs/node/blob/master/deps/openssl/doc/UPGRADING.md), | ||
there are 4 floating patches that are applied on top of the plain OpenSSL 1.0.2 | ||
source: | ||
|
||
* [c66c3d9fa](https://github.com/nodejs/node/commit/c66c3d9fa3f5bab0bdfe363dd947136cf8a3907f): | ||
`deps: fix openssl assembly error on ia32 win32`. A minor tweak to | ||
deps/openssl/openssl/crypto/perlasm/x86masm.pl to switch the instruction set | ||
referenced in ASM from 486 to 686, only affecting Windows on IA32. | ||
* [42a8de2ac](https://github.com/nodejs/node/commit/42a8de2ac66b6953cbc731fdb0b128b8019643b2): | ||
`deps: fix asm build error of openssl in x86_win32`. A fix for | ||
deps/openssl/openssl/crypto/perlasm/x86masm.pl for ASM produced for Windows on | ||
IA32 as described in | ||
https://mta.openssl.org/pipermail/openssl-dev/2015-February/000651.html | ||
* [2eb170874](https://github.com/nodejs/node/commit/2eb170874aa5e84e71b62caab7ac9792fd59c10f): | ||
`openssl: fix keypress requirement in apps on win32`. A fix for the `openssl` | ||
client application, used by the Node.js test suite, to properly accept stdin | ||
without requiring a physical keyboard. As described in | ||
<http://openssl.6102.n7.nabble.com/PATCH-s-client-Fix-keypress-requirement-with-redirected-input-on-Windows-td46787.html>. | ||
* [664a65969](https://github.com/nodejs/node/commit/664a6596960655e214fef25e74d3285097703e95): | ||
`deps: add -no_rand_screen to openssl s_client`. Adds a `-no_rand_screen` | ||
command line option to the `openssl` client application, used by the Node.js | ||
test suite which skips invocation of the `RAND_screen()` call on Windows in | ||
order to speed up some of the Node.js TLS tests. Use of this can be found in | ||
many of the `test/*/test-{tls,https}-*` test files. | ||
|
||
|
||
### OpenSSL 1.1.0 | ||
|
||
OpenSSL 1.1.0 represents a fairly major rework of the codebase, at least in | ||
comparison to its slow evolution until this point. The external API has some | ||
major departures from 1.0.2. However, support for compiling against an external | ||
OpenSSL 1.1.0 library (dynamically linked) was | ||
[added](https://github.com/nodejs/node/pull/16130) to Node.js' master branch in | ||
late 2017. | ||
|
||
Even though OpenSSL 1.1.0 is only supported until 2019-09-11, the API shift was | ||
an important stage in Node.js' adaptation. | ||
|
||
Openssl 1.1.0 is currently included in Node.js 10.x, but Node.js is expected to | ||
be updated to include OpenSSL 1.1.1 in the upcoming 10.16.0 release. | ||
|
||
|
||
### OpenSSL 1.1.1 | ||
|
||
The OpenSSL team has designated 1.1.1 the next LTS line and have made a | ||
commitment that it will remain both API and ABI compatible with OpenSSL 1.1.0, | ||
and will be supported until 2023-09-11. It is the first OpenSSL version to | ||
support TLS 1.3, however Node.js' TLS1.3 support requires at least OpenSSL | ||
1.1.1b. | ||
|
||
|
||
### OpenSSL 3.0.0 and FIPS | ||
|
||
The next release of OpenSSL will be 3.0.0. It is skipping 2.0 because that | ||
version has been used for OpenSSL FIPS. It is a major re-architecting, and while | ||
it is expected to be API compatible with OpenSSL 1.1.1, it is *not* expected to | ||
be ABI compatible, re-compilation will be necessary to upgrade from OpenSSL | ||
1.1.1 to 3.0.0. | ||
|
||
OpenSSL 3.0.0 is expected to support FIPS. | ||
|
||
See the [OpenSSL 3.0.0 Design][] for more information. | ||
|
||
Beta releases of 3.0.0 are expected in Fall, 2019. | ||
|
||
Since OpenSSL 3.0.0 is not expected to be ABI compatible with OpenSSL 1.1.1, | ||
Node.js 12.x cannot be updated to it. Whether Node.js 13.x (a non-LTS release) | ||
will be able to include OpenSSL 3.0.0 is currently unknown. It depends on | ||
whether 3.0.0 is ABI compatible with 1.1.1 (it is not expected to be), whether | ||
the Node.js project is willing to make an ABI incompatible update to OpenSSL | ||
within a non-LTS release line, the timing of the OpenSSL 3.0.0 release, and the | ||
timing of FIPS support for OpenSSL 3.0.0, most of which is unknown. | ||
|
||
Currently, it appears that Node.js 13.x will be the next version of Node.js that | ||
may possibly support FIPS, and that Node.js 14.x, released in April, 2020 will | ||
be the next LTS candidate that may possibly support FIPS. There will be a gap | ||
between Node.js 8.x going end-of-life in December, 2019, and the next LTS | ||
release of Node.js that supports FIPS coming in April, 2020. | ||
|
||
At this point, the gap looks unavoidable. | ||
|
||
|
||
## OpenSSL forks: LibreSSL and BoringSSL | ||
|
||
**Node.js does not officially support compiling against OpenSSL-compatible | ||
libraries** aside from the OpenSSL FIPS Object Module. However, Node.js | ||
welcomes contributions which may improve compatibility where those | ||
contributions are relatively unobtrusive. | ||
|
||
### [LibreSSL](https://www.libressl.org/) | ||
|
||
[Some work](https://github.com/nodejs/node/pull/9376) has been done to enable | ||
compilation against LibreSSL. Some operating system distributions ship LibreSSL | ||
instead of OpenSSL and therefore require patching of software such as Node.js. | ||
This is already done in practice, external to the Node.js codebase and without | ||
any support from the Node.js core team. Due to the close compatibility between | ||
LibreSSL and OpenSSL, full and unobtrusive support for compiling against | ||
LibreSSL could be landed into the Node.js codebase given developers interested | ||
in completing this task. | ||
|
||
Even if such support was to land in the Node.js codebase, the Node.js project | ||
will not commit to officially supporting LibreSSL or even maintaining full | ||
compatibility in an ongoing basis. As is the case for some operating systems | ||
that are not officially supported, ongoing compatibility will need to be | ||
monitored by interested parties who will also need to submit fixes as required. | ||
|
||
### [BoringSSL](https://boringssl.googlesource.com/boringssl/) | ||
|
||
> Although BoringSSL is an open source project, it is not intended for general | ||
> use, as OpenSSL is. We don't recommend that third parties depend upon it. | ||
> Doing so is likely to be frustrating because there are no guarantees of API | ||
> or ABI stability. | ||
Google have made it clear that BoringSSL is not intended for general use | ||
outside of their own internal needs. Node.js will not officially support | ||
BoringSSL and unless trivially unobtrusive, the Node.js core team is | ||
discouraged from accepting changes that support BoringSSL. The appearance of | ||
support for BoringSSL will send the wrong message to users regarding its | ||
suitability as an OpenSSL replacement and Node.js' willingness to maintain | ||
support. | ||
|
||
[Node.js Release Schedule]: https://github.com/nodejs/Release/blob/master/README.md#release-schedule | ||
[OpenSSL Release Strategy]: https://www.openssl.org/policies/releasestrat.html | ||
[OpenSSL 3.0 and FIPS Update]: https://www.openssl.org/blog/blog/2019/02/13/FIPS-update/ | ||
[OpenSSL 3.0.0 Design]: https://www.openssl.org/docs/OpenSSL300Design.html | ||
|