39 using crypto::SecureContext;
40 using crypto::SSLWrap;
42 using v8::EscapableHandleScope;
45 using v8::FunctionCallbackInfo;
46 using v8::FunctionTemplate;
52 TLSWrap::TLSWrap(Environment* env,
57 env->tls_wrap_constructor_function()
58 ->NewInstance(env->context()).ToLocalChecked(),
59 AsyncWrap::PROVIDER_TLSWRAP),
60 SSLWrap<TLSWrap>(env, sc, kind),
74 node::Wrap(
object(),
this);
78 CHECK_NE(sc,
nullptr);
81 SSL_CTX_sess_set_get_cb(sc_->ctx_, SSLWrap<TLSWrap>::GetSessionCallback);
82 SSL_CTX_sess_set_new_cb(sc_->ctx_, SSLWrap<TLSWrap>::NewSessionCallback);
85 stream_->set_after_write_cb({ OnAfterWriteImpl,
this });
86 stream_->set_alloc_cb({ OnAllocImpl,
this });
87 stream_->set_read_cb({ OnReadImpl,
this });
88 stream_->set_destruct_cb({ OnDestructImpl,
this });
90 set_alloc_cb({ OnAllocSelf,
this });
91 set_read_cb({ OnReadSelf,
this });
105 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB 106 sni_context_.Reset();
107 #endif // SSL_CTRL_SET_TLSEXT_SERVERNAME_CB 113 void TLSWrap::MakePending() {
114 write_item_queue_.MoveBack(&pending_write_items_);
118 bool TLSWrap::InvokeQueued(
int status,
const char* error_str) {
119 if (pending_write_items_.IsEmpty())
124 pending_write_items_.MoveBack(&queue);
125 while (WriteItem* wi = queue.PopFront()) {
126 wi->w_->Done(status, error_str);
134 void TLSWrap::NewSessionDoneCb() {
139 void TLSWrap::InitSSL() {
143 crypto::NodeBIO::FromBIO(enc_in_)->AssignEnvironment(env());
144 crypto::NodeBIO::FromBIO(enc_out_)->AssignEnvironment(env());
146 SSL_set_bio(ssl_, enc_in_, enc_out_);
151 #ifdef SSL_MODE_RELEASE_BUFFERS 152 long mode = SSL_get_mode(ssl_);
153 SSL_set_mode(ssl_, mode | SSL_MODE_RELEASE_BUFFERS);
154 #endif // SSL_MODE_RELEASE_BUFFERS 156 SSL_set_app_data(ssl_,
this);
157 SSL_set_info_callback(ssl_, SSLInfoCallback);
159 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB 161 SSL_CTX_set_tlsext_servername_callback(sc_->ctx_, SelectSNIContextCallback);
163 #endif // SSL_CTRL_SET_TLSEXT_SERVERNAME_CB 167 SSL_set_cert_cb(ssl_, SSLWrap<TLSWrap>::SSLCertCallback,
this);
170 SSL_set_accept_state(ssl_);
171 }
else if (is_client()) {
173 crypto::NodeBIO::FromBIO(enc_in_)->set_initial(kInitialClientBufferLength);
174 SSL_set_connect_state(ssl_);
181 clear_in_ =
new crypto::NodeBIO();
182 clear_in_->AssignEnvironment(env());
186 void TLSWrap::Wrap(
const FunctionCallbackInfo<Value>& args) {
187 Environment* env = Environment::GetCurrent(args);
189 if (args.Length() < 1 || !args[0]->IsObject()) {
190 return env->ThrowTypeError(
191 "First argument should be a StreamWrap instance");
193 if (args.Length() < 2 || !args[1]->IsObject()) {
194 return env->ThrowTypeError(
195 "Second argument should be a SecureContext instance");
197 if (args.Length() < 3 || !args[2]->IsBoolean())
198 return env->ThrowTypeError(
"Third argument should be boolean");
200 Local<External> stream_obj = args[0].As<External>();
201 Local<Object> sc = args[1].As<Object>();
202 Kind kind = args[2]->IsTrue() ? SSLWrap<TLSWrap>::kServer :
203 SSLWrap<TLSWrap>::kClient;
205 StreamBase* stream =
static_cast<StreamBase*
>(stream_obj->Value());
206 CHECK_NE(stream,
nullptr);
208 TLSWrap* res =
new TLSWrap(env, kind, stream, Unwrap<SecureContext>(sc));
210 args.GetReturnValue().Set(res->object());
214 void TLSWrap::Receive(
const FunctionCallbackInfo<Value>& args) {
216 ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
225 while (len > 0 && wrap->IsAlive() && !wrap->IsClosing()) {
226 wrap->stream_->OnAlloc(len, &buf);
227 size_t copy = buf.len > len ?
len : buf.len;
228 memcpy(buf.base, data, copy);
230 wrap->stream_->OnRead(buf.len, &buf);
239 Environment* env = Environment::GetCurrent(args);
242 ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
245 return env->ThrowError(
"Already started.");
246 wrap->started_ =
true;
249 CHECK(wrap->is_client());
255 void TLSWrap::SSLInfoCallback(
const SSL* ssl_,
int where,
int ret) {
256 if (!(where & (SSL_CB_HANDSHAKE_START | SSL_CB_HANDSHAKE_DONE)))
261 SSL* ssl =
const_cast<SSL*
>(ssl_);
262 TLSWrap* c =
static_cast<TLSWrap*
>(SSL_get_app_data(ssl));
263 Environment* env = c->env();
264 Local<Object>
object = c->object();
266 if (where & SSL_CB_HANDSHAKE_START) {
267 Local<Value> callback =
object->Get(env->onhandshakestart_string());
268 if (callback->IsFunction()) {
269 c->MakeCallback(callback.As<Function>(), 0,
nullptr);
273 if (where & SSL_CB_HANDSHAKE_DONE) {
274 c->established_ =
true;
275 Local<Value> callback =
object->Get(env->onhandshakedone_string());
276 if (callback->IsFunction()) {
277 c->MakeCallback(callback.As<Function>(), 0,
nullptr);
283 void TLSWrap::EncOut() {
285 if (!hello_parser_.IsEnded())
289 if (write_size_ != 0)
293 if (is_waiting_new_session())
297 if (established_ && !write_item_queue_.IsEmpty())
304 if (BIO_pending(enc_out_) == 0) {
305 if (clear_in_->Length() == 0)
310 char* data[kSimultaneousBufferCount];
311 size_t size[arraysize(data)];
312 size_t count = arraysize(data);
313 write_size_ = crypto::NodeBIO::FromBIO(enc_out_)->PeekMultiple(data,
316 CHECK(write_size_ != 0 && count != 0);
318 Local<Object> req_wrap_obj =
319 env()->write_wrap_constructor_function()
320 ->NewInstance(env()->context()).ToLocalChecked();
326 uv_buf_t buf[arraysize(data)];
327 for (
size_t i = 0; i < count; i++)
328 buf[i] = uv_buf_init(data[i], size[i]);
329 int err = stream_->DoWrite(write_req, buf, count,
nullptr);
333 write_req->Dispose();
341 void TLSWrap::EncOutCb(WriteWrap* req_wrap,
int status) {
342 TLSWrap* wrap = req_wrap->wrap()->Cast<TLSWrap>();
347 CHECK_NE(wrap->ssl_,
nullptr);
356 wrap->InvokeQueued(status);
361 crypto::NodeBIO::FromBIO(wrap->enc_out_)->Read(
nullptr, wrap->write_size_);
367 wrap->write_size_ = 0;
372 Local<Value> TLSWrap::GetSSLError(
int status,
int* err,
const char** msg) {
373 EscapableHandleScope scope(env()->isolate());
377 return Local<Value>();
379 *err = SSL_get_error(ssl_, status);
382 case SSL_ERROR_WANT_READ:
383 case SSL_ERROR_WANT_WRITE:
384 case SSL_ERROR_WANT_X509_LOOKUP:
386 case SSL_ERROR_ZERO_RETURN:
387 return scope.Escape(env()->zero_return_string());
391 CHECK(*err == SSL_ERROR_SSL || *err == SSL_ERROR_SYSCALL);
393 BIO* bio = BIO_new(BIO_s_mem());
394 ERR_print_errors(bio);
397 BIO_get_mem_ptr(bio, &mem);
399 Local<String> message =
400 OneByteString(env()->isolate(), mem->data, mem->length);
401 Local<Value> exception = Exception::Error(message);
403 if (msg !=
nullptr) {
404 CHECK_EQ(*msg,
nullptr);
405 char*
const buf =
new char[mem->length + 1];
406 memcpy(buf, mem->data, mem->length);
407 buf[mem->length] =
'\0';
412 return scope.Escape(exception);
415 return Local<Value>();
419 void TLSWrap::ClearOut() {
421 if (!hello_parser_.IsEnded())
431 crypto::MarkPopErrorOnReturn mark_pop_error_on_return;
433 char out[kClearOutChunkSize];
436 read = SSL_read(ssl_, out,
sizeof(out));
446 OnAlloc(avail, &buf);
447 if (static_cast<int>(buf.len) < avail)
449 memcpy(buf.base, current, avail);
463 int flags = SSL_get_shutdown(ssl_);
464 if (!eof_ && flags & SSL_RECEIVED_SHUTDOWN) {
466 OnRead(UV_EOF,
nullptr);
474 Local<Value> arg = GetSSLError(read, &err,
nullptr);
477 if (err == SSL_ERROR_ZERO_RETURN && eof_)
480 if (!arg.IsEmpty()) {
483 if (BIO_pending(enc_out_) != 0)
492 bool TLSWrap::ClearIn() {
494 if (!hello_parser_.IsEnded())
500 crypto::MarkPopErrorOnReturn mark_pop_error_on_return;
503 while (clear_in_->Length() > 0) {
505 char* data = clear_in_->Peek(&avail);
506 written = SSL_write(ssl_, data, avail);
507 CHECK(written == -1 || written == static_cast<int>(avail));
510 clear_in_->Read(
nullptr, avail);
514 if (clear_in_->Length() == 0) {
515 CHECK_GE(written, 0);
521 const char* error_str =
nullptr;
522 Local<Value> arg = GetSSLError(written, &err, &error_str);
523 if (!arg.IsEmpty()) {
525 InvokeQueued(UV_EPROTO, error_str);
534 void* TLSWrap::Cast() {
535 return reinterpret_cast<void*
>(
this);
539 AsyncWrap* TLSWrap::GetAsyncWrap() {
540 return static_cast<AsyncWrap*
>(
this);
544 bool TLSWrap::IsIPCPipe() {
545 return stream_->IsIPCPipe();
549 int TLSWrap::GetFD() {
550 return stream_->GetFD();
554 bool TLSWrap::IsAlive() {
555 return ssl_ !=
nullptr && stream_ !=
nullptr && stream_->IsAlive();
559 bool TLSWrap::IsClosing() {
560 return stream_->IsClosing();
564 int TLSWrap::ReadStart() {
565 return stream_->ReadStart();
569 int TLSWrap::ReadStop() {
570 return stream_->ReadStop();
574 const char* TLSWrap::Error()
const {
579 void TLSWrap::ClearError() {
585 int TLSWrap::DoWrite(WriteWrap* w,
588 uv_stream_t* send_handle) {
589 CHECK_EQ(send_handle,
nullptr);
590 CHECK_NE(ssl_,
nullptr);
596 for (i = 0; i < count; i++)
597 if (bufs[i].len > 0) {
605 if (BIO_pending(enc_out_) == 0)
606 return stream_->DoWrite(w, bufs, count, send_handle);
610 write_item_queue_.PushBack(
new WriteItem(w));
622 for (i = 0; i < count; i++)
623 clear_in_->Write(bufs[i].base, bufs[i].len);
627 if (ssl_ ==
nullptr) {
630 static char msg[] =
"Write after DestroySSL";
631 char* tmp =
new char[
sizeof(msg)];
632 memcpy(tmp, msg,
sizeof(msg));
637 crypto::MarkPopErrorOnReturn mark_pop_error_on_return;
640 for (i = 0; i < count; i++) {
641 written = SSL_write(ssl_, bufs[i].base, bufs[i].len);
642 CHECK(written == -1 || written == static_cast<int>(bufs[i].len));
649 Local<Value> arg = GetSSLError(written, &err, &error_);
654 for (; i < count; i++)
655 clear_in_->Write(bufs[i].base, bufs[i].len);
665 void TLSWrap::OnAfterWriteImpl(WriteWrap* w,
void*
ctx) {
670 void TLSWrap::OnAllocImpl(
size_t suggested_size, uv_buf_t* buf,
void*
ctx) {
671 TLSWrap* wrap =
static_cast<TLSWrap*
>(
ctx);
673 if (wrap->ssl_ ==
nullptr) {
674 *buf = uv_buf_init(
nullptr, 0);
679 buf->base = crypto::NodeBIO::FromBIO(wrap->enc_in_)->PeekWritable(&size);
684 void TLSWrap::OnReadImpl(ssize_t nread,
686 uv_handle_type pending,
688 TLSWrap* wrap =
static_cast<TLSWrap*
>(
ctx);
689 wrap->DoRead(nread, buf, pending);
693 void TLSWrap::OnDestructImpl(
void* ctx) {
694 TLSWrap* wrap =
static_cast<TLSWrap*
>(
ctx);
695 wrap->clear_stream();
699 void TLSWrap::OnAllocSelf(
size_t suggested_size, uv_buf_t* buf,
void* ctx) {
700 buf->base = node::Malloc(suggested_size);
701 buf->len = suggested_size;
705 void TLSWrap::OnReadSelf(ssize_t nread,
707 uv_handle_type pending,
709 TLSWrap* wrap =
static_cast<TLSWrap*
>(
ctx);
710 Local<Object> buf_obj;
712 buf_obj =
Buffer::New(wrap->env(), buf->base, buf->len).ToLocalChecked();
713 wrap->EmitData(nread, buf_obj, Local<Object>());
717 void TLSWrap::DoRead(ssize_t nread,
719 uv_handle_type pending) {
725 if (nread == UV_EOF) {
731 OnRead(nread,
nullptr);
736 if (ssl_ ==
nullptr) {
737 OnRead(UV_EPROTO,
nullptr);
742 crypto::NodeBIO* enc_in = crypto::NodeBIO::FromBIO(enc_in_);
743 enc_in->Commit(nread);
746 if (!hello_parser_.IsEnded()) {
748 uint8_t* data =
reinterpret_cast<uint8_t*
>(enc_in->Peek(&avail));
749 CHECK(avail == 0 || data !=
nullptr);
750 return hello_parser_.Parse(data, avail);
758 int TLSWrap::DoShutdown(ShutdownWrap* req_wrap) {
759 crypto::MarkPopErrorOnReturn mark_pop_error_on_return;
761 if (ssl_ !=
nullptr && SSL_shutdown(ssl_) == 0)
766 return stream_->DoShutdown(req_wrap);
770 void TLSWrap::SetVerifyMode(
const FunctionCallbackInfo<Value>& args) {
771 Environment* env = Environment::GetCurrent(args);
774 ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
776 if (args.Length() < 2 || !args[0]->IsBoolean() || !args[1]->IsBoolean())
777 return env->ThrowTypeError(
"Bad arguments, expected two booleans");
779 if (wrap->ssl_ ==
nullptr)
780 return env->ThrowTypeError(
"SetVerifyMode after destroySSL");
783 if (wrap->is_server()) {
784 bool request_cert = args[0]->IsTrue();
787 verify_mode = SSL_VERIFY_NONE;
789 bool reject_unauthorized = args[1]->IsTrue();
790 verify_mode = SSL_VERIFY_PEER;
791 if (reject_unauthorized)
792 verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
796 verify_mode = SSL_VERIFY_NONE;
804 void TLSWrap::EnableSessionCallbacks(
805 const FunctionCallbackInfo<Value>& args) {
807 ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
808 if (wrap->ssl_ ==
nullptr) {
809 return wrap->env()->ThrowTypeError(
810 "EnableSessionCallbacks after destroySSL");
812 wrap->enable_session_callbacks();
813 crypto::NodeBIO::FromBIO(wrap->enc_in_)->set_initial(kMaxHelloLength);
814 wrap->hello_parser_.Start(SSLWrap<TLSWrap>::OnClientHello,
815 OnClientHelloParseEnd,
820 void TLSWrap::DestroySSL(
const FunctionCallbackInfo<Value>& args) {
822 ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
828 wrap->InvokeQueued(UV_ECANCELED,
"Canceled because of SSL destruction");
831 wrap->SSLWrap<TLSWrap>::DestroySSL();
833 delete wrap->clear_in_;
834 wrap->clear_in_ =
nullptr;
838 void TLSWrap::EnableCertCb(
const FunctionCallbackInfo<Value>& args) {
840 ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
841 wrap->WaitForCertCb(OnClientHelloParseEnd, wrap);
845 void TLSWrap::OnClientHelloParseEnd(
void* arg) {
846 TLSWrap* c =
static_cast<TLSWrap*
>(arg);
851 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB 852 void TLSWrap::GetServername(
const FunctionCallbackInfo<Value>& args) {
853 Environment* env = Environment::GetCurrent(args);
856 ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
858 CHECK_NE(wrap->ssl_,
nullptr);
860 const char* servername = SSL_get_servername(wrap->ssl_,
861 TLSEXT_NAMETYPE_host_name);
862 if (servername !=
nullptr) {
863 args.GetReturnValue().Set(OneByteString(env->isolate(), servername));
865 args.GetReturnValue().Set(
false);
870 void TLSWrap::SetServername(
const FunctionCallbackInfo<Value>& args) {
871 Environment* env = Environment::GetCurrent(args);
874 ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder());
876 if (args.Length() < 1 || !args[0]->IsString())
877 return env->ThrowTypeError(
"First argument should be a string");
880 return env->ThrowError(
"Already started.");
882 if (!wrap->is_client())
885 CHECK_NE(wrap->ssl_,
nullptr);
887 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB 888 node::Utf8Value servername(env->isolate(), args[0].As<String>());
889 SSL_set_tlsext_host_name(wrap->ssl_, *servername);
890 #endif // SSL_CTRL_SET_TLSEXT_SERVERNAME_CB 894 int TLSWrap::SelectSNIContextCallback(SSL*
s,
int* ad,
void* arg) {
895 TLSWrap*
p =
static_cast<TLSWrap*
>(SSL_get_app_data(s));
896 Environment* env = p->env();
898 const char* servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
900 if (servername ==
nullptr)
901 return SSL_TLSEXT_ERR_OK;
904 Local<Object>
object = p->object();
905 Local<Value> ctx =
object->Get(env->sni_context_string());
908 if (!ctx->IsObject())
909 return SSL_TLSEXT_ERR_NOACK;
911 Local<FunctionTemplate> cons = env->secure_context_constructor_template();
912 if (!cons->HasInstance(ctx)) {
914 Local<Value> err = Exception::TypeError(env->sni_context_err_string());
915 p->MakeCallback(env->onerror_string(), 1, &err);
916 return SSL_TLSEXT_ERR_NOACK;
919 p->sni_context_.Reset();
920 p->sni_context_.Reset(env->isolate(),
ctx);
922 SecureContext* sc = Unwrap<SecureContext>(ctx.As<Object>());
923 CHECK_NE(sc,
nullptr);
924 p->SetSNIContext(sc);
925 return SSL_TLSEXT_ERR_OK;
927 #endif // SSL_CTRL_SET_TLSEXT_SERVERNAME_CB 932 Local<Context> context) {
933 Environment* env = Environment::GetCurrent(context);
935 env->SetMethod(target,
"wrap", TLSWrap::Wrap);
937 auto constructor = [](
const FunctionCallbackInfo<Value>& args) {
938 CHECK(args.IsConstructCall());
939 args.This()->SetAlignedPointerInInternalField(0,
nullptr);
942 Local<String> tlsWrapString =
943 FIXED_ONE_BYTE_STRING(env->isolate(),
"TLSWrap");
945 auto t = env->NewFunctionTemplate(constructor);
946 t->InstanceTemplate()->SetInternalFieldCount(1);
947 t->SetClassName(tlsWrapString);
949 AsyncWrap::AddWrapMethods(env, t, AsyncWrap::kFlagHasReset);
950 env->SetProtoMethod(t,
"receive", Receive);
951 env->SetProtoMethod(t,
"start",
Start);
952 env->SetProtoMethod(t,
"setVerifyMode", SetVerifyMode);
953 env->SetProtoMethod(t,
"enableSessionCallbacks", EnableSessionCallbacks);
954 env->SetProtoMethod(t,
"destroySSL", DestroySSL);
955 env->SetProtoMethod(t,
"enableCertCb", EnableCertCb);
957 StreamBase::AddMethods<TLSWrap>(env,
t, StreamBase::kFlagHasWritev);
958 SSLWrap<TLSWrap>::AddMethods(env, t);
960 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB 961 env->SetProtoMethod(t,
"getServername", GetServername);
962 env->SetProtoMethod(t,
"setServername", SetServername);
963 #endif // SSL_CRT_SET_TLSEXT_SERVERNAME_CB 965 env->set_tls_wrap_constructor_function(t->GetFunction());
967 target->Set(tlsWrapString, t->GetFunction());
bool HasInstance(Local< Value > val)
void NODE_COUNT_NET_BYTES_SENT(int bytes)
NODE_MODULE_CONTEXT_AWARE_BUILTIN(inspector, node::inspector::Agent::InitInspector)
union node::cares_wrap::@8::CaresAsyncData::@0 data
size_t Length(Local< Value > val)
void Initialize(Local< Object > target, Local< Value > unused, Local< Context > context, void *priv)
char * Data(Local< Value > val)
int VerifyCallback(int preverify_ok, X509_STORE_CTX *ctx)
MaybeLocal< Object > New(Isolate *isolate, Local< String > string, enum encoding enc)
MaybeLocal< Value > MakeCallback(Isolate *isolate, Local< Object > recv, Local< Function > callback, int argc, Local< Value > *argv, async_id asyncId, async_id triggerAsyncId)
int Start(Isolate *isolate, IsolateData *isolate_data, int argc, const char *const *argv, int exec_argc, const char *const *exec_argv)