Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v11.x backport] TLS1.3 #26951

Closed
wants to merge 13 commits into from
Closed
2 changes: 2 additions & 0 deletions deps/openssl/openssl/crypto/chacha/build.info
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ GENERATE[chacha-armv4.S]=asm/chacha-armv4.pl $(PERLASM_SCHEME)
INCLUDE[chacha-armv4.o]=..
GENERATE[chacha-armv8.S]=asm/chacha-armv8.pl $(PERLASM_SCHEME)
INCLUDE[chacha-armv8.o]=..
GENERATE[chacha-s390x.S]=asm/chacha-s390x.pl $(PERLASM_SCHEME)
INCLUDE[chacha-s390x.o]=..

BEGINRAW[Makefile(unix)]
##### CHACHA assembler implementations
Expand Down
2 changes: 2 additions & 0 deletions deps/openssl/openssl/crypto/poly1305/build.info
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ GENERATE[poly1305-armv8.S]=asm/poly1305-armv8.pl $(PERLASM_SCHEME)
INCLUDE[poly1305-armv8.o]=..
GENERATE[poly1305-mips.S]=asm/poly1305-mips.pl $(PERLASM_SCHEME)
INCLUDE[poly1305-mips.o]=..
GENERATE[poly1305-s390x.S]=asm/poly1305-s390x.pl $(PERLASM_SCHEME)
INCLUDE[poly1305-s390x.o]=..

BEGINRAW[Makefile(unix)]
{- $builddir -}/poly1305-%.S: {- $sourcedir -}/asm/poly1305-%.pl
Expand Down
2 changes: 2 additions & 0 deletions deps/openssl/openssl/crypto/rc4/build.info
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ GENERATE[rc4-md5-x86_64.s]=asm/rc4-md5-x86_64.pl $(PERLASM_SCHEME)

GENERATE[rc4-parisc.s]=asm/rc4-parisc.pl $(PERLASM_SCHEME)

GENERATE[rc4-s390x.s]=asm/rc4-s390x.pl $(PERLASM_SCHEME)

BEGINRAW[Makefile]
# GNU make "catch all"
{- $builddir -}/rc4-%.s: {- $sourcedir -}/asm/rc4-%.pl
Expand Down
50 changes: 50 additions & 0 deletions doc/api/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,54 @@ added: v4.0.0
Specify an alternative default TLS cipher list. Requires Node.js to be built
with crypto support (default).

### `--tls-max-v1.2`
<!-- YAML
added: REPLACEME
-->

Set [`tls.DEFAULT_MAX_VERSION`][] to 'TLSv1.2'. Use to disable support for
TLSv1.3.

### `--tls-max-v1.3`
<!-- YAML
added: REPLACEME
-->

Set default [`tls.DEFAULT_MAX_VERSION`][] to 'TLSv1.3'. Use to enable support
for TLSv1.3.

### `--tls-min-v1.0`
<!-- YAML
added: REPLACEME
-->

Set default [`tls.DEFAULT_MIN_VERSION`][] to 'TLSv1'. Use for compatibility with
old TLS clients or servers.

### `--tls-min-v1.1`
<!-- YAML
added: REPLACEME
-->

Set default [`tls.DEFAULT_MIN_VERSION`][] to 'TLSv1.1'. Use for compatibility
with old TLS clients or servers.

### `--tls-min-v1.2`
<!-- YAML
added: REPLACEME
-->

Set default [`minVersion`][] to `'TLSv1.2'`. Use to disable support for TLSv1
and TLSv1.1 in favour of TLSv1.2, which is more secure.

### `--tls-min-v1.3`
<!-- YAML
added: REPLACEME
-->

Set default [`tls.DEFAULT_MIN_VERSION`][] to 'TLSv1.3'. Use to disable support
for TLSv1.2, which is not as secure as TLSv1.3.

