From 7eee37257fe708ec23e8be292047320491ac8361 Mon Sep 17 00:00:00 2001 From: Shigeki Ohtsu Date: Tue, 27 Oct 2015 00:10:24 +0900 Subject: [PATCH] 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 --- src/env.h | 2 ++ src/node_crypto.cc | 48 +++++++++++++++++++++++++++++----------------- src/node_crypto.h | 9 --------- 3 files changed, 32 insertions(+), 27 deletions(-) diff --git a/src/env.h b/src/env.h index b3f55c173a239e..c558764c671a21 100644 --- a/src/env.h +++ b/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") \ diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 1f50b643b5900f..2bbfa0552b2f3f 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -1917,14 +1917,17 @@ int SSLWrap::AdvertiseNextProtoCallback(SSL* s, HandleScope handle_scope(env->isolate()); Context::Scope context_scope(env->context()); - if (w->npn_protos_.IsEmpty()) { + Local npn_buffer = + w->object()->GetHiddenValue(env->npn_buffer_string()); + + if (npn_buffer.IsEmpty()) { // No initialization - no NPN protocols *data = reinterpret_cast(""); *len = 0; } else { - Local obj = PersistentToLocal(env->isolate(), w->npn_protos_); - *data = reinterpret_cast(Buffer::Data(obj)); - *len = Buffer::Length(obj); + CHECK(Buffer::HasInstance(npn_buffer)); + *data = reinterpret_cast(Buffer::Data(npn_buffer)); + *len = Buffer::Length(npn_buffer); } return SSL_TLSEXT_ERR_OK; @@ -1943,25 +1946,27 @@ int SSLWrap::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 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(const_cast("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 obj = PersistentToLocal(env->isolate(), w->npn_protos_); + CHECK(Buffer::HasInstance(npn_buffer)); const unsigned char* npn_protos = - reinterpret_cast(Buffer::Data(obj)); - size_t len = Buffer::Length(obj); + reinterpret_cast(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 result; @@ -1979,8 +1984,9 @@ int SSLWrap::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::GetNegotiatedProto( Base* w = Unwrap(args.Holder()); if (w->is_client()) { - if (w->selected_npn_proto_.IsEmpty() == false) { - args.GetReturnValue().Set(w->selected_npn_proto_); - } + Local 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::GetNegotiatedProto( template void SSLWrap::SetNPNProtocols(const FunctionCallbackInfo& args) { Base* w = Unwrap(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()); + Local npn_buffer = Local::New(env->isolate(), args[0]); + bool r = w->object()->SetHiddenValue(env->npn_buffer_string(), npn_buffer); + CHECK(r); } #endif // OPENSSL_NPN_NEGOTIATED diff --git a/src/node_crypto.h b/src/node_crypto.h index 4aceb41cb8ce19..06e2ad40fba201 100644 --- a/src/node_crypto.h +++ b/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 ocsp_response_; #endif // NODE__HAVE_TLSEXT_STATUS_CB -#ifdef OPENSSL_NPN_NEGOTIATED - v8::Persistent npn_protos_; - v8::Persistent selected_npn_proto_; -#endif // OPENSSL_NPN_NEGOTIATED - #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB v8::Persistent sni_context_; #endif