From 2feed574bd4c37e5c117ee5392b09feffc27ab4a Mon Sep 17 00:00:00 2001 From: Shigeki Ohtsu Date: Thu, 23 Apr 2015 15:25:15 +0900 Subject: [PATCH 1/5] tls, crypto: add ALPN Support cherry-pick 802a2e79e1adb22542ba12fba5e331e94277272d from v6-staging. ALPN is added to tls according to RFC7301, which supersedes NPN. When the server receives both NPN and ALPN extensions from the client, ALPN takes precedence over NPN and the server does not send NPN extension to the client. alpnProtocol in TLSSocket always returns false when no selected protocol exists by ALPN. In https server, http/1.1 token is always set when no options.ALPNProtocols exists. PR-URL: https://github.com/nodejs/node/pull/2564 Reviewed-By: Fedor Indutny Reviewed-By: Ben Noordhuis --- doc/api/tls.md | 34 +- lib/_tls_legacy.js | 15 +- lib/_tls_wrap.js | 27 +- lib/https.js | 7 + lib/tls.js | 51 +- src/env.h | 2 + src/node.cc | 7 + src/node_constants.cc | 5 + src/node_crypto.cc | 101 ++++ src/node_crypto.h | 13 +- test/parallel/test-tls-alpn-server-client.js | 540 +++++++++++++++++++ 11 files changed, 769 insertions(+), 33 deletions(-) create mode 100644 test/parallel/test-tls-alpn-server-client.js diff --git a/doc/api/tls.md b/doc/api/tls.md index 9c650ad9bbec5e..8dff5225f0987c 100644 --- a/doc/api/tls.md +++ b/doc/api/tls.md @@ -120,14 +120,15 @@ of an application. The `--tls-cipher-list` switch should by used only if absolutely necessary. -## NPN and SNI +## ALPN, NPN and SNI -NPN (Next Protocol Negotiation) and SNI (Server Name Indication) are TLS +ALPN (Application-Layer Protocol Negotiation Extension), NPN (Next +Protocol Negotiation) and SNI (Server Name Indication) are TLS handshake extensions allowing you: - * NPN - to use one TLS server for multiple protocols (HTTP, SPDY) + * ALPN/NPN - to use one TLS server for multiple protocols (HTTP, SPDY, HTTP/2) * SNI - to use one TLS server for multiple hostnames with different SSL certificates. @@ -305,7 +306,13 @@ server. If `socket.authorized` is false, then `socket.authorizationError` is set to describe how authorization failed. Implied but worth mentioning: depending on the settings of the TLS server, you unauthorized connections may be accepted. -`socket.npnProtocol` is a string containing selected NPN protocol. + +`socket.npnProtocol` is a string containing the selected NPN protocol +and `socket.alpnProtocol` is a string containing the selected ALPN +protocol, 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, this returns false. + `socket.servername` is a string containing servername requested with SNI. @@ -429,6 +436,8 @@ Construct a new TLSSocket object from existing TCP socket. - `NPNProtocols`: Optional, see [`tls.createServer()`][] + - `ALPNProtocols`: Optional, see [tls.createServer][] + - `SNICallback`: Optional, see [`tls.createServer()`][] - `session`: Optional, a `Buffer` instance, containing TLS session @@ -460,8 +469,9 @@ The listener will be called no matter if the server's certificate was authorized or not. It is up to the user to test `tlsSocket.authorized` to see if the server certificate was signed by one of the specified CAs. If `tlsSocket.authorized === false` then the error can be found in -`tlsSocket.authorizationError`. Also if NPN was used you can check -`tlsSocket.npnProtocol` for negotiated protocol. +`tlsSocket.authorizationError`. Also if ALPN or NPN was used - you can +check `tlsSocket.alpnProtocol` or `tlsSocket.npnProtocol` for the +negotiated protocol. ### tlsSocket.address()