### `--trace-deprecation`
<!-- YAML
added: v0.8.0
Expand Down Expand Up @@ -881,6 +929,8 @@ greater than `4` (its current default value). For more information, see the
[`Buffer`]: buffer.html#buffer_class_buffer
[`SlowBuffer`]: buffer.html#buffer_class_slowbuffer
[`process.setUncaughtExceptionCaptureCallback()`]: process.html#process_process_setuncaughtexceptioncapturecallback_fn
[`tls.DEFAULT_MAX_VERSION`]: tls.html#tls_tls_default_max_version
[`tls.DEFAULT_MIN_VERSION`]: tls.html#tls_tls_default_min_version
[Chrome DevTools Protocol]: https://chromedevtools.github.io/devtools-protocol/
[REPL]: repl.html
[ScriptCoverage]: https://chromedevtools.github.io/devtools-protocol/tot/Profiler#type-ScriptCoverage
Expand Down
6 changes: 6 additions & 0 deletions doc/api/errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -1714,6 +1714,12 @@ recommended to use 2048 bits or larger for stronger security.
A TLS/SSL handshake timed out. In this case, the server must also abort the
connection.

<a id="ERR_TLS_INVALID_PROTOCOL_METHOD"></a>
### ERR_TLS_INVALID_PROTOCOL_METHOD

The specified `secureProtocol` method is invalid. It is either unknown, or
disabled because it is insecure.

<a id="ERR_TLS_INVALID_PROTOCOL_VERSION"></a>
### ERR_TLS_INVALID_PROTOCOL_VERSION

Expand Down
141 changes: 113 additions & 28 deletions doc/api/tls.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ not required and a default ECDHE curve will be used. The `ecdhCurve` property
can be used when creating a TLS Server to specify the list of names of supported
curves to use, see [`tls.createServer()`] for more info.

Perfect Forward Secrecy was optional up to TLSv1.2, but it is not optional for
TLSv1.3, because all TLSv1.3 cipher suites use ECDHE.

### ALPN and SNI

<!-- type=misc -->
Expand Down Expand Up @@ -136,6 +139,8 @@ threshold is exceeded. The limits are configurable:
The default renegotiation limits should not be modified without a full
understanding of the implications and risks.

TLSv1.3 does not support renegotiation.

### Session Resumption

Establishing a TLS session can be relatively slow. The process can be sped
Expand Down Expand Up @@ -176,6 +181,10 @@ as for resumption with session tickets. For debugging, if
[`tls.TLSSocket.getTLSTicket()`][] returns a value, the session data contains a
ticket, otherwise it contains client-side session state.

With TLSv1.3, be aware that multiple tickets may be sent by the server,
resulting in multiple `'session'` events, see [`'session'`][] for more
information.

Single process servers need no specific implementation to use session tickets.
To use session tickets across server restarts or load balancers, servers must
all have the same ticket keys. There are three 16-byte keys internally, but the
Expand Down Expand Up @@ -230,6 +239,9 @@ Node.js is built with a default suite of enabled and disabled TLS ciphers.
Currently, the default cipher suite is:

