diff options
author | Ben Noordhuis <info@bnoordhuis.nl> | 2018-03-17 05:13:47 +0100 |
---|---|---|
committer | Ben Noordhuis <info@bnoordhuis.nl> | 2018-03-27 16:22:37 +0200 |
commit | 5bfbe5ceaecb6412b176db446caf00f77f84bae7 (patch) | |
tree | 4c3a6696de1c1116046144473cac5e1389564790 | |
parent | b3f23910a25613eb289fe4b338f83783a9f731b3 (diff) | |
download | node-new-5bfbe5ceaecb6412b176db446caf00f77f84bae7.tar.gz |
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: https://github.com/nodejs/node/issues/14602
PR-URL: https://github.com/nodejs/node/pull/19403
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
-rw-r--r-- | deps/openssl/openssl.gypi | 3 | ||||
-rw-r--r-- | doc/api/crypto.md | 4 | ||||
-rw-r--r-- | doc/api/tls.md | 52 | ||||
-rw-r--r-- | lib/_tls_wrap.js | 13 | ||||
-rw-r--r-- | lib/https.js | 4 | ||||
-rw-r--r-- | node.gyp | 4 | ||||
-rw-r--r-- | src/env.h | 2 | ||||
-rw-r--r-- | src/node.cc | 7 | ||||
-rw-r--r-- | src/node_constants.cc | 5 | ||||
-rw-r--r-- | src/node_crypto.cc | 182 | ||||
-rw-r--r-- | src/node_crypto.h | 18 | ||||
-rw-r--r-- | src/tls_wrap.cc | 2 | ||||
-rw-r--r-- | test/parallel/test-https-argument-of-creating.js | 17 | ||||
-rw-r--r-- | test/parallel/test-tls-alpn-server-client.js | 435 | ||||
-rw-r--r-- | test/parallel/test-tls-npn-server-client.js | 118 | ||||
-rw-r--r-- | test/parallel/test-tls-socket-constructor-alpn-options-parsing.js (renamed from test/parallel/test-tls-socket-constructor-alpn-npn-options-parsing.js) | 29 |
16 files changed, 73 insertions, 822 deletions
diff --git a/deps/openssl/openssl.gypi b/deps/openssl/openssl.gypi index 871cec0c7e..d6d2589083 100644 --- a/deps/openssl/openssl.gypi +++ b/deps/openssl/openssl.gypi @@ -1268,6 +1268,9 @@ # the real driver but that poses a security liability when an attacker # is able to create a malicious DLL in one of the default search paths. 'OPENSSL_NO_HW', + + # Disable NPN (Next Protocol Negotiation), superseded by ALPN. + 'OPENSSL_NO_NEXTPROTONEG', ], 'openssl_default_defines_win': [ 'MK1MF_BUILD', diff --git a/doc/api/crypto.md b/doc/api/crypto.md index 4c2354f52e..f90c2cfe2e 100644 --- a/doc/api/crypto.md +++ b/doc/api/crypto.md @@ -2413,10 +2413,6 @@ the `crypto`, `tls`, and `https` modules and are generally specific to OpenSSL. <td></td> </tr> <tr> - <td><code>NPN_ENABLED</code></td> - <td></td> - </tr> - <tr> <td><code>ALPN_ENABLED</code></td> <td></td> </tr> diff --git a/doc/api/tls.md b/doc/api/tls.md index 39ef97562a..f519681c62 100644 --- a/doc/api/tls.md +++ b/doc/api/tls.md @@ -104,22 +104,17 @@ 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. -### ALPN, NPN, and SNI +### ALPN and SNI <!-- type=misc --> -ALPN (Application-Layer Protocol Negotiation Extension), NPN (Next -Protocol Negotiation) and, SNI (Server Name Indication) are TLS -handshake extensions: +ALPN (Application-Layer Protocol Negotiation Extension) and +SNI (Server Name Indication) are TLS handshake extensions: -* ALPN/NPN - Allows the use of one TLS server for multiple protocols (HTTP, - SPDY, HTTP/2) +* ALPN - Allows the use of one TLS server for multiple protocols (HTTP, HTTP/2) * SNI - Allows the use of one TLS server for multiple hostnames with different SSL certificates. -Use of ALPN is recommended over NPN. The NPN extension has never been -formally defined or documented and generally not recommended for use. - ### Client-initiated renegotiation attack mitigation <!-- type=misc --> @@ -332,12 +327,9 @@ server. If `tlsSocket.authorized` is `false`, then `socket.authorizationError` is set to describe how authorization failed. Note that depending on the settings of the TLS server, unauthorized connections may still be accepted. -The `tlsSocket.npnProtocol` and `tlsSocket.alpnProtocol` properties are strings -that contain the selected NPN and ALPN protocols, respectively. When both NPN -and ALPN extensions are received, ALPN takes precedence over NPN and the next -protocol is selected by ALPN. - -When ALPN has no selected protocol, `tlsSocket.alpnProtocol` returns `false`. +The `tlsSocket.alpnProtocol` property is a string that contains the selected +ALPN protocol. When ALPN has no selected protocol, `tlsSocket.alpnProtocol` +equals `false`. The `tlsSocket.servername` property is a string containing the server name requested via SNI. @@ -468,7 +460,6 @@ changes: (`isServer` is true) may optionally set `requestCert` to true to request a client certificate. * `rejectUnauthorized`: Optional, see [`tls.createServer()`][] - * `NPNProtocols`: Optional, see [`tls.createServer()`][] * `ALPNProtocols`: Optional, see [`tls.createServer()`][] * `SNICallback`: Optional, see [`tls.createServer()`][] * `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 is the client's responsibility to check the `tlsSocket.authorized` property to determine if the server certificate was signed by one of the specified CAs. If `tlsSocket.authorized === false`, then the error can be found by examining the -`tlsSocket.authorizationError` property. If either ALPN or NPN was used, -the `tlsSocket.alpnProtocol` or `tlsSocket.npnProtocol` properties can be -checked to determine the negotiated protocol. +`tlsSocket.authorizationError` property. If ALPN was used, the +`tlsSocket.alpnProtocol` property can be checked to determine the negotiated +protocol. ### tlsSocket.address() <!-- YAML @@ -841,8 +832,7 @@ changes: description: The `lookup` option is supported now. - version: v8.0.0 pr-url: https://github.com/nodejs/node/pull/11984 - description: The `ALPNProtocols` and `NPNProtocols` options can - be `Uint8Array`s now. + description: The `ALPNProtocols` option can be a `Uint8Array` now. - version: v5.3.0, v4.7.0 pr-url: https://github.com/nodejs/node/pull/4246 description: The `secureContext` option is supported now. @@ -869,12 +859,6 @@ changes: verified against the list of supplied CAs. An `'error'` event is emitted if verification fails; `err.code` contains the OpenSSL error code. Defaults to `true`. - * `NPNProtocols` {string[]|Buffer[]|Uint8Array[]|Buffer|Uint8Array} - An array of strings, `Buffer`s or `Uint8Array`s, or a single `Buffer` or - `Uint8Array` containing supported NPN protocols. `Buffer`s should have the - format `[len][name][len][name]...` e.g. `0x05hello0x05world`, where the - first byte is the length of the next protocol name. Passing an array is - usually much simpler, e.g. `['hello', 'world']`. * `ALPNProtocols`: {string[]|Buffer[]|Uint8Array[]|Buffer|Uint8Array} An array of strings, `Buffer`s or `Uint8Array`s, or a single `Buffer` or `Uint8Array` containing the supported ALPN protocols. `Buffer`s should have @@ -1116,8 +1100,7 @@ changes: description: The `options` parameter can now include `clientCertEngine`. - version: v8.0.0 pr-url: https://github.com/nodejs/node/pull/11984 - description: The `ALPNProtocols` and `NPNProtocols` options can - be `Uint8Array`s now. + description: The `ALPNProtocols` option can be a `Uint8Array` now. - version: v5.0.0 pr-url: https://github.com/nodejs/node/pull/2564 description: ALPN options are supported now. @@ -1136,13 +1119,6 @@ changes: * `rejectUnauthorized` {boolean} If not `false` the server will reject any connection which is not authorized with the list of supplied CAs. This option only has an effect if `requestCert` is `true`. Defaults to `true`. - * `NPNProtocols` {string[]|Buffer[]|Uint8Array[]|Buffer|Uint8Array} - An array of strings, `Buffer`s or `Uint8Array`s, or a single `Buffer` or - `Uint8Array` containing supported NPN protocols. `Buffer`s should have the - format `[len][name][len][name]...` e.g. `0x05hello0x05world`, where the - first byte is the length of the next protocol name. Passing an array is - usually much simpler, e.g. `['hello', 'world']`. - (Protocols should be ordered by their priority.) * `ALPNProtocols`: {string[]|Buffer[]|Uint8Array[]|Buffer|Uint8Array} An array of strings, `Buffer`s or `Uint8Array`s, or a single `Buffer` or `Uint8Array` containing the supported ALPN protocols. `Buffer`s should have @@ -1150,9 +1126,6 @@ changes: first byte is the length of the next protocol name. Passing an array is usually much simpler, e.g. `['hello', 'world']`. (Protocols should be ordered by their priority.) - When the server receives both NPN and ALPN extensions from the client, - ALPN takes precedence over NPN and the server does not send an NPN - extension to the client. * `SNICallback(servername, cb)` {Function} A function that will be called if the client supports SNI TLS extension. Two arguments will be passed when called: `servername` and `cb`. `SNICallback` should invoke `cb(null, ctx)`, @@ -1333,7 +1306,6 @@ changes: * `server` {net.Server} An optional [`net.Server`][] instance * `requestCert`: Optional, see [`tls.createServer()`][] * `rejectUnauthorized`: Optional, see [`tls.createServer()`][] - * `NPNProtocols`: Optional, see [`tls.createServer()`][] * `ALPNProtocols`: Optional, see [`tls.createServer()`][] * `SNICallback`: Optional, see [`tls.createServer()`][] * `session` {Buffer} An optional `Buffer` instance containing a TLS session. diff --git a/lib/_tls_wrap.js b/lib/_tls_wrap.js index 686e109ca3..2e6b2e8da5 100644 --- a/lib/_tls_wrap.js +++ b/lib/_tls_wrap.js @@ -294,8 +294,6 @@ function initRead(tls, wrapped) { function TLSSocket(socket, opts) { const tlsOptions = Object.assign({}, opts); - if (tlsOptions.NPNProtocols) - tls.convertNPNProtocols(tlsOptions.NPNProtocols, tlsOptions); if (tlsOptions.ALPNProtocols) tls.convertALPNProtocols(tlsOptions.ALPNProtocols, tlsOptions); @@ -306,7 +304,6 @@ function TLSSocket(socket, opts) { this._controlReleased = false; this._SNICallback = null; this.servername = null; - this.npnProtocol = null; this.alpnProtocol = null; this.authorized = false; this.authorizationError = null; @@ -529,9 +526,6 @@ TLSSocket.prototype._init = function(socket, wrap) { ssl.enableCertCb(); } - if (process.features.tls_npn && options.NPNProtocols) - ssl.setNPNProtocols(options.NPNProtocols); - if (process.features.tls_alpn && options.ALPNProtocols) { // keep reference in secureContext not to be GC-ed ssl._secureContext.alpnBuffer = options.ALPNProtocols; @@ -630,10 +624,6 @@ TLSSocket.prototype._releaseControl = function() { }; TLSSocket.prototype._finishInit = function() { - if (process.features.tls_npn) { - this.npnProtocol = this._handle.getNegotiatedProtocol(); - } - if (process.features.tls_alpn) { this.alpnProtocol = this._handle.getALPNNegotiatedProtocol(); } @@ -790,7 +780,6 @@ function tlsConnectionListener(rawSocket) { requestCert: this.requestCert, rejectUnauthorized: this.rejectUnauthorized, handshakeTimeout: this[kHandshakeTimeout], - NPNProtocols: this.NPNProtocols, ALPNProtocols: this.ALPNProtocols, SNICallback: this[kSNICallback] || SNICallback }); @@ -982,7 +971,6 @@ Server.prototype.setOptions = function(options) { else this.honorCipherOrder = true; if (secureOptions) this.secureOptions = secureOptions; - if (options.NPNProtocols) tls.convertNPNProtocols(options.NPNProtocols, this); if (options.ALPNProtocols) tls.convertALPNProtocols(options.ALPNProtocols, this); if (options.sessionIdContext) { @@ -1149,7 +1137,6 @@ exports.connect = function(...args /* [port,] [host,] [options,] [cb] */) { requestCert: true, rejectUnauthorized: options.rejectUnauthorized !== false, session: options.session, - NPNProtocols: options.NPNProtocols, ALPNProtocols: options.ALPNProtocols, requestOCSP: options.requestOCSP }); diff --git a/lib/https.js b/lib/https.js index b9e2d56492..4cca2fb9ee 100644 --- a/lib/https.js +++ b/lib/https.js @@ -49,10 +49,6 @@ function Server(opts, requestListener) { } opts = util._extend({}, opts); - if (process.features.tls_npn && !opts.NPNProtocols) { - opts.NPNProtocols = ['http/1.1', 'http/1.0']; - } - if (process.features.tls_alpn && !opts.ALPNProtocols) { // http/1.0 is not defined as Protocol IDs in IANA // http://www.iana.org/assignments/tls-extensiontype-values @@ -586,8 +586,8 @@ 'mkssldef_flags': [ # Categories to export. '-CAES,BF,BIO,DES,DH,DSA,EC,ECDH,ECDSA,ENGINE,EVP,HMAC,MD4,MD5,' - 'NEXTPROTONEG,PSK,RC2,RC4,RSA,SHA,SHA0,SHA1,SHA256,SHA512,SOCK,' - 'STDIO,TLSEXT,FP_API', + 'PSK,RC2,RC4,RSA,SHA,SHA0,SHA1,SHA256,SHA512,SOCK,STDIO,TLSEXT,' + 'FP_API', # Defines. '-DWIN32', # Symbols to filter from the export list. @@ -103,8 +103,6 @@ struct PackageConfig { V(contextify_context_private_symbol, "node:contextify:context") \ V(contextify_global_private_symbol, "node:contextify:global") \ V(decorated_private_symbol, "node:decorated") \ - V(npn_buffer_private_symbol, "node:npnBuffer") \ - V(selected_npn_buffer_private_symbol, "node:selectedNpnBuffer") \ V(napi_env, "node:napi:env") \ V(napi_wrapper, "node:napi:wrapper") \ diff --git a/src/node.cc b/src/node.cc index c0ae99f423..b508433115 100644 --- a/src/node.cc +++ b/src/node.cc @@ -2824,13 +2824,6 @@ static Local<Object> GetFeatures(Environment* env) { // TODO(bnoordhuis) ping libuv obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "ipv6"), True(env->isolate())); -#ifndef OPENSSL_NO_NEXTPROTONEG - Local<Boolean> tls_npn = True(env->isolate()); -#else - Local<Boolean> tls_npn = False(env->isolate()); -#endif - obj->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "tls_npn"), tls_npn); - #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation Local<Boolean> tls_alpn = True(env->isolate()); #else diff --git a/src/node_constants.cc b/src/node_constants.cc index 9ecffead53..2eaf622da7 100644 --- a/src/node_constants.cc +++ b/src/node_constants.cc @@ -971,11 +971,6 @@ void DefineOpenSSLConstants(Local<Object> target) { NODE_DEFINE_CONSTANT(target, DH_NOT_SUITABLE_GENERATOR); #endif -#ifndef OPENSSL_NO_NEXTPROTONEG -#define NPN_ENABLED 1 - NODE_DEFINE_CONSTANT(target, NPN_ENABLED); -#endif - #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation #define ALPN_ENABLED 1 NODE_DEFINE_CONSTANT(target, ALPN_ENABLED); diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 7bc8e2b3de..57dbe6861d 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -81,7 +81,6 @@ using v8::DontDelete; using v8::EscapableHandleScope; using v8::Exception; using v8::External; -using v8::False; using v8::FunctionCallbackInfo; using v8::FunctionTemplate; using v8::HandleScope; @@ -231,7 +230,7 @@ static X509_STORE* root_cert_store; // Just to generate static methods template void SSLWrap<TLSWrap>::AddMethods(Environment* env, Local<FunctionTemplate> t); -template void SSLWrap<TLSWrap>::InitNPN(SecureContext* sc); +template void SSLWrap<TLSWrap>::ConfigureSecureContext(SecureContext* sc); template void SSLWrap<TLSWrap>::SetSNIContext(SecureContext* sc); template int SSLWrap<TLSWrap>::SetCACerts(SecureContext* sc); #if OPENSSL_VERSION_NUMBER < 0x10100000L @@ -253,21 +252,6 @@ template void SSLWrap<TLSWrap>::OnClientHello( void* arg, const ClientHelloParser::ClientHello& hello); -#ifndef OPENSSL_NO_NEXTPROTONEG -template int SSLWrap<TLSWrap>::AdvertiseNextProtoCallback( - SSL* s, - const unsigned char** data, - unsigned int* len, - void* arg); -template int SSLWrap<TLSWrap>::SelectNextProtoCallback( - SSL* s, - unsigned char** out, - unsigned char* outlen, - const unsigned char* in, - unsigned int inlen, - void* arg); -#endif - #ifdef NODE__HAVE_TLSEXT_STATUS_CB template int SSLWrap<TLSWrap>::TLSExtStatusCallback(SSL* s, void* arg); #endif @@ -1593,31 +1577,13 @@ void SSLWrap<Base>::AddMethods(Environment* env, Local<FunctionTemplate> t) { env->SetProtoMethod(t, "setMaxSendFragment", SetMaxSendFragment); #endif // SSL_set_max_send_fragment -#ifndef OPENSSL_NO_NEXTPROTONEG - env->SetProtoMethod(t, "getNegotiatedProtocol", GetNegotiatedProto); -#endif // OPENSSL_NO_NEXTPROTONEG - -#ifndef OPENSSL_NO_NEXTPROTONEG - env->SetProtoMethod(t, "setNPNProtocols", SetNPNProtocols); -#endif - env->SetProtoMethod(t, "getALPNNegotiatedProtocol", GetALPNNegotiatedProto); env->SetProtoMethod(t, "setALPNProtocols", SetALPNProtocols); } template <class Base> -void SSLWrap<Base>::InitNPN(SecureContext* sc) { -#ifndef OPENSSL_NO_NEXTPROTONEG - // Server should advertise NPN protocols - SSL_CTX_set_next_protos_advertised_cb(sc->ctx_, - AdvertiseNextProtoCallback, - nullptr); - // Client should select protocol from list of advertised - // If server supports NPN - SSL_CTX_set_next_proto_select_cb(sc->ctx_, SelectNextProtoCallback, nullptr); -#endif // OPENSSL_NO_NEXTPROTONEG - +void SSLWrap<Base>::ConfigureSecureContext(SecureContext* sc) { #ifdef NODE__HAVE_TLSEXT_STATUS_CB // OCSP stapling SSL_CTX_set_tlsext_status_cb(sc->ctx_, TLSExtStatusCallback); @@ -2474,148 +2440,6 @@ void SSLWrap<Base>::GetProtocol(const FunctionCallbackInfo<Value>& args) { } -#ifndef OPENSSL_NO_NEXTPROTONEG -template <class Base> -int SSLWrap<Base>::AdvertiseNextProtoCallback(SSL* s, - const unsigned char** data, - unsigned int* len, - void* arg) { - Base* w = static_cast<Base*>(SSL_get_app_data(s)); - Environment* env = w->env(); - HandleScope handle_scope(env->isolate()); - Context::Scope context_scope(env->context()); - - auto npn_buffer = - w->object()->GetPrivate( - env->context(), - env->npn_buffer_private_symbol()).ToLocalChecked(); - - if (npn_buffer->IsUndefined()) { - // No initialization - no NPN protocols - *data = reinterpret_cast<const unsigned char*>(""); - *len = 0; - } else { - CHECK(Buffer::HasInstance(npn_buffer)); - *data = reinterpret_cast<const unsigned char*>(Buffer::Data(npn_buffer)); - *len = Buffer::Length(npn_buffer); - } - - return SSL_TLSEXT_ERR_OK; -} - - -template <class Base> -int SSLWrap<Base>::SelectNextProtoCallback(SSL* s, - unsigned char** out, - unsigned char* outlen, - const unsigned char* in, - unsigned int inlen, - void* arg) { - Base* w = static_cast<Base*>(SSL_get_app_data(s)); - Environment* env = w->env(); - HandleScope handle_scope(env->isolate()); - Context::Scope context_scope(env->context()); - - auto npn_buffer = - w->object()->GetPrivate( - env->context(), - env->npn_buffer_private_symbol()).ToLocalChecked(); - - if (npn_buffer->IsUndefined()) { - // We should at least select one protocol - // If server is using NPN - *out = reinterpret_cast<unsigned char*>(const_cast<char*>("http/1.1")); - *outlen = 8; - - // set status: unsupported - CHECK( - w->object()->SetPrivate( - env->context(), - env->selected_npn_buffer_private_symbol(), - False(env->isolate())).FromJust()); - - return SSL_TLSEXT_ERR_OK; - } - - CHECK(Buffer::HasInstance(npn_buffer)); - const unsigned char* npn_protos = - reinterpret_cast<const unsigned char*>(Buffer::Data(npn_buffer)); - size_t len = Buffer::Length(npn_buffer); - - int status = SSL_select_next_proto(out, outlen, in, inlen, npn_protos, len); - Local<Value> result; - switch (status) { - case OPENSSL_NPN_UNSUPPORTED: - result = Null(env->isolate()); - break; - case OPENSSL_NPN_NEGOTIATED: - result = OneByteString(env->isolate(), *out, *outlen); - break; - case OPENSSL_NPN_NO_OVERLAP: - result = False(env->isolate()); - break; - default: - break; - } - - CHECK( - w->object()->SetPrivate( - env->context(), - env->selected_npn_buffer_private_symbol(), - result).FromJust()); - - return SSL_TLSEXT_ERR_OK; -} - - -template <class Base> -void SSLWrap<Base>::GetNegotiatedProto( - const FunctionCallbackInfo<Value>& args) { - Base* w; - ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder()); - Environment* env = w->env(); - - if (w->is_client()) { - auto selected_npn_buffer = - w->object()->GetPrivate( - env->context(), - env->selected_npn_buffer_private_symbol()).ToLocalChecked(); - args.GetReturnValue().Set(selected_npn_buffer); - return; - } - - const unsigned char* npn_proto; - unsigned int npn_proto_len; - - SSL_get0_next_proto_negotiated(w->ssl_, &npn_proto, &npn_proto_len); - - if (!npn_proto) - return args.GetReturnValue().Set(false); - - args.GetReturnValue().Set( - OneByteString(args.GetIsolate(), npn_proto, npn_proto_len)); -} - - -template <class Base> -void SSLWrap<Base>::SetNPNProtocols(const FunctionCallbackInfo<Value>& args) { - Base* w; - ASSIGN_OR_RETURN_UNWRAP(&w, args.Holder()); - Environment* env = w->env(); - - if (args.Length() < 1) - return env->ThrowTypeError("NPN protocols argument is mandatory"); - - THROW_AND_RETURN_IF_NOT_BUFFER(args[0], "NPN protocols"); - - CHECK( - w->object()->SetPrivate( - env->context(), - env->npn_buffer_private_symbol(), - args[0]).FromJust()); -} -#endif // OPENSSL_NO_NEXTPROTONEG - #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation template <class Base> int SSLWrap<Base>::SelectALPNCallback(SSL* s, @@ -2883,7 +2707,7 @@ void SSLWrap<Base>::DestroySSL() { template <class Base> void SSLWrap<Base>::SetSNIContext(SecureContext* sc) { - InitNPN(sc); + ConfigureSecureContext(sc); CHECK_EQ(SSL_set_SSL_CTX(ssl_, sc->ctx_), sc->ctx_); SetCACerts(sc); diff --git a/src/node_crypto.h b/src/node_crypto.h index 1b2170ef85..c8cf558d60 100644 --- a/src/node_crypto.h +++ b/src/node_crypto.h @@ -249,7 +249,7 @@ class SSLWrap { static const int64_t kExternalSize = 4448 + 1024 + 42 * 1024; #endif - static void InitNPN(SecureContext* sc); + static void ConfigureSecureContext(SecureContext* sc); static void AddMethods(Environment* env, v8::Local<v8::FunctionTemplate> t); #if OPENSSL_VERSION_NUMBER < 0x10100000L @@ -295,22 +295,6 @@ class SSLWrap { const v8::FunctionCallbackInfo<v8::Value>& args); #endif // SSL_set_max_send_fragment -#ifndef OPENSSL_NO_NEXTPROTONEG - static void GetNegotiatedProto( - const v8::FunctionCallbackInfo<v8::Value>& args); - static void SetNPNProtocols(const v8::FunctionCallbackInfo<v8::Value>& args); - static int AdvertiseNextProtoCallback(SSL* s, - const unsigned char** data, - unsigned int* len, - void* arg); - static int SelectNextProtoCallback(SSL* s, - unsigned char** out, - unsigned char* outlen, - const unsigned char* in, - unsigned int inlen, - void* arg); -#endif // OPENSSL_NO_NEXTPROTONEG - static void GetALPNNegotiatedProto( const v8::FunctionCallbackInfo<v8::Value>& args); static void SetALPNProtocols(const v8::FunctionCallbackInfo<v8::Value>& args); diff --git a/src/tls_wrap.cc b/src/tls_wrap.cc index cddef66c44..05154d6ff5 100644 --- a/src/tls_wrap.cc +++ b/src/tls_wrap.cc @@ -135,7 +135,7 @@ void TLSWrap::InitSSL() { } #endif // SSL_CTRL_SET_TLSEXT_SERVERNAME_CB - InitNPN(sc_); + ConfigureSecureContext(sc_); SSL_set_cert_cb(ssl_, SSLWrap<TLSWrap>::SSLCertCallback, this); diff --git a/test/parallel/test-https-argument-of-creating.js b/test/parallel/test-https-argument-of-creating.js index 5a4150eb1c..0630028406 100644 --- a/test/parallel/test-https-argument-of-creating.js +++ b/test/parallel/test-https-argument-of-creating.js @@ -12,12 +12,13 @@ const dftProtocol = {}; // test for immutable `opts` { - const opts = { foo: 'bar', NPNProtocols: [ 'http/1.1' ] }; + const opts = { foo: 'bar', ALPNProtocols: [ 'http/1.1' ] }; const server = https.createServer(opts); - tls.convertNPNProtocols([ 'http/1.1' ], dftProtocol); - assert.deepStrictEqual(opts, { foo: 'bar', NPNProtocols: [ 'http/1.1' ] }); - assert.strictEqual(server.NPNProtocols.compare(dftProtocol.NPNProtocols), 0); + tls.convertALPNProtocols([ 'http/1.1' ], dftProtocol); + assert.deepStrictEqual(opts, { foo: 'bar', ALPNProtocols: [ 'http/1.1' ] }); + assert.strictEqual(server.ALPNProtocols.compare(dftProtocol.ALPNProtocols), + 0); } @@ -26,8 +27,9 @@ const dftProtocol = {}; const mustNotCall = common.mustNotCall(); const server = https.createServer(mustNotCall); - tls.convertNPNProtocols([ 'http/1.1', 'http/1.0' ], dftProtocol); - assert.strictEqual(server.NPNProtocols.compare(dftProtocol.NPNProtocols), 0); + tls.convertALPNProtocols([ 'http/1.1' ], dftProtocol); + assert.strictEqual(server.ALPNProtocols.compare(dftProtocol.ALPNProtocols), + 0); assert.strictEqual(server.listeners('request').length, 1); assert.strictEqual(server.listeners('request')[0], mustNotCall); } @@ -37,6 +39,7 @@ const dftProtocol = {}; { const server = https.createServer(); - assert.strictEqual(server.NPNProtocols.compare(dftProtocol.NPNProtocols), 0); + assert.strictEqual(server.ALPNProtocols.compare(dftProtocol.ALPNProtocols), + 0); assert.strictEqual(server.listeners('request').length, 0); } diff --git a/test/parallel/test-tls-alpn-server-client.js b/test/parallel/test-tls-alpn-server-client.js index 44699b2053..8b8ae3e5cf 100644 --- a/test/parallel/test-tls-alpn-server-client.js +++ b/test/parallel/test-tls-alpn-server-client.js @@ -4,9 +4,9 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -if (!process.features.tls_alpn || !process.features.tls_npn) { +if (!process.features.tls_alpn) { common.skip( - 'Skipping because node compiled without NPN or ALPN feature of OpenSSL.'); + 'Skipping because node compiled without ALPN feature of OpenSSL.'); } const assert = require('assert'); @@ -21,9 +21,7 @@ const serverIP = common.localhostIPv4; function checkResults(result, expected) { assert.strictEqual(result.server.ALPN, expected.server.ALPN); - assert.strictEqual(result.server.NPN, expected.server.NPN); assert.strictEqual(result.client.ALPN, expected.client.ALPN); - assert.strictEqual(result.client.NPN, expected.client.NPN); } function runTest(clientsOptions, serverOptions, cb) { @@ -32,7 +30,7 @@ function runTest(clientsOptions, serverOptions, cb) { const results = []; let index = 0; const server = tls.createServer(serverOptions, function(c) { - results[index].server = { ALPN: c.alpnProtocol, NPN: c.npnProtocol }; + results[index].server = { ALPN: c.alpnProtocol }; }); server.listen(0, serverIP, function() { @@ -47,8 +45,7 @@ function runTest(clientsOptions, serverOptions, cb) { results[index] = {}; const client = tls.connect(opt, function() { - results[index].client = { ALPN: client.alpnProtocol, - NPN: client.npnProtocol }; + results[index].client = { ALPN: client.alpnProtocol }; client.destroy(); if (options.length) { index++; @@ -62,113 +59,42 @@ function runTest(clientsOptions, serverOptions, cb) { } -// Server: ALPN/NPN, Client: ALPN/NPN +// Server: ALPN, Client: ALPN function Test1() { const serverOptions = { ALPNProtocols: ['a', 'b', 'c'], - NPNProtocols: ['a', 'b', 'c'] }; const clientsOptions = [{ ALPNProtocols: ['a', 'b', 'c'], - NPNProtocols: ['a', 'b', 'c'] }, { ALPNProtocols: ['c', 'b', 'e'], - NPNProtocols: ['c', 'b', 'e'] }, { ALPNProtocols: ['first-priority-unsupported', 'x', 'y'], - NPNProtocols: ['first-priority-unsupported', 'x', 'y'] }]; runTest(clientsOptions, serverOptions, function(results) { // 'a' is selected by ALPN checkResults(results[0], - { server: { ALPN: 'a', NPN: false }, - client: { ALPN: 'a', NPN: undefined } }); + { server: { ALPN: 'a' }, + client: { ALPN: 'a' } }); // 'b' is selected by ALPN checkResults(results[1], - { server: { ALPN: 'b', NPN: false }, - client: { ALPN: 'b', NPN: undefined } }); + { server: { ALPN: 'b' }, + client: { ALPN: 'b' } }); // nothing is selected by ALPN checkResults(results[2], - { server: { ALPN: false, NPN: 'first-priority-unsupported' }, - client: { ALPN: false, NPN: false } }); + { server: { ALPN: false }, + client: { ALPN: false } }); // execute next test Test2(); }); } -// Server: ALPN/NPN, Client: ALPN +// Server: ALPN, Client: Nothing function Test2() { const serverOptions = { ALPNProtocols: ['a', 'b', 'c'], - NPNProtocols: ['a', 'b', 'c'] - }; - - const clientsOptions = [{ - ALPNProtocols: ['a', 'b', 'c'] - }, { - ALPNProtocols: ['c', 'b', 'e'] - }, { - ALPNProtocols: ['first-priority-unsupported', 'x', 'y'] - }]; - - runTest(clientsOptions, serverOptions, function(results) { - // 'a' is selected by ALPN - checkResults(results[0], - { server: { ALPN: 'a', NPN: false }, - client: { ALPN: 'a', NPN: undefined } }); - // 'b' is selected by ALPN - checkResults(results[1], - { server: { ALPN: 'b', NPN: false }, - client: { ALPN: 'b', NPN: undefined } }); - // nothing is selected by ALPN - checkResults(results[2], - { server: { ALPN: false, NPN: 'http/1.1' }, - client: { ALPN: false, NPN: false } }); - // execute next test - Test3(); - }); -} - -// Server: ALPN/NPN, Client: NPN -function Test3() { - const serverOptions = { - ALPNProtocols: ['a', 'b', 'c'], - NPNProtocols: ['a', 'b', 'c'] - }; - - const clientsOptions = [{ - NPNProtocols: ['a', 'b', 'c'] - }, { - NPPNProtocols: ['c', 'b', 'e'] - }, { - NPPNProtocols: ['first-priority-unsupported', 'x', 'y'] - }]; - - runTest(clientsOptions, serverOptions, function(results) { - // 'a' is selected by NPN - checkResults(results[0], - { server: { ALPN: false, NPN: 'a' }, - client: { ALPN: false, NPN: 'a' } }); - // nothing is selected by ALPN - checkResults(results[1], - { server: { ALPN: false, NPN: 'http/1.1' }, - client: { ALPN: false, NPN: false } }); - // nothing is selected by ALPN - checkResults(results[2], - { server: { ALPN: false, NPN: 'http/1.1' }, - client: { ALPN: false, NPN: false } }); - // execute next test - Test4(); - }); -} - -// Server: ALPN/NPN, Client: Nothing -function Test4() { - const serverOptions = { - ALPNProtocols: ['a', 'b', 'c'], - NPNProtocols: ['a', 'b', 'c'] }; const clientsOptions = [{}, {}, {}]; @@ -176,357 +102,66 @@ function Test4() { runTest(clientsOptions, serverOptions, function(results) { // nothing is selected by ALPN checkResults(results[0], - { server: { ALPN: false, NPN: 'http/1.1' }, - client: { ALPN: false, NPN: false } }); + { server: { ALPN: false }, + client: { ALPN: false } }); // nothing is selected by ALPN checkResults(results[1], - { server: { ALPN: false, NPN: 'http/1.1' }, - client: { ALPN: false, NPN: false } }); - // nothing is selected by ALPN - checkResults(results[2], - { server: { ALPN: false, NPN: 'http/1.1' }, - client: { ALPN: false, NPN: false } }); - // execute next test - Test5(); - }); -} - -// Server: ALPN, Client: ALPN/NPN -function Test5() { - const serverOptions = { - ALPNProtocols: ['a', 'b', 'c'] - }; - - const clientsOptions = [{ - ALPNProtocols: ['a', 'b', 'c'], - NPNProtocols: ['a', 'b', 'c'] - }, { - ALPNProtocols: ['c', 'b', 'e'], - NPNProtocols: ['c', 'b', 'e'] - }, { - ALPNProtocols: ['first-priority-unsupported', 'x', 'y'], - NPNProtocols: ['first-priority-unsupported', 'x', 'y'] - }]; - - runTest(clientsOptions, serverOptions, function(results) { - // 'a' is selected by ALPN - checkResults(results[0], { server: { ALPN: 'a', NPN: false }, - client: { ALPN: 'a', NPN: undefined } }); - // 'b' is selected by ALPN - checkResults(results[1], { server: { ALPN: 'b', NPN: false }, - client: { ALPN: 'b', NPN: undefined } }); - // nothing is selected by ALPN - checkResults(results[2], { server: { ALPN: false, - NPN: 'first-priority-unsupported' }, - client: { ALPN: false, NPN: false } }); - // execute next test - Test6(); - }); -} - -// Server: ALPN, Client: ALPN -function Test6() { - const serverOptions = { - ALPNProtocols: ['a', 'b', 'c'] - }; - - const clientsOptions = [{ - ALPNProtocols: ['a', 'b', 'c'] - }, { - ALPNProtocols: ['c', 'b', 'e'] - }, { - ALPNProtocols: ['first-priority-unsupported', 'x', 'y'] - }]; - - runTest(clientsOptions, serverOptions, function(results) { - // 'a' is selected by ALPN - checkResults(results[0], { server: { ALPN: 'a', NPN: false }, - client: { ALPN: 'a', NPN: undefined } }); - // 'b' is selected by ALPN - checkResults(results[1], { server: { ALPN: 'b', NPN: false }, - client: { ALPN: 'b', NPN: undefined } }); - // nothing is selected by ALPN - checkResults(results[2], { server: { ALPN: false, NPN: 'http/1.1' }, - client: { ALPN: false, NPN: false } }); - // execute next test - Test7(); - }); -} - -// Server: ALPN, Client: NPN -function Test7() { - const serverOptions = { - ALPNProtocols: ['a', 'b', 'c'] - }; - - const clientsOptions = [{ - NPNProtocols: ['a', 'b', 'c'] - }, { - NPNProtocols: ['c', 'b', 'e'] - }, { - NPNProtocols: ['first-priority-unsupported', 'x', 'y'] - }]; - - runTest(clientsOptions, serverOptions, function(results) { - // nothing is selected by ALPN - checkResults(results[0], { server: { ALPN: false, NPN: 'a' }, - client: { ALPN: false, NPN: false } }); - // nothing is selected by ALPN - checkResults(results[1], { server: { ALPN: false, NPN: 'c' }, - client: { ALPN: false, NPN: false } }); - // nothing is selected by ALPN - checkResults(results[2], - { server: { ALPN: false, NPN: 'first-priority-unsupported' }, - client: { ALPN: false, NPN: false } }); - // execute next test - Test8(); - }); -} - -// Server: ALPN, Client: Nothing -function Test8() { - const serverOptions = { - ALPNProtocols: ['a', 'b', 'c'] - }; - - const clientsOptions = [{}, {}, {}]; - - runTest(clientsOptions, serverOptions, function(results) { - // nothing is selected by ALPN - checkResults(results[0], { server: { ALPN: false, NPN: 'http/1.1' }, - client: { ALPN: false, NPN: false } }); - // nothing is selected by ALPN - checkResults(results[1], { server: { ALPN: false, NPN: 'http/1.1' }, - client: { ALPN: false, NPN: false } }); + { server: { ALPN: false }, + client: { ALPN: false } }); // nothing is selected by ALPN checkResults(results[2], - { server: { ALPN: false, NPN: 'http/1.1' }, - client: { ALPN: false, NPN: false } }); - // execute next test - Test9(); - }); -} - -// Server: NPN, Client: ALPN/NPN -function Test9() { - const serverOptions = { - NPNProtocols: ['a', 'b', 'c'] - }; - - const clientsOptions = [{ - ALPNrotocols: ['a', 'b', 'c'], - NPNProtocols: ['a', 'b', 'c'] - }, { - ALPNProtocols: ['c', 'b', 'e'], - NPNProtocols: ['c', 'b', 'e'] - }, { - ALPNProtocols: ['first-priority-unsupported', 'x', 'y'], - NPNProtocols: ['first-priority-unsupported', 'x', 'y'] - }]; - - runTest(clientsOptions, serverOptions, function(results) { - // 'a' is selected by NPN - checkResults(results[0], { server: { ALPN: false, NPN: 'a' }, - client: { ALPN: false, NPN: 'a' } }); - // 'b' is selected by NPN - checkResults(results[1], { server: { ALPN: false, NPN: 'b' }, - client: { ALPN: false, NPN: 'b' } }); - // nothing is selected - checkResults(results[2], - { server: { ALPN: false, NPN: 'first-priority-unsupported' }, - client: { ALPN: false, NPN: false } }); - // execute next test - Test10(); - }); -} - -// Server: NPN, Client: ALPN -function Test10() { - const serverOptions = { - NPNProtocols: ['a', 'b', 'c'] - }; - - const clientsOptions = [{ - ALPNProtocols: ['a', 'b', 'c'] - }, { - ALPNProtocols: ['c', 'b', 'e'] - }, { - ALPNProtocols: ['first-priority-unsupported', 'x', 'y'] - }]; - - runTest(clientsOptions, serverOptions, function(results) { - // nothing is selected - checkResults(results[0], { server: { ALPN: false, NPN: 'http/1.1' }, - client: { ALPN: false, NPN: false } }); - // nothing is selected - checkResults(results[1], { server: { ALPN: false, NPN: 'http/1.1' }, - client: { ALPN: false, NPN: false } }); - // nothing is selected - checkResults(results[2], { server: { ALPN: false, NPN: 'http/1.1' }, - client: { ALPN: false, NPN: false } }); + { server: { ALPN: false }, + client: { ALPN: false } }); // execute next test - Test11(); - }); -} - -// Server: NPN, Client: NPN -function Test11() { - const serverOptions = { - NPNProtocols: ['a', 'b', 'c'] - }; - - const clientsOptions = [{ - NPNProtocols: ['a', 'b', 'c'] - }, { - NPNProtocols: ['c', 'b', 'e'] - }, { - NPNProtocols: ['first-priority-unsupported', 'x', 'y'] - }]; - - runTest(clientsOptions, serverOptions, function(results) { - // 'a' is selected by NPN - checkResults(results[0], { server: { ALPN: false, NPN: 'a' }, - client: { ALPN: false, NPN: 'a' } }); - // 'b' is selected by NPN - checkResults(results[1], { server: { ALPN: false, NPN: 'b' }, - client: { ALPN: false, NPN: 'b' } }); - // nothing is selected - checkResults(results[2], - { server: { ALPN: false, NPN: 'first-priority-unsupported' }, - client: { ALPN: false, NPN: false } }); - // execute next test - Test12(); - }); -} - -// Server: NPN, Client: Nothing -function Test12() { - const serverOptions = { - NPNProtocols: ['a', 'b', 'c'] - }; - - const clientsOptions = [{}, {}, {}]; - - runTest(clientsOptions, serverOptions, function(results) { - // nothing is selected - checkResults(results[0], { server: { ALPN: false, NPN: 'http/1.1' }, - client: { ALPN: false, NPN: false } }); - // nothing is selected - checkResults(results[1], { server: { ALPN: false, NPN: 'http/1.1' }, - client: { ALPN: false, NPN: false } }); - // nothing is selected - checkResults(results[2], - { server: { ALPN: false, NPN: 'http/1.1' }, - client: { ALPN: false, NPN: false } }); - // execute next test - Test13(); + Test3(); }); } -// Server: Nothing, Client: ALPN/NPN -function Test13() { +// Server: Nothing, Client: ALPN +function Test3() { const serverOptions = {}; const clientsOptions = [{ ALPNrotocols: ['a', 'b', 'c'], - NPNProtocols: ['a', 'b', 'c'] }, { ALPNProtocols: ['c', 'b', 'e'], - NPNProtocols: ['c', 'b', 'e'] }, { ALPNProtocols: ['first-priority-unsupported', 'x', 'y'], - NPNProtocols: ['first-priority-unsupported', 'x', 'y'] }]; runTest(clientsOptions, serverOptions, function(results) { // nothing is selected - checkResults(results[0], { server: { ALPN: false, NPN: 'a' }, - client: { ALPN: false, NPN: false } }); + checkResults(results[0], { server: { ALPN: false }, + client: { ALPN: false } }); // nothing is selected - checkResults(results[1], { server: { ALPN: false, NPN: 'c' }, - client: { ALPN: false, NPN: false } }); + checkResults(results[1], { server: { ALPN: false }, + client: { ALPN: false } }); // nothing is selected checkResults(results[2], - { server: { ALPN: false, NPN: 'first-priority-unsupported' }, - client: { ALPN: false, NPN: false } }); + { server: { ALPN: false }, + client: { ALPN: false } }); // execute next test - Test14(); - }); -} - -// Server: Nothing, Client: ALPN -function Test14() { - const serverOptions = {}; - - const clientsOptions = [{ - ALPNrotocols: ['a', 'b', 'c'] - }, { - ALPNProtocols: ['c', 'b', 'e'] - }, { - ALPNProtocols: ['first-priority-unsupported', 'x', 'y'] - }]; - - runTest(clientsOptions, serverOptions, function(results) { - // nothing is selected - checkResults(results[0], { server: { ALPN: false, NPN: 'http/1.1' }, - client: { ALPN: false, NPN: false } }); - // nothing is selected - checkResults(results[1], { server: { ALPN: false, NPN: 'http/1.1' }, - client: { ALPN: false, NPN: false } }); - // nothing is selected - checkResults(results[2], - { server: { ALPN: false, NPN: 'http/1.1' }, - client: { ALPN: false, NPN: false } }); - // execute next test - Test15(); - }); -} - -// Server: Nothing, Client: NPN -function Test15() { - const serverOptions = {}; - - const clientsOptions = [{ - NPNProtocols: ['a', 'b', 'c'] - }, { - NPNProtocols: ['c', 'b', 'e'] - }, { - NPNProtocols: ['first-priority-unsupported', 'x', 'y'] - }]; - - runTest(clientsOptions, serverOptions, function(results) { - // nothing is selected - checkResults(results[0], { server: { ALPN: false, NPN: 'a' }, - client: { ALPN: false, NPN: false } }); - // nothing is selected - checkResults(results[1], { server: { ALPN: false, NPN: 'c' }, - client: { ALPN: false, NPN: false } }); - // nothing is selected - checkResults(results[2], - { server: { ALPN: false, NPN: 'first-priority-unsupported' }, - client: { ALPN: false, NPN: false } }); - // execute next test - Test16(); + Test4(); }); } // Server: Nothing, Client: Nothing -function Test16() { +function Test4() { const serverOptions = {}; const clientsOptions = [{}, {}, {}]; runTest(clientsOptions, serverOptions, function(results) { // nothing is selected - checkResults(results[0], { server: { ALPN: false, NPN: 'http/1.1' }, - client: { ALPN: false, NPN: false } }); + checkResults(results[0], { server: { ALPN: false }, + client: { ALPN: false } }); // nothing is selected - checkResults(results[1], { server: { ALPN: false, NPN: 'http/1.1' }, - client: { ALPN: false, NPN: false } }); + checkResults(results[1], { server: { ALPN: false }, + client: { ALPN: false } }); // nothing is selected checkResults(results[2], - { server: { ALPN: false, NPN: 'http/1.1' }, - client: { ALPN: false, NPN: false } }); + { server: { ALPN: false }, + client: { ALPN: false } }); }); } diff --git a/test/parallel/test-tls-npn-server-client.js b/test/parallel/test-tls-npn-server-client.js deleted file mode 100644 index 518e881f9c..0000000000 --- a/test/parallel/test-tls-npn-server-client.js +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -'use strict'; -const common = require('../common'); -if (!common.hasCrypto) - common.skip('missing crypto'); - -if (!process.features.tls_npn) - common.skip('Skipping because node compiled without NPN feature of OpenSSL.'); - -const assert = require('assert'); -const tls = require('tls'); -const fixtures = require('../common/fixtures'); - -function loadPEM(n) { - return fixtures.readKey(`${n}.pem`); -} - -const serverOptions = { - key: loadPEM('agent2-key'), - cert: loadPEM('agent2-cert'), - crl: loadPEM('ca2-crl'), - SNICallback: function(servername, cb) { - cb(null, tls.createSecureContext({ - key: loadPEM('agent2-key'), - cert: loadPEM('agent2-cert'), - crl: loadPEM('ca2-crl'), - })); - }, - NPNProtocols: ['a', 'b', 'c'] -}; - -const clientsOptions = [{ - port: undefined, - key: serverOptions.key, - cert: serverOptions.cert, - crl: serverOptions.crl, - NPNProtocols: ['a', 'b', 'c'], - rejectUnauthorized: false -}, { - port: undefined, - key: serverOptions.key, - cert: serverOptions.cert, - crl: serverOptions.crl, - NPNProtocols: ['c', 'b', 'e'], - rejectUnauthorized: false -}, { - port: undefined, - key: serverOptions.key, - cert: serverOptions.cert, - crl: serverOptions.crl, - rejectUnauthorized: false -}, { - port: undefined, - key: serverOptions.key, - cert: serverOptions.cert, - crl: serverOptions.crl, - NPNProtocols: ['first-priority-unsupported', 'x', 'y'], - rejectUnauthorized: false -}]; - -const serverResults = []; -const clientsResults = []; - -const server = tls.createServer(serverOptions, function(c) { - serverResults.push(c.npnProtocol); -}); -server.listen(0, startTest); - -function startTest() { - function connectClient(options, callback) { - options.port = server.address().port; - const client = tls.connect(options, function() { - clientsResults.push(client.npnProtocol); - client.destroy(); - - callback(); - }); - } - - connectClient(clientsOptions[0], function() { - connectClient(clientsOptions[1], function() { - connectClient(clientsOptions[2], function() { - connectClient(clientsOptions[3], function() { - server.close(); - }); - }); - }); - }); -} - -process.on('exit', function() { - assert.strictEqual(serverResults[0], clientsResults[0]); - assert.strictEqual(serverResults[1], clientsResults[1]); - assert.strictEqual(serverResults[2], 'http/1.1'); - assert.strictEqual(clientsResults[2], false); - assert.strictEqual(serverResults[3], 'first-priority-unsupported'); - assert.strictEqual(clientsResults[3], false); -}); diff --git a/test/parallel/test-tls-socket-constructor-alpn-npn-options-parsing.js b/test/parallel/test-tls-socket-constructor-alpn-options-parsing.js index fec06c94ee..edbc9f63cf 100644 --- a/test/parallel/test-tls-socket-constructor-alpn-npn-options-parsing.js +++ b/test/parallel/test-tls-socket-constructor-alpn-options-parsing.js @@ -1,7 +1,6 @@ 'use strict'; -// Test that TLSSocket can take arrays of strings for ALPNProtocols and -// NPNProtocols. +// Test that TLSSocket can take arrays of strings for ALPNProtocols. const common = require('../common'); @@ -12,12 +11,8 @@ const tls = require('tls'); new tls.TLSSocket(null, { ALPNProtocols: ['http/1.1'], - NPNProtocols: ['http/1.1'] }); -if (!process.features.tls_npn) - common.skip('node compiled without NPN feature of OpenSSL'); - if (!process.features.tls_alpn) common.skip('node compiled without ALPN feature of OpenSSL'); @@ -37,17 +32,15 @@ const server = net.createServer(common.mustCall((s) => { key, cert, ALPNProtocols: ['http/1.1'], - NPNProtocols: ['http/1.1'] }); tlsSocket.on('secure', common.mustCall(() => { protocols.push({ alpnProtocol: tlsSocket.alpnProtocol, - npnProtocol: tlsSocket.npnProtocol }); tlsSocket.end(); })); -}, 2)); +})); server.listen(0, common.mustCall(() => { const alpnOpts = { @@ -55,24 +48,14 @@ server.listen(0, common.mustCall(() => { rejectUnauthorized: false, ALPNProtocols: ['h2', 'http/1.1'] }; - const npnOpts = { - port: server.address().port, - rejectUnauthorized: false, - NPNProtocols: ['h2', 'http/1.1'] - }; tls.connect(alpnOpts, function() { this.end(); - tls.connect(npnOpts, function() { - this.end(); - - server.close(); + server.close(); - assert.deepStrictEqual(protocols, [ - { alpnProtocol: 'http/1.1', npnProtocol: false }, - { alpnProtocol: false, npnProtocol: 'http/1.1' } - ]); - }); + assert.deepStrictEqual(protocols, [ + { alpnProtocol: 'http/1.1' }, + ]); }); })); |