Skip to content

Commit

Permalink
crypto: make ALPN the same for OpenSSL 1.0.2 & 1.1.0
Browse files Browse the repository at this point in the history
This is kind of hairy. OpenSSL 1.0.2 ignored the return value and always
treated everything as SSL_TLSEXT_ERR_NOACK (so the comment was wrong and
Node was never sending a warning alert). OpenSSL 1.1.0 honors
SSL_TLSEXT_ERR_NOACK vs SSL_TLSEXT_ERR_FATAL_ALERT and treats everything
unknown as SSL_TLSEXT_ERR_FATAL_ALERT.

Since this is a behavior change (tests break too), start by aligning
everything on SSL_TLSEXT_ERR_NOACK. If sending no_application_protocol
is desirable in the future, this can by changed to
SSL_TLSEXT_ERR_FATAL_ALERT with whatever deprecation process is
appropriate.

However, note that, contrary to
https://rt.openssl.org/Ticket/Display.html?id=3463#txn-54498,
SSL_TLSEXT_ERR_FATAL_ALERT is *not* useful to a server with no fallback
protocol. Even if such mismatches were rejected, such a server must
*still* account for the fallback protocol case when the client does not
advertise ALPN at all. Thus this may not be worth bothering.

PR-URL: #16130
Backport-PR-URL: #18622
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Rod Vagg <rod@vagg.org>
  • Loading branch information
davidben authored and gibfahn committed Feb 18, 2018
1 parent 92ec6f6 commit 7873826
Showing 1 changed file with 6 additions and 14 deletions.
20 changes: 6 additions & 14 deletions src/node_crypto.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2505,20 +2505,12 @@ int SSLWrap<Base>::SelectALPNCallback(SSL* s,
unsigned alpn_protos_len = Buffer::Length(alpn_buffer);
int status = SSL_select_next_proto(const_cast<unsigned char**>(out), outlen,
alpn_protos, alpn_protos_len, in, inlen);

switch (status) {
case OPENSSL_NPN_NO_OVERLAP:
// According to 3.2. Protocol Selection of RFC7301,
// fatal no_application_protocol alert shall be sent
// but current openssl does not support it yet. See
// https://rt.openssl.org/Ticket/Display.html?id=3463&user=guest&pass=guest
// Instead, we send a warning alert for now.
return SSL_TLSEXT_ERR_ALERT_WARNING;
case OPENSSL_NPN_NEGOTIATED:
return SSL_TLSEXT_ERR_OK;
default:
return SSL_TLSEXT_ERR_ALERT_FATAL;
}
// According to 3.2. Protocol Selection of RFC7301, fatal
// no_application_protocol alert shall be sent but OpenSSL 1.0.2 does not
// support it yet. See
// https://rt.openssl.org/Ticket/Display.html?id=3463&user=guest&pass=guest
return status == OPENSSL_NPN_NEGOTIATED ? SSL_TLSEXT_ERR_OK
: SSL_TLSEXT_ERR_NOACK;
}
#endif // TLSEXT_TYPE_application_layer_protocol_negotiation

Expand Down

0 comments on commit 7873826

Please sign in to comment.