```txt
TLS_AES_256_GCM_SHA384:
TLS_CHACHA20_POLY1305_SHA256:
TLS_AES_128_GCM_SHA256:
ECDHE-RSA-AES128-GCM-SHA256:
ECDHE-ECDSA-AES128-GCM-SHA256:
ECDHE-RSA-AES256-GCM-SHA384:
Expand Down Expand Up @@ -270,7 +282,19 @@ The default can also be replaced on a per client or server basis using the
in [`tls.createServer()`], [`tls.connect()`], and when creating new
[`tls.TLSSocket`]s.

Consult [OpenSSL cipher list format documentation][] for details on the format.
The ciphers list can contain a mixture of TLSv1.3 cipher suite names, the ones
that start with `'TLS_'`, and specifications for TLSv1.2 and below cipher
suites. The TLSv1.2 ciphers support a legacy specification format, consult
the OpenSSL [cipher list format][] documentation for details, but those
specifications do *not* apply to TLSv1.3 ciphers. The TLSv1.3 suites can only
be enabled by including their full name in the cipher list. They cannot, for
example, be enabled or disabled by using the legacy TLSv1.2 `'EECDH'` or
`'!EECDH'` specification.

Despite the relative order of TLSv1.3 and TLSv1.2 cipher suites, the TLSv1.3
protocol is significantly more secure than TLSv1.2, and will always be chosen
over TLSv1.2 if the handshake indicates it is supported, and if any TLSv1.3
cipher suites are enabled.

The default cipher suite included within Node.js has been carefully
selected to reflect current security best practices and risk mitigation.
Expand All @@ -289,7 +313,18 @@ Old clients that rely on insecure and deprecated RC4 or DES-based ciphers
(like Internet Explorer 6) cannot complete the handshaking process with
the default configuration. If these clients _must_ be supported, the
[TLS recommendations] may offer a compatible cipher suite. For more details
on the format, see the [OpenSSL cipher list format documentation].
on the format, see the OpenSSL [cipher list format][] documentation.

There are only 5 TLSv1.3 cipher suites:
- `'TLS_AES_256_GCM_SHA384'`
- `'TLS_CHACHA20_POLY1305_SHA256'`
- `'TLS_AES_128_GCM_SHA256'`
- `'TLS_AES_128_CCM_SHA256'`
- `'TLS_AES_128_CCM_8_SHA256'`

The first 3 are enabled by default. The last 2 `CCM`-based suites are supported
by TLSv1.3 because they may be more performant on constrained systems, but they
are not enabled by default since they offer less security.

## Class: tls.Server
<!-- YAML
Expand Down Expand Up @@ -634,11 +669,11 @@ On the client, the `session` can be provided to the `session` option of

See [Session Resumption][] for more information.

Note: For TLS1.2 and below, [`tls.TLSSocket.getSession()`][] can be called once
the handshake is complete. For TLS1.3, only ticket based resumption is allowed
Note: For TLSv1.2 and below, [`tls.TLSSocket.getSession()`][] can be called once
the handshake is complete. For TLSv1.3, only ticket based resumption is allowed
by the protocol, multiple tickets are sent, and the tickets aren't sent until
later, after the handshake completes, so it is necessary to wait for the
`'session'` event to get a resumable session. Future-proof applications are
`'session'` event to get a resumable session. Applications are
recommended to use the `'session'` event instead of `getSession()` to ensure
they will work for all TLS protocol versions. Applications that only expect to
get or use 1 session should listen for this event only once:
Expand Down Expand Up @@ -724,7 +759,7 @@ added: v0.11.4
Returns an object representing the cipher name. The `version` key is a legacy
field which always contains the value `'TLSv1/SSLv3'`.

For example: `{ name: 'AES256-SHA', version: 'TLSv1/SSLv3' }`.
For example: `{ name: 'AES256-SHA', version: 'TLSv1.2' }`.

See `SSL_CIPHER_get_name()` in
<https://www.openssl.org/docs/man1.1.0/ssl/SSL_CIPHER_get_name.html> for more
Expand Down Expand Up @@ -897,12 +932,13 @@ be returned for server sockets or disconnected client sockets.

Protocol versions are:

* `'SSLv3'`
* `'TLSv1'`
* `'TLSv1.1'`
* `'TLSv1.2'`
* `'SSLv3'`
* `'TLSv1.3'`

See <https://www.openssl.org/docs/man1.1.0/ssl/SSL_get_version.html> for more
See <https://www.openssl.org/docs/man1.1.1/man3/SSL_get_version.html> for more
information.

### tlsSocket.getSession()
Expand All @@ -919,8 +955,8 @@ for debugging.

See [Session Resumption][] for more information.

Note: `getSession()` works only for TLS1.2 and below. Future-proof applications
should use the [`'session'`][] event.
Note: `getSession()` works only for TLSv1.2 and below. For TLSv1.3, applications
must use the [`'session'`][] event (it also works for TLSv1.2 and below).

### tlsSocket.getTLSTicket()
<!-- YAML
Expand Down Expand Up @@ -1002,8 +1038,12 @@ added: v0.11.8
verification fails; `err.code` contains the OpenSSL error code. **Default:**
`true`.
* `requestCert`
* `callback` {Function} A function that will be called when the renegotiation
request has been completed.
* `callback` {Function} If `renegotiate()` returned `true`, callback is
attached once to the `'secure'` event. If it returned `false`, it will be
called in the next tick with `ERR_TLS_RENEGOTIATE`, unless the `tlsSocket`
has been destroyed, in which case it will not be called at all.

* Returns: {boolean} `true` if renegotiation was initiated, `false` otherwise.

The `tlsSocket.renegotiate()` method initiates a TLS renegotiation process.
Upon completion, the `callback` function will be passed a single argument
Expand All @@ -1015,6 +1055,9 @@ connection has been established.
When running as the server, the socket will be destroyed with an error after
`handshakeTimeout` timeout.

For TLSv1.3, renegotiation cannot be initiated, it is not supported by the
protocol.

### tlsSocket.setMaxSendFragment(size)
<!-- YAML
added: v0.11.11
Expand Down Expand Up @@ -1213,6 +1256,9 @@ argument.
<!-- YAML
added: v0.11.13
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/26209
description: TLSv1.3 support added.
- version: v11.5.0
pr-url: https://github.com/nodejs/node/pull/24733
description: The `ca:` option now supports `BEGIN TRUSTED CERTIFICATE`.
Expand Down Expand Up @@ -1303,13 +1349,15 @@ changes:
`object.passphrase` is optional. Encrypted keys will be decrypted with
`object.passphrase` if provided, or `options.passphrase` if it is not.
* `maxVersion` {string} Optionally set the maximum TLS version to allow. One
of `TLSv1.2'`, `'TLSv1.1'`, or `'TLSv1'`. Cannot be specified along with the
`secureProtocol` option, use one or the other. **Default:** `'TLSv1.2'`.
of `TLSv1.3`, `TLSv1.2'`, `'TLSv1.1'`, or `'TLSv1'`. Cannot be specified
along with the `secureProtocol` option, use one or the other.
**Default:** [`tls.DEFAULT_MAX_VERSION`][].
* `minVersion` {string} Optionally set the minimum TLS version to allow. One
of `TLSv1.2'`, `'TLSv1.1'`, or `'TLSv1'`. Cannot be specified along with the
`secureProtocol` option, use one or the other. It is not recommended to use
less than TLSv1.2, but it may be required for interoperability.
**Default:** `'TLSv1'`.
of `TLSv1.3`, `TLSv1.2'`, `'TLSv1.1'`, or `'TLSv1'`. Cannot be specified
along with the `secureProtocol` option, use one or the other. It is not
recommended to use less than TLSv1.2, but it may be required for
interoperability.
**Default:** [`tls.DEFAULT_MIN_VERSION`][].
* `passphrase` {string} Shared passphrase used for a single private key and/or
a PFX.
* `pfx` {string|string[]|Buffer|Buffer[]|Object[]} PFX or PKCS12 encoded
Expand All @@ -1325,12 +1373,15 @@ changes:
which is not usually necessary. This should be used carefully if at all!
Value is a numeric bitmask of the `SSL_OP_*` options from
[OpenSSL Options][].
* `secureProtocol` {string} The TLS protocol version to use. The possible
values are listed as [SSL_METHODS][], use the function names as strings. For
example, use `'TLSv1_1_method'` to force TLS version 1.1, or `'TLS_method'`
to allow any TLS protocol version. It is not recommended to use TLS versions
less than 1.2, but it may be required for interoperability. **Default:**
none, see `minVersion`.
* `secureProtocol` {string} Legacy mechanism to select the TLS protocol
version to use, it does not support independent control of the minimum and
maximum version, and does not support limiting the protocol to TLSv1.3. Use
`minVersion` and `maxVersion` instead. The possible values are listed as
[SSL_METHODS][], use the function names as strings. For example, use
`'TLSv1_1_method'` to force TLS version 1.1, or `'TLS_method'` to allow any
TLS protocol version up to TLSv1.3. It is not recommended to use TLS
versions less than 1.2, but it may be required for interoperability.
**Default:** none, see `minVersion`.
* `sessionIdContext` {string} Opaque identifier used by servers to ensure
session state is not shared between applications. Unused by clients.

Expand Down Expand Up @@ -1450,10 +1501,15 @@ added: v0.10.2

* Returns: {string[]}

Returns an array with the names of the supported SSL ciphers.
Returns an array with the names of the supported TLS ciphers. The names are
lower-case for historical reasons, but must be uppercased to be used in
the `ciphers` option of [`tls.createSecureContext()`][].

Cipher names that start with `'tls_'` are for TLSv1.3, all the others are for
TLSv1.2 and below.

```js
console.log(tls.getCiphers()); // ['AES128-SHA', 'AES256-SHA', ...]
console.log(tls.getCiphers()); // ['aes128-gcm-sha256', 'aes128-sha', ...]
```

## tls.DEFAULT_ECDH_CURVE
Expand All @@ -1469,6 +1525,33 @@ The default curve name to use for ECDH key agreement in a tls server. The
default value is `'auto'`. See [`tls.createSecureContext()`] for further
information.

## tls.DEFAULT_MAX_VERSION
<!-- YAML
added: v11.4.0
-->

* {string} The default value of the `maxVersion` option of
[`tls.createSecureContext()`][]. It can be assigned any of the supported TLS
protocol versions, `TLSv1.3`, `TLSv1.2'`, `'TLSv1.1'`, or `'TLSv1'`.
**Default:** `'TLSv1.2'`, unless changed using CLI options. Using
`--tls-max-v1.2` sets the default to `'TLSv1.2`'. Using `--tls-max-v1.3` sets
the default to `'TLSv1.3'`. If multiple of the options are provided, the
highest maximum is used.

## tls.DEFAULT_MIN_VERSION
<!-- YAML
added: v11.4.0
-->

* {string} The default value of the `minVersion` option of
[`tls.createSecureContext()`][]. It can be assigned any of the supported TLS
protocol versions, `'TLSv1.3'`, `TLSv1.2'`, `'TLSv1.1'`, or `'TLSv1'`.
**Default:** `'TLSv1'`, unless changed using CLI options. Using
`--tls-min-v1.0` sets the default to `'TLSv1'`. Using `--tls-min-v1.1` sets
the default to `'TLSv1.1'`. Using `--tls-min-v1.3` sets the default to
`'TLSv1.3'`. If multiple of the options are provided, the lowest minimum is
used.

## Deprecated APIs

### Class: CryptoStream
Expand Down Expand Up @@ -1597,6 +1680,8 @@ where `secureSocket` has the same API as `pair.cleartext`.
[`server.setTicketKeys()`]: #tls_server_setticketkeys_keys
[`socket.setTimeout(timeout)`]: #net_socket_settimeout_timeout_callback
[`tls.DEFAULT_ECDH_CURVE`]: #tls_tls_default_ecdh_curve
[`tls.DEFAULT_MAX_VERSION`]: #tls_tls_default_max_version
[`tls.DEFAULT_MIN_VERSION`]: #tls_tls_default_min_version
[`tls.Server`]: #tls_class_tls_server
[`tls.TLSSocket.getPeerCertificate()`]: #tls_tlssocket_getpeercertificate_detailed
[`tls.TLSSocket.getSession()`]: #tls_tlssocket_getsession
Expand All @@ -1613,16 +1698,16 @@ where `secureSocket` has the same API as `pair.cleartext`.
[Forward secrecy]: https://en.wikipedia.org/wiki/Perfect_forward_secrecy
[OCSP request]: https://en.wikipedia.org/wiki/OCSP_stapling
[OpenSSL Options]: crypto.html#crypto_openssl_options
[OpenSSL cipher list format documentation]: https://www.openssl.org/docs/man1.1.0/apps/ciphers.html#CIPHER-LIST-FORMAT
[Perfect Forward Secrecy]: #tls_perfect_forward_secrecy
[RFC 2246]: https://www.ietf.org/rfc/rfc2246.txt
[RFC 5077]: https://tools.ietf.org/html/rfc5077
[RFC 5929]: https://tools.ietf.org/html/rfc5929
[SSL_METHODS]: https://www.openssl.org/docs/man1.1.0/ssl/ssl.html#Dealing-with-Protocol-Methods
[SSL_METHODS]: https://www.openssl.org/docs/man1.1.1/man7/ssl.html#Dealing-with-Protocol-Methods
[Session Resumption]: #tls_session_resumption
[Stream]: stream.html#stream_stream
[TLS recommendations]: https://wiki.mozilla.org/Security/Server_Side_TLS
[asn1.js]: https://www.npmjs.com/package/asn1.js
[certificate object]: #tls_certificate_object
[cipher list format]: https://www.openssl.org/docs/man1.1.1/man1/ciphers.html#CIPHER-LIST-FORMAT
[modifying the default cipher suite]: #tls_modifying_the_default_tls_cipher_suite
[specific attacks affecting larger AES key sizes]: https://www.schneier.com/blog/archives/2009/07/another_new_aes.html
Loading