Browse Source

tls,crypto: move NPN protcol data to hidden value

This fix is to be consistent implementation with ALPN. Tow NPN
protocol data in the persistent memebers move to hidden variables in
the wrap object.

PR-URL: https://github.com/nodejs/node/pull/2564
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
v5.x
Shigeki Ohtsu 9 years ago
committed by Rod Vagg
parent
commit
5029f41b2f
  1. 2
      src/env.h
  2. 48
      src/node_crypto.cc
  3. 9
      src/node_crypto.h

2
src/env.h

@ -131,6 +131,7 @@ namespace node {
V(netmask_string, "netmask") \
V(nice_string, "nice") \
V(nlink_string, "nlink") \
V(npn_buffer_string, "npnBuffer") \
V(nsname_string, "nsname") \
V(ocsp_request_string, "OCSPRequest") \
V(offset_string, "offset") \
@ -181,6 +182,7 @@ namespace node {
V(serial_string, "serial") \
V(scavenge_string, "scavenge") \
V(scopeid_string, "scopeid") \
V(selected_npn_buffer_string, "selectedNpnBuffer") \
V(sent_shutdown_string, "sentShutdown") \
V(serial_number_string, "serialNumber") \
V(service_string, "service") \

48
src/node_crypto.cc

@ -1917,14 +1917,17 @@ int SSLWrap<Base>::AdvertiseNextProtoCallback(SSL* s,
HandleScope handle_scope(env->isolate());
Context::Scope context_scope(env->context());
if (w->npn_protos_.IsEmpty()) {
Local<Value> npn_buffer =
w->object()->GetHiddenValue(env->npn_buffer_string());
if (npn_buffer.IsEmpty()) {
// No initialization - no NPN protocols
*data = reinterpret_cast<const unsigned char*>("");
*len = 0;
} else {
Local<Object> obj = PersistentToLocal(env->isolate(), w->npn_protos_);
*data = reinterpret_cast<const unsigned char*>(Buffer::Data(obj));
*len = Buffer::Length(obj);
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;
@ -1943,25 +1946,27 @@ int SSLWrap<Base>::SelectNextProtoCallback(SSL* s,
HandleScope handle_scope(env->isolate());
Context::Scope context_scope(env->context());
// Release old protocol handler if present
w->selected_npn_proto_.Reset();
Local<Value> npn_buffer =
w->object()->GetHiddenValue(env->npn_buffer_string());
if (w->npn_protos_.IsEmpty()) {
if (npn_buffer.IsEmpty()) {
// 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
w->selected_npn_proto_.Reset(env->isolate(), False(env->isolate()));
bool r = w->object()->SetHiddenValue(env->selected_npn_buffer_string(),
False(env->isolate()));
CHECK(r);
return SSL_TLSEXT_ERR_OK;
}
Local<Object> obj = PersistentToLocal(env->isolate(), w->npn_protos_);
CHECK(Buffer::HasInstance(npn_buffer));
const unsigned char* npn_protos =
reinterpret_cast<const unsigned char*>(Buffer::Data(obj));
size_t len = Buffer::Length(obj);
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;
@ -1979,8 +1984,9 @@ int SSLWrap<Base>::SelectNextProtoCallback(SSL* s,
break;
}
if (!result.IsEmpty())
w->selected_npn_proto_.Reset(env->isolate(), result);
bool r = w->object()->SetHiddenValue(env->selected_npn_buffer_string(),
result);
CHECK(r);
return SSL_TLSEXT_ERR_OK;
}
@ -1992,9 +1998,12 @@ void SSLWrap<Base>::GetNegotiatedProto(
Base* w = Unwrap<Base>(args.Holder());
if (w->is_client()) {
if (w->selected_npn_proto_.IsEmpty() == false) {
args.GetReturnValue().Set(w->selected_npn_proto_);
}
Local<Value> selected_npn_buffer =
w->object()->GetHiddenValue(w->env()->selected_npn_buffer_string());
if (selected_npn_buffer.IsEmpty() == false)
args.GetReturnValue().Set(selected_npn_buffer);
return;
}
@ -2014,11 +2023,14 @@ void SSLWrap<Base>::GetNegotiatedProto(
template <class Base>
void SSLWrap<Base>::SetNPNProtocols(const FunctionCallbackInfo<Value>& args) {
Base* w = Unwrap<Base>(args.Holder());
Environment* env = w->env();
if (args.Length() < 1 || !Buffer::HasInstance(args[0]))
return w->env()->ThrowTypeError("Must give a Buffer as first argument");
return env->ThrowTypeError("Must give a Buffer as first argument");
w->npn_protos_.Reset(args.GetIsolate(), args[0].As<Object>());
Local<Value> npn_buffer = Local<Value>::New(env->isolate(), args[0]);
bool r = w->object()->SetHiddenValue(env->npn_buffer_string(), npn_buffer);
CHECK(r);
}
#endif // OPENSSL_NPN_NEGOTIATED

9
src/node_crypto.h

@ -178,10 +178,6 @@ class SSLWrap {
next_sess_ = nullptr;
}
#ifdef OPENSSL_NPN_NEGOTIATED
npn_protos_.Reset();
selected_npn_proto_.Reset();
#endif
#ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
sni_context_.Reset();
#endif
@ -298,11 +294,6 @@ class SSLWrap {
v8::Persistent<v8::Object> ocsp_response_;
#endif // NODE__HAVE_TLSEXT_STATUS_CB
#ifdef OPENSSL_NPN_NEGOTIATED
v8::Persistent<v8::Object> npn_protos_;
v8::Persistent<v8::Value> selected_npn_proto_;
#endif // OPENSSL_NPN_NEGOTIATED
#ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
v8::Persistent<v8::Value> sni_context_;
#endif

Loading…
Cancel
Save