Skip to content

Commit 5bfbe5c

Browse files
committed
tls: drop NPN (next protocol negotiation) support
NPN has been superseded by ALPN. Chrome and Firefox removed support for NPN in 2016 and 2017 respectively to no ill effect. Fixes: #14602 PR-URL: #19403 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de>
1 parent b3f2391 commit 5bfbe5c

16 files changed

+73
-822
lines changed

deps/openssl/openssl.gypi

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1268,6 +1268,9 @@
12681268
# the real driver but that poses a security liability when an attacker
12691269
# is able to create a malicious DLL in one of the default search paths.
12701270
'OPENSSL_NO_HW',
1271+
1272+
# Disable NPN (Next Protocol Negotiation), superseded by ALPN.
1273+
'OPENSSL_NO_NEXTPROTONEG',
12711274
],
12721275
'openssl_default_defines_win': [
12731276
'MK1MF_BUILD',

doc/api/crypto.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2412,10 +2412,6 @@ the `crypto`, `tls`, and `https` modules and are generally specific to OpenSSL.
24122412
<td><code>DH_NOT_SUITABLE_GENERATOR</code></td>
24132413
<td></td>
24142414
</tr>
2415-
<tr>
2416-
<td><code>NPN_ENABLED</code></td>
2417-
<td></td>
2418-
</tr>
24192415
<tr>
24202416
<td><code>ALPN_ENABLED</code></td>
24212417
<td></td>

doc/api/tls.md

Lines changed: 12 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -104,22 +104,17 @@ not required and a default ECDHE curve will be used. The `ecdhCurve` property
104104
can be used when creating a TLS Server to specify the list of names of supported
105105
curves to use, see [`tls.createServer()`] for more info.
106106

107-
### ALPN, NPN, and SNI
107+
### ALPN and SNI
108108

109109
<!-- type=misc -->
110110

111-
ALPN (Application-Layer Protocol Negotiation Extension), NPN (Next
112-
Protocol Negotiation) and, SNI (Server Name Indication) are TLS
113-
handshake extensions:
111+
ALPN (Application-Layer Protocol Negotiation Extension) and
112+
SNI (Server Name Indication) are TLS handshake extensions:
114113

115-
* ALPN/NPN - Allows the use of one TLS server for multiple protocols (HTTP,
116-
SPDY, HTTP/2)
114+
* ALPN - Allows the use of one TLS server for multiple protocols (HTTP, HTTP/2)
117115
* SNI - Allows the use of one TLS server for multiple hostnames with different
118116
SSL certificates.
119117

120-
Use of ALPN is recommended over NPN. The NPN extension has never been
121-
formally defined or documented and generally not recommended for use.
122-
123118
### Client-initiated renegotiation attack mitigation
124119

125120
<!-- type=misc -->
@@ -332,12 +327,9 @@ server. If `tlsSocket.authorized` is `false`, then `socket.authorizationError`
332327
is set to describe how authorization failed. Note that depending on the settings
333328
of the TLS server, unauthorized connections may still be accepted.
334329

335-
The `tlsSocket.npnProtocol` and `tlsSocket.alpnProtocol` properties are strings
336-
that contain the selected NPN and ALPN protocols, respectively. When both NPN
337-
and ALPN extensions are received, ALPN takes precedence over NPN and the next
338-
protocol is selected by ALPN.
339-
340-
When ALPN has no selected protocol, `tlsSocket.alpnProtocol` returns `false`.
330+
The `tlsSocket.alpnProtocol` property is a string that contains the selected
331+
ALPN protocol. When ALPN has no selected protocol, `tlsSocket.alpnProtocol`
332+
equals `false`.
341333

342334
The `tlsSocket.servername` property is a string containing the server name
343335
requested via SNI.
@@ -468,7 +460,6 @@ changes:
468460
(`isServer` is true) may optionally set `requestCert` to true to request a
469461
client certificate.
470462
* `rejectUnauthorized`: Optional, see [`tls.createServer()`][]
471-
* `NPNProtocols`: Optional, see [`tls.createServer()`][]
472463
* `ALPNProtocols`: Optional, see [`tls.createServer()`][]
473464
* `SNICallback`: Optional, see [`tls.createServer()`][]
474465
* `session` {Buffer} An optional `Buffer` instance containing a TLS session.
@@ -509,9 +500,9 @@ regardless of whether or not the server's certificate has been authorized. It
509500
is the client's responsibility to check the `tlsSocket.authorized` property to
510501
determine if the server certificate was signed by one of the specified CAs. If
511502
`tlsSocket.authorized === false`, then the error can be found by examining the
512-
`tlsSocket.authorizationError` property. If either ALPN or NPN was used,
513-
the `tlsSocket.alpnProtocol` or `tlsSocket.npnProtocol` properties can be
514-
checked to determine the negotiated protocol.
503+
`tlsSocket.authorizationError` property. If ALPN was used, the
504+
`tlsSocket.alpnProtocol` property can be checked to determine the negotiated
505+
protocol.
515506

516507
### tlsSocket.address()
517508
<!-- YAML
@@ -841,8 +832,7 @@ changes:
841832
description: The `lookup` option is supported now.
842833
- version: v8.0.0
843834
pr-url: https://github.com/nodejs/node/pull/11984
844-
description: The `ALPNProtocols` and `NPNProtocols` options can
845-
be `Uint8Array`s now.
835+
description: The `ALPNProtocols` option can be a `Uint8Array` now.
846836
- version: v5.3.0, v4.7.0
847837
pr-url: https://github.com/nodejs/node/pull/4246
848838
description: The `secureContext` option is supported now.
@@ -869,12 +859,6 @@ changes:
869859
verified against the list of supplied CAs. An `'error'` event is emitted if
870860
verification fails; `err.code` contains the OpenSSL error code. Defaults to
871861
`true`.
872-
* `NPNProtocols` {string[]|Buffer[]|Uint8Array[]|Buffer|Uint8Array}
873-
An array of strings, `Buffer`s or `Uint8Array`s, or a single `Buffer` or
874-
`Uint8Array` containing supported NPN protocols. `Buffer`s should have the
875-
format `[len][name][len][name]...` e.g. `0x05hello0x05world`, where the
876-
first byte is the length of the next protocol name. Passing an array is
877-
usually much simpler, e.g. `['hello', 'world']`.
878862
* `ALPNProtocols`: {string[]|Buffer[]|Uint8Array[]|Buffer|Uint8Array}
879863
An array of strings, `Buffer`s or `Uint8Array`s, or a single `Buffer` or
880864
`Uint8Array` containing the supported ALPN protocols. `Buffer`s should have
@@ -1116,8 +1100,7 @@ changes:
11161100
description: The `options` parameter can now include `clientCertEngine`.
11171101
- version: v8.0.0
11181102
pr-url: https://github.com/nodejs/node/pull/11984
1119-
description: The `ALPNProtocols` and `NPNProtocols` options can
1120-
be `Uint8Array`s now.
1103+
description: The `ALPNProtocols` option can be a `Uint8Array` now.
11211104
- version: v5.0.0
11221105
pr-url: https://github.com/nodejs/node/pull/2564
11231106
description: ALPN options are supported now.
@@ -1136,23 +1119,13 @@ changes:
11361119
* `rejectUnauthorized` {boolean} If not `false` the server will reject any
11371120
connection which is not authorized with the list of supplied CAs. This
11381121
option only has an effect if `requestCert` is `true`. Defaults to `true`.
1139-
* `NPNProtocols` {string[]|Buffer[]|Uint8Array[]|Buffer|Uint8Array}
1140-
An array of strings, `Buffer`s or `Uint8Array`s, or a single `Buffer` or
1141-
`Uint8Array` containing supported NPN protocols. `Buffer`s should have the
1142-
format `[len][name][len][name]...` e.g. `0x05hello0x05world`, where the
1143-
first byte is the length of the next protocol name. Passing an array is
1144-
usually much simpler, e.g. `['hello', 'world']`.
1145-
(Protocols should be ordered by their priority.)
11461122
* `ALPNProtocols`: {string[]|Buffer[]|Uint8Array[]|Buffer|Uint8Array}
11471123
An array of strings, `Buffer`s or `Uint8Array`s, or a single `Buffer` or
11481124
`Uint8Array` containing the supported ALPN protocols. `Buffer`s should have
11491125
the format `[len][name][len][name]...` e.g. `0x05hello0x05world`, where the
11501126
first byte is the length of the next protocol name. Passing an array is
11511127
usually much simpler, e.g. `['hello', 'world']`.
11521128
(Protocols should be ordered by their priority.)
1153-
When the server receives both NPN and ALPN extensions from the client,
1154-
ALPN takes precedence over NPN and the server does not send an NPN
1155-
extension to the client.
11561129
* `SNICallback(servername, cb)` {Function} A function that will be called if
11571130
the client supports SNI TLS extension. Two arguments will be passed when
11581131
called: `servername` and `cb`. `SNICallback` should invoke `cb(null, ctx)`,
@@ -1333,7 +1306,6 @@ changes:
13331306
* `server` {net.Server} An optional [`net.Server`][] instance
13341307
* `requestCert`: Optional, see [`tls.createServer()`][]
13351308
* `rejectUnauthorized`: Optional, see [`tls.createServer()`][]
1336-
* `NPNProtocols`: Optional, see [`tls.createServer()`][]
13371309
* `ALPNProtocols`: Optional, see [`tls.createServer()`][]
13381310
* `SNICallback`: Optional, see [`tls.createServer()`][]
13391311
* `session` {Buffer} An optional `Buffer` instance containing a TLS session.

lib/_tls_wrap.js

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -294,8 +294,6 @@ function initRead(tls, wrapped) {
294294
function TLSSocket(socket, opts) {
295295
const tlsOptions = Object.assign({}, opts);
296296

297-
if (tlsOptions.NPNProtocols)
298-
tls.convertNPNProtocols(tlsOptions.NPNProtocols, tlsOptions);
299297
if (tlsOptions.ALPNProtocols)
300298
tls.convertALPNProtocols(tlsOptions.ALPNProtocols, tlsOptions);
301299

@@ -306,7 +304,6 @@ function TLSSocket(socket, opts) {
306304
this._controlReleased = false;
307305
this._SNICallback = null;
308306
this.servername = null;
309-
this.npnProtocol = null;
310307
this.alpnProtocol = null;
311308
this.authorized = false;
312309
this.authorizationError = null;
@@ -529,9 +526,6 @@ TLSSocket.prototype._init = function(socket, wrap) {
529526
ssl.enableCertCb();
530527
}
531528

532-
if (process.features.tls_npn && options.NPNProtocols)
533-
ssl.setNPNProtocols(options.NPNProtocols);
534-
535529
if (process.features.tls_alpn && options.ALPNProtocols) {
536530
// keep reference in secureContext not to be GC-ed
537531
ssl._secureContext.alpnBuffer = options.ALPNProtocols;
@@ -630,10 +624,6 @@ TLSSocket.prototype._releaseControl = function() {
630624
};
631625

632626
TLSSocket.prototype._finishInit = function() {
633-
if (process.features.tls_npn) {
634-
this.npnProtocol = this._handle.getNegotiatedProtocol();
635-
}
636-
637627
if (process.features.tls_alpn) {
638628
this.alpnProtocol = this._handle.getALPNNegotiatedProtocol();
639629
}
@@ -790,7 +780,6 @@ function tlsConnectionListener(rawSocket) {
790780
requestCert: this.requestCert,
791781
rejectUnauthorized: this.rejectUnauthorized,
792782
handshakeTimeout: this[kHandshakeTimeout],
793-
NPNProtocols: this.NPNProtocols,
794783
ALPNProtocols: this.ALPNProtocols,
795784
SNICallback: this[kSNICallback] || SNICallback
796785
});
@@ -982,7 +971,6 @@ Server.prototype.setOptions = function(options) {
982971
else
983972
this.honorCipherOrder = true;
984973
if (secureOptions) this.secureOptions = secureOptions;
985-
if (options.NPNProtocols) tls.convertNPNProtocols(options.NPNProtocols, this);
986974
if (options.ALPNProtocols)
987975
tls.convertALPNProtocols(options.ALPNProtocols, this);
988976
if (options.sessionIdContext) {
@@ -1149,7 +1137,6 @@ exports.connect = function(...args /* [port,] [host,] [options,] [cb] */) {
11491137
requestCert: true,
11501138
rejectUnauthorized: options.rejectUnauthorized !== false,
11511139
session: options.session,
1152-
NPNProtocols: options.NPNProtocols,
11531140
ALPNProtocols: options.ALPNProtocols,
11541141
requestOCSP: options.requestOCSP
11551142
});

lib/https.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,6 @@ function Server(opts, requestListener) {
4949
}
5050
opts = util._extend({}, opts);
5151

52-
if (process.features.tls_npn && !opts.NPNProtocols) {
53-
opts.NPNProtocols = ['http/1.1', 'http/1.0'];
54-
}
55-
5652
if (process.features.tls_alpn && !opts.ALPNProtocols) {
5753
// http/1.0 is not defined as Protocol IDs in IANA
5854
// http://www.iana.org/assignments/tls-extensiontype-values

node.gyp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -586,8 +586,8 @@
586586
'mkssldef_flags': [
587587
# Categories to export.
588588
'-CAES,BF,BIO,DES,DH,DSA,EC,ECDH,ECDSA,ENGINE,EVP,HMAC,MD4,MD5,'
589-
'NEXTPROTONEG,PSK,RC2,RC4,RSA,SHA,SHA0,SHA1,SHA256,SHA512,SOCK,'
590-
'STDIO,TLSEXT,FP_API',
589+
'PSK,RC2,RC4,RSA,SHA,SHA0,SHA1,SHA256,SHA512,SOCK,STDIO,TLSEXT,'
590+
'FP_API',
591591
# Defines.
592592
'-DWIN32',
593593
# Symbols to filter from the export list.

src/env.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,6 @@ struct PackageConfig {
103103
V(contextify_context_private_symbol, "node:contextify:context") \
104104
V(contextify_global_private_symbol, "node:contextify:global") \
105105
V(decorated_private_symbol, "node:decorated") \
106-
V(npn_buffer_private_symbol, "node:npnBuffer") \
107-
V(selected_npn_buffer_private_symbol, "node:selectedNpnBuffer") \
108106
V(napi_env, "node:napi:env") \
109107
V(napi_wrapper, "node:napi:wrapper") \
110108

src/node.cc

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2824,13 +2824,6 @@ static Local<Object> GetFeatures(Environment* env) {
28242824
// TODO(bnoordhuis) ping libuv
28252825
obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "ipv6"), True(env->isolate()));
28262826

2827-
#ifndef OPENSSL_NO_NEXTPROTONEG
2828-
Local<Boolean> tls_npn = True(env->isolate());
2829-
#else
2830-
Local<Boolean> tls_npn = False(env->isolate());
2831-
#endif
2832-
obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "tls_npn"), tls_npn);
2833-
28342827
#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
28352828
Local<Boolean> tls_alpn = True(env->isolate());
28362829
#else

src/node_constants.cc

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -971,11 +971,6 @@ void DefineOpenSSLConstants(Local<Object> target) {
971971
NODE_DEFINE_CONSTANT(target, DH_NOT_SUITABLE_GENERATOR);
972972
#endif
973973

974-
#ifndef OPENSSL_NO_NEXTPROTONEG
975-
#define NPN_ENABLED 1
976-
NODE_DEFINE_CONSTANT(target, NPN_ENABLED);
977-
#endif
978-
979974
#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
980975
#define ALPN_ENABLED 1
981976
NODE_DEFINE_CONSTANT(target, ALPN_ENABLED);

0 commit comments

Comments
 (0)