summaryrefslogtreecommitdiff
path: root/src/tls_wrap.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/tls_wrap.cc')
-rw-r--r--src/tls_wrap.cc166
1 files changed, 82 insertions, 84 deletions
diff --git a/src/tls_wrap.cc b/src/tls_wrap.cc
index cff2cded8c..e6afda6c0c 100644
--- a/src/tls_wrap.cc
+++ b/src/tls_wrap.cc
@@ -34,6 +34,7 @@ namespace node {
using crypto::SSLWrap;
using crypto::SecureContext;
using v8::Boolean;
+using v8::Context;
using v8::Exception;
using v8::Function;
using v8::FunctionCallbackInfo;
@@ -44,40 +45,20 @@ using v8::Integer;
using v8::Local;
using v8::Null;
using v8::Object;
-using v8::Persistent;
using v8::String;
using v8::Value;
-static Cached<String> onread_sym;
-static Cached<String> onerror_sym;
-static Cached<String> onhandshakestart_sym;
-static Cached<String> onhandshakedone_sym;
-static Cached<String> onclienthello_sym;
-static Cached<String> subject_sym;
-static Cached<String> subjectaltname_sym;
-static Cached<String> modulus_sym;
-static Cached<String> exponent_sym;
-static Cached<String> issuer_sym;
-static Cached<String> valid_from_sym;
-static Cached<String> valid_to_sym;
-static Cached<String> fingerprint_sym;
-static Cached<String> name_sym;
-static Cached<String> version_sym;
-static Cached<String> ext_key_usage_sym;
-static Cached<String> sni_context_sym;
-
-static Persistent<Function> tlsWrap;
-
static const int X509_NAME_FLAGS = ASN1_STRFLGS_ESC_CTRL
| ASN1_STRFLGS_ESC_MSB
| XN_FLAG_SEP_MULTILINE
| XN_FLAG_FN_SN;
-TLSCallbacks::TLSCallbacks(Kind kind,
+TLSCallbacks::TLSCallbacks(Environment* env,
+ Kind kind,
Handle<Object> sc,
StreamWrapCallbacks* old)
- : SSLWrap<TLSCallbacks>(ObjectWrap::Unwrap<SecureContext>(sc), kind),
+ : SSLWrap<TLSCallbacks>(env, ObjectWrap::Unwrap<SecureContext>(sc), kind),
StreamWrapCallbacks(old),
enc_in_(NULL),
enc_out_(NULL),
@@ -92,7 +73,7 @@ TLSCallbacks::TLSCallbacks(Kind kind,
sc_ = ObjectWrap::Unwrap<SecureContext>(sc);
sc_handle_.Reset(node_isolate, sc);
- Local<Object> object = NewInstance(tlsWrap);
+ Local<Object> object = env->tls_wrap_constructor_function()->NewInstance();
NODE_WRAP(object, this);
persistent().Reset(node_isolate, object);
@@ -197,7 +178,8 @@ void TLSCallbacks::InitSSL() {
void TLSCallbacks::Wrap(const FunctionCallbackInfo<Value>& args) {
- HandleScope scope(node_isolate);
+ Environment* env = Environment::GetCurrent(args.GetIsolate());
+ HandleScope handle_scope(args.GetIsolate());
if (args.Length() < 1 || !args[0]->IsObject())
return ThrowTypeError("First argument should be a StreamWrap instance");
@@ -212,8 +194,8 @@ void TLSCallbacks::Wrap(const FunctionCallbackInfo<Value>& args) {
SSLWrap<TLSCallbacks>::kClient;
TLSCallbacks* callbacks = NULL;
- WITH_GENERIC_STREAM(stream, {
- callbacks = new TLSCallbacks(kind, sc, wrap->callbacks());
+ WITH_GENERIC_STREAM(env, stream, {
+ callbacks = new TLSCallbacks(env, kind, sc, wrap->callbacks());
wrap->OverrideCallbacks(callbacks);
});
@@ -243,23 +225,32 @@ void TLSCallbacks::Start(const FunctionCallbackInfo<Value>& args) {
void TLSCallbacks::SSLInfoCallback(const SSL* ssl_, int where, int ret) {
+ if (!(where & (SSL_CB_HANDSHAKE_START | SSL_CB_HANDSHAKE_DONE)))
+ return;
+
// Be compatible with older versions of OpenSSL. SSL_get_app_data() wants
// a non-const SSL* in OpenSSL <= 0.9.7e.
SSL* ssl = const_cast<SSL*>(ssl_);
+ TLSCallbacks* c = static_cast<TLSCallbacks*>(SSL_get_app_data(ssl));
+ Environment* env = c->env();
+ // There should be a Context::Scope a few stack frames down.
+ assert(env->context() == env->isolate()->GetCurrentContext());
+ HandleScope handle_scope(env->isolate());
+ Local<Object> object = c->object(env->isolate());
+
if (where & SSL_CB_HANDSHAKE_START) {
- HandleScope scope(node_isolate);
- TLSCallbacks* c = static_cast<TLSCallbacks*>(SSL_get_app_data(ssl));
- Local<Object> object = c->object(node_isolate);
- if (object->Has(onhandshakestart_sym))
- MakeCallback(object, onhandshakestart_sym, 0, NULL);
+ Local<Value> callback = object->Get(env->onhandshakestart_string());
+ if (callback->IsFunction()) {
+ MakeCallback(env, object, callback.As<Function>());
+ }
}
+
if (where & SSL_CB_HANDSHAKE_DONE) {
- HandleScope scope(node_isolate);
- TLSCallbacks* c = static_cast<TLSCallbacks*>(SSL_get_app_data(ssl));
c->established_ = true;
- Local<Object> object = c->object(node_isolate);
- if (object->Has(onhandshakedone_sym))
- MakeCallback(object, onhandshakedone_sym, 0, NULL);
+ Local<Value> callback = object->Get(env->onhandshakedone_string());
+ if (callback->IsFunction()) {
+ MakeCallback(env, object, callback.As<Function>());
+ }
}
}
@@ -306,9 +297,8 @@ void TLSCallbacks::EncOut() {
void TLSCallbacks::EncOutCb(uv_write_t* req, int status) {
- HandleScope scope(node_isolate);
-
TLSCallbacks* callbacks = static_cast<TLSCallbacks*>(req->data);
+ Environment* env = callbacks->env();
// Handle error
if (status) {
@@ -317,10 +307,16 @@ void TLSCallbacks::EncOutCb(uv_write_t* req, int status) {
return;
// Notify about error
+ Context::Scope context_scope(env->context());
+ HandleScope handle_scope(env->isolate());
Local<Value> arg = String::Concat(
FIXED_ONE_BYTE_STRING(node_isolate, "write cb error, status: "),
Integer::New(status, node_isolate)->ToString());
- MakeCallback(callbacks->object(node_isolate), onerror_sym, 1, &arg);
+ MakeCallback(env,
+ callbacks->object(node_isolate),
+ env->onerror_string(),
+ 1,
+ &arg);
callbacks->InvokeQueued(status);
return;
}
@@ -334,7 +330,7 @@ void TLSCallbacks::EncOutCb(uv_write_t* req, int status) {
}
-Handle<Value> TLSCallbacks::GetSSLError(int status, int* err) {
+Local<Value> TLSCallbacks::GetSSLError(int status, int* err) {
HandleScope scope(node_isolate);
*err = SSL_get_error(ssl_, status);
@@ -365,7 +361,7 @@ Handle<Value> TLSCallbacks::GetSSLError(int status, int* err) {
return scope.Close(exception);
}
}
- return Handle<Value>();
+ return Local<Value>();
}
@@ -374,7 +370,8 @@ void TLSCallbacks::ClearOut() {
if (!hello_parser_.IsEnded())
return;
- HandleScope scope(node_isolate);
+ Context::Scope context_scope(env()->context());
+ HandleScope handle_scope(env()->isolate());
assert(ssl_ != NULL);
@@ -385,9 +382,13 @@ void TLSCallbacks::ClearOut() {
if (read > 0) {
Local<Value> argv[] = {
Integer::New(read, node_isolate),
- Buffer::New(out, read)
+ Buffer::New(env(), out, read)
};
- MakeCallback(Self(), onread_sym, ARRAY_SIZE(argv), argv);
+ MakeCallback(env(),
+ Self(),
+ env()->onread_string(),
+ ARRAY_SIZE(argv),
+ argv);
}
} while (read > 0);
@@ -395,8 +396,13 @@ void TLSCallbacks::ClearOut() {
int err;
Handle<Value> argv = GetSSLError(read, &err);
- if (!argv.IsEmpty())
- MakeCallback(object(node_isolate), onerror_sym, 1, &argv);
+ if (!argv.IsEmpty()) {
+ MakeCallback(env(),
+ object(node_isolate),
+ env()->onerror_string(),
+ 1,
+ &argv);
+ }
}
}
@@ -406,8 +412,6 @@ bool TLSCallbacks::ClearIn() {
if (!hello_parser_.IsEnded())
return false;
- HandleScope scope(node_isolate);
-
int written = 0;
while (clear_in_->Length() > 0) {
size_t avail = 0;
@@ -425,11 +429,19 @@ bool TLSCallbacks::ClearIn() {
return true;
}
+ Context::Scope context_scope(env()->context());
+ HandleScope handle_scope(env()->isolate());
+
// Error or partial write
int err;
Handle<Value> argv = GetSSLError(written, &err);
- if (!argv.IsEmpty())
- MakeCallback(object(node_isolate), onerror_sym, 1, &argv);
+ if (!argv.IsEmpty()) {
+ MakeCallback(env(),
+ object(node_isolate),
+ env()->onerror_string(),
+ 1,
+ &argv);
+ }
return false;
}
@@ -440,8 +452,6 @@ int TLSCallbacks::DoWrite(WriteWrap* w,
size_t count,
uv_stream_t* send_handle,
uv_write_cb cb) {
- HandleScope scope(node_isolate);
-
assert(send_handle == NULL);
// Queue callback to execute it on next tick
@@ -489,9 +499,15 @@ int TLSCallbacks::DoWrite(WriteWrap* w,
if (i != count) {
int err;
+ Context::Scope context_scope(env()->context());
+ HandleScope handle_scope(env()->isolate());
Handle<Value> argv = GetSSLError(written, &err);
if (!argv.IsEmpty()) {
- MakeCallback(object(node_isolate), onerror_sym, 1, &argv);
+ MakeCallback(env(),
+ object(node_isolate),
+ env()->onerror_string(),
+ 1,
+ &argv);
return -1;
}
@@ -527,8 +543,10 @@ void TLSCallbacks::DoRead(uv_stream_t* handle,
if (nread < 0) {
// Error should be emitted only after all data was read
ClearOut();
+ Context::Scope context_scope(env()->context());
+ HandleScope handle_scope(env()->isolate());
Local<Value> arg = Integer::New(nread, node_isolate);
- MakeCallback(Self(), onread_sym, 1, &arg);
+ MakeCallback(env(), Self(), env()->onread_string(), 1, &arg);
return;
}
@@ -664,18 +682,16 @@ int TLSCallbacks::SelectSNIContextCallback(SSL* s, int* ad, void* arg) {
HandleScope scope(node_isolate);
TLSCallbacks* p = static_cast<TLSCallbacks*>(arg);
+ Environment* env = p->env();
const char* servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
if (servername != NULL) {
// Call the SNI callback and use its return value as context
Local<Object> object = p->object(node_isolate);
- Local<Value> ctx;
- if (object->Has(sni_context_sym)) {
- ctx = object->Get(sni_context_sym);
- }
+ Local<Value> ctx = object->Get(env->sni_context_string());
- if (ctx.IsEmpty() || ctx->IsUndefined())
+ if (!ctx->IsObject())
return SSL_TLSEXT_ERR_NOACK;
p->sni_context_.Dispose();
@@ -690,8 +706,10 @@ int TLSCallbacks::SelectSNIContextCallback(SSL* s, int* ad, void* arg) {
#endif // SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
-void TLSCallbacks::Initialize(Handle<Object> target) {
- HandleScope scope(node_isolate);
+void TLSCallbacks::Initialize(Handle<Object> target,
+ Handle<Value> unused,
+ Handle<Context> context) {
+ Environment* env = Environment::GetCurrent(context);
NODE_SET_METHOD(target, "wrap", TLSCallbacks::Wrap);
@@ -715,29 +733,9 @@ void TLSCallbacks::Initialize(Handle<Object> target) {
NODE_SET_PROTOTYPE_METHOD(t, "setServername", SetServername);
#endif // SSL_CRT_SET_TLSEXT_SERVERNAME_CB
- tlsWrap.Reset(node_isolate, t->GetFunction());
-
- onread_sym = FIXED_ONE_BYTE_STRING(node_isolate, "onread");
- onerror_sym = FIXED_ONE_BYTE_STRING(node_isolate, "onerror");
- onhandshakestart_sym =
- FIXED_ONE_BYTE_STRING(node_isolate, "onhandshakestart");
- onhandshakedone_sym = FIXED_ONE_BYTE_STRING(node_isolate, "onhandshakedone");
- onclienthello_sym = FIXED_ONE_BYTE_STRING(node_isolate, "onclienthello");
-
- subject_sym = FIXED_ONE_BYTE_STRING(node_isolate, "subject");
- issuer_sym = FIXED_ONE_BYTE_STRING(node_isolate, "issuer");
- valid_from_sym = FIXED_ONE_BYTE_STRING(node_isolate, "valid_from");
- valid_to_sym = FIXED_ONE_BYTE_STRING(node_isolate, "valid_to");
- subjectaltname_sym = FIXED_ONE_BYTE_STRING(node_isolate, "subjectaltname");
- modulus_sym = FIXED_ONE_BYTE_STRING(node_isolate, "modulus");
- exponent_sym = FIXED_ONE_BYTE_STRING(node_isolate, "exponent");
- fingerprint_sym = FIXED_ONE_BYTE_STRING(node_isolate, "fingerprint");
- name_sym = FIXED_ONE_BYTE_STRING(node_isolate, "name");
- version_sym = FIXED_ONE_BYTE_STRING(node_isolate, "version");
- ext_key_usage_sym = FIXED_ONE_BYTE_STRING(node_isolate, "ext_key_usage");
- sni_context_sym = FIXED_ONE_BYTE_STRING(node_isolate, "sni_context");
+ env->set_tls_wrap_constructor_function(t->GetFunction());
}
} // namespace node
-NODE_MODULE(node_tls_wrap, node::TLSCallbacks::Initialize)
+NODE_MODULE_CONTEXT_AWARE(node_tls_wrap, node::TLSCallbacks::Initialize)