-
Notifications
You must be signed in to change notification settings - Fork 30k
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
tls: Add support for ALPN fallback when no ALPN protocol matches #45075
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -39,6 +39,7 @@ using v8::Array; | |
using v8::ArrayBuffer; | ||
using v8::ArrayBufferView; | ||
using v8::BackingStore; | ||
using v8::Boolean; | ||
using v8::Context; | ||
using v8::DontDelete; | ||
using v8::Exception; | ||
|
@@ -237,6 +238,13 @@ int SelectALPNCallback( | |
if (UNLIKELY(alpn_buffer.IsEmpty()) || !alpn_buffer->IsArrayBufferView()) | ||
return SSL_TLSEXT_ERR_NOACK; | ||
|
||
bool alpn_fallback_allowed = | ||
w->object() | ||
->Get(env->context(), env->allow_alpn_fallback_string()) | ||
.ToLocalChecked() | ||
.As<Boolean>() | ||
->Value(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As @bnoordhuis mentions, this is going to be slow. Definitely should avoid uses of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not very familiar with the JS/C++ interface. What's the preferred way to set a value from the JS TLS wrap such that it's directly accessible here? If I create a new private field & setter on the C++ wrap, call that from JS in setup, and then read There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes and yes. :-) |
||
|
||
ArrayBufferViewContents<unsigned char> alpn_protos(alpn_buffer); | ||
int status = SSL_select_next_proto( | ||
const_cast<unsigned char**>(out), | ||
|
@@ -249,10 +257,17 @@ int SelectALPNCallback( | |
// Previous versions of Node.js returned SSL_TLSEXT_ERR_NOACK if no protocol | ||
// match was found. This would neither cause a fatal alert nor would it result | ||
// in a useful ALPN response as part of the Server Hello message. | ||
// We now return SSL_TLSEXT_ERR_ALERT_FATAL in that case as per Section 3.2 | ||
// of RFC 7301, which causes a fatal no_application_protocol alert. | ||
return status == OPENSSL_NPN_NEGOTIATED ? SSL_TLSEXT_ERR_OK | ||
: SSL_TLSEXT_ERR_ALERT_FATAL; | ||
|
||
// By default, we now return SSL_TLSEXT_ERR_ALERT_FATAL in that case as per | ||
// Section 3.2 of RFC 7301, which causes a fatal no_application_protocol | ||
// alert, unless the allowALPNFallback option has been set, which enables | ||
// OpenSSL's default protocol selection behavior, falling back to the client's | ||
// first preference. | ||
if (status == OPENSSL_NPN_NEGOTIATED || alpn_fallback_allowed) { | ||
return SSL_TLSEXT_ERR_OK; | ||
} else { | ||
return SSL_TLSEXT_ERR_ALERT_FATAL; | ||
} | ||
} | ||
|
||
int TLSExtStatusCallback(SSL* s, void* arg) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awkwardly structured sentence / grammar here.