1 // Copyright Joyent, Inc. and other Node contributors.
3 // Permission is hereby granted, free of charge, to any person obtaining a
4 // copy of this software and associated documentation files (the
5 // "Software"), to deal in the Software without restriction, including
6 // without limitation the rights to use, copy, modify, merge, publish,
7 // distribute, sublicense, and/or sell copies of the Software, and to permit
8 // persons to whom the Software is furnished to do so, subject to the
9 // following conditions:
11 // The above copyright notice and this permission notice shall be included
12 // in all copies or substantial portions of the Software.
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17 // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 // USE OR OTHER DEALINGS IN THE SOFTWARE.
23 #include "async-wrap.h"
24 #include "async-wrap-inl.h"
25 #include "node_buffer.h" // Buffer
26 #include "node_crypto.h" // SecureContext
27 #include "node_crypto_bio.h" // NodeBIO
28 #include "node_crypto_clienthello.h" // ClientHelloParser
29 #include "node_crypto_clienthello-inl.h"
30 #include "node_wrap.h" // WithGenericStream
31 #include "node_counters.h"
32 #include "node_internals.h"
38 using crypto::SSLWrap;
39 using crypto::SecureContext;
42 using v8::EscapableHandleScope;
45 using v8::FunctionCallbackInfo;
46 using v8::FunctionTemplate;
48 using v8::HandleScope;
56 static const int X509_NAME_FLAGS = ASN1_STRFLGS_ESC_CTRL
57 | ASN1_STRFLGS_ESC_MSB
58 | XN_FLAG_SEP_MULTILINE
62 size_t TLSCallbacks::error_off_;
63 char TLSCallbacks::error_buf_[1024];
66 TLSCallbacks::TLSCallbacks(Environment* env,
69 StreamWrapCallbacks* old)
70 : SSLWrap<TLSCallbacks>(env, Unwrap<SecureContext>(sc), kind),
71 StreamWrapCallbacks(old),
73 env->tls_wrap_constructor_function()->NewInstance(),
74 AsyncWrap::PROVIDER_TLSWRAP),
75 sc_(Unwrap<SecureContext>(sc)),
76 sc_handle_(env->isolate(), sc),
87 node::Wrap<TLSCallbacks>(object(), this);
89 // Initialize queue for clearIn writes
90 QUEUE_INIT(&write_item_queue_);
91 QUEUE_INIT(&pending_write_items_);
93 // We've our own session callbacks
94 SSL_CTX_sess_set_get_cb(sc_->ctx_, SSLWrap<TLSCallbacks>::GetSessionCallback);
95 SSL_CTX_sess_set_new_cb(sc_->ctx_, SSLWrap<TLSCallbacks>::NewSessionCallback);
101 TLSCallbacks::~TLSCallbacks() {
109 persistent().Reset();
111 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
112 sni_context_.Reset();
113 #endif // SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
115 // Move all writes to pending
119 while (!QUEUE_EMPTY(&pending_write_items_)) {
120 QUEUE* q = QUEUE_HEAD(&pending_write_items_);
123 WriteItem* wi = QUEUE_DATA(q, WriteItem, member_);
129 void TLSCallbacks::MakePending() {
131 QUEUE* from = &write_item_queue_;
132 QUEUE* to = &pending_write_items_;
134 if (QUEUE_EMPTY(from))
137 // Add items to pending
140 // Empty original queue
145 bool TLSCallbacks::InvokeQueued(int status) {
146 if (QUEUE_EMPTY(&pending_write_items_))
150 while (!QUEUE_EMPTY(&pending_write_items_)) {
151 QUEUE* q = QUEUE_HEAD(&pending_write_items_);
154 WriteItem* wi = QUEUE_DATA(q, WriteItem, member_);
155 wi->cb_(&wi->w_->req_, status);
163 void TLSCallbacks::NewSessionDoneCb() {
168 void TLSCallbacks::InitSSL() {
170 enc_in_ = NodeBIO::New();
171 enc_out_ = NodeBIO::New();
173 SSL_set_bio(ssl_, enc_in_, enc_out_);
175 // NOTE: This could be overriden in SetVerifyMode
176 SSL_set_verify(ssl_, SSL_VERIFY_NONE, crypto::VerifyCallback);
178 #ifdef SSL_MODE_RELEASE_BUFFERS
179 long mode = SSL_get_mode(ssl_);
180 SSL_set_mode(ssl_, mode | SSL_MODE_RELEASE_BUFFERS);
181 #endif // SSL_MODE_RELEASE_BUFFERS
183 SSL_set_app_data(ssl_, this);
184 SSL_set_info_callback(ssl_, SSLInfoCallback);
186 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
188 SSL_CTX_set_tlsext_servername_callback(sc_->ctx_, SelectSNIContextCallback);
189 SSL_CTX_set_tlsext_servername_arg(sc_->ctx_, this);
191 #endif // SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
196 SSL_set_accept_state(ssl_);
197 } else if (is_client()) {
198 SSL_set_connect_state(ssl_);
204 // Initialize ring for queud clear data
205 clear_in_ = new NodeBIO();
209 void TLSCallbacks::Wrap(const FunctionCallbackInfo<Value>& args) {
210 HandleScope handle_scope(args.GetIsolate());
211 Environment* env = Environment::GetCurrent(args.GetIsolate());
213 if (args.Length() < 1 || !args[0]->IsObject()) {
214 return env->ThrowTypeError(
215 "First argument should be a StreamWrap instance");
217 if (args.Length() < 2 || !args[1]->IsObject()) {
218 return env->ThrowTypeError(
219 "Second argument should be a SecureContext instance");
221 if (args.Length() < 3 || !args[2]->IsBoolean())
222 return env->ThrowTypeError("Third argument should be boolean");
224 Local<Object> stream = args[0].As<Object>();
225 Local<Object> sc = args[1].As<Object>();
226 Kind kind = args[2]->IsTrue() ? SSLWrap<TLSCallbacks>::kServer :
227 SSLWrap<TLSCallbacks>::kClient;
229 TLSCallbacks* callbacks = NULL;
230 WITH_GENERIC_STREAM(env, stream, {
231 callbacks = new TLSCallbacks(env, kind, sc, wrap->callbacks());
232 wrap->OverrideCallbacks(callbacks);
235 if (callbacks == NULL) {
236 return args.GetReturnValue().SetNull();
239 args.GetReturnValue().Set(callbacks->persistent());
243 void TLSCallbacks::Receive(const FunctionCallbackInfo<Value>& args) {
244 HandleScope handle_scope(args.GetIsolate());
246 TLSCallbacks* wrap = Unwrap<TLSCallbacks>(args.This());
248 CHECK(Buffer::HasInstance(args[0]));
249 char* data = Buffer::Data(args[0]);
250 size_t len = Buffer::Length(args[0]);
253 uv_stream_t* stream = wrap->wrap()->stream();
255 // Copy given buffer entirely or partiall if handle becomes closed
256 while (len > 0 && !uv_is_closing(reinterpret_cast<uv_handle_t*>(stream))) {
257 wrap->DoAlloc(reinterpret_cast<uv_handle_t*>(stream), len, &buf);
258 size_t copy = buf.len > len ? len : buf.len;
259 memcpy(buf.base, data, copy);
260 wrap->DoRead(stream, buf.len, &buf, UV_UNKNOWN_HANDLE);
268 void TLSCallbacks::Start(const FunctionCallbackInfo<Value>& args) {
269 Environment* env = Environment::GetCurrent(args.GetIsolate());
270 HandleScope scope(env->isolate());
272 TLSCallbacks* wrap = Unwrap<TLSCallbacks>(args.This());
275 return env->ThrowError("Already started.");
276 wrap->started_ = true;
278 // Send ClientHello handshake
279 assert(wrap->is_client());
285 void TLSCallbacks::SSLInfoCallback(const SSL* ssl_, int where, int ret) {
286 if (!(where & (SSL_CB_HANDSHAKE_START | SSL_CB_HANDSHAKE_DONE)))
289 // Be compatible with older versions of OpenSSL. SSL_get_app_data() wants
290 // a non-const SSL* in OpenSSL <= 0.9.7e.
291 SSL* ssl = const_cast<SSL*>(ssl_);
292 TLSCallbacks* c = static_cast<TLSCallbacks*>(SSL_get_app_data(ssl));
293 Environment* env = c->env();
294 HandleScope handle_scope(env->isolate());
295 Context::Scope context_scope(env->context());
296 Local<Object> object = c->object();
298 if (where & SSL_CB_HANDSHAKE_START) {
299 Local<Value> callback = object->Get(env->onhandshakestart_string());
300 if (callback->IsFunction()) {
301 c->MakeCallback(callback.As<Function>(), 0, NULL);
305 if (where & SSL_CB_HANDSHAKE_DONE) {
306 c->established_ = true;
307 Local<Value> callback = object->Get(env->onhandshakedone_string());
308 if (callback->IsFunction()) {
309 c->MakeCallback(callback.As<Function>(), 0, NULL);
315 void TLSCallbacks::EncOut() {
316 // Ignore cycling data if ClientHello wasn't yet parsed
317 if (!hello_parser_.IsEnded())
321 if (write_size_ != 0)
324 // Wait for `newSession` callback to be invoked
325 if (is_waiting_new_session())
329 if (established_ && !QUEUE_EMPTY(&write_item_queue_))
333 if (BIO_pending(enc_out_) == 0) {
334 if (clear_in_->Length() == 0)
339 char* data[kSimultaneousBufferCount];
340 size_t size[ARRAY_SIZE(data)];
341 size_t count = ARRAY_SIZE(data);
342 write_size_ = NodeBIO::FromBIO(enc_out_)->PeekMultiple(data, size, &count);
343 assert(write_size_ != 0 && count != 0);
345 write_req_.data = this;
346 uv_buf_t buf[ARRAY_SIZE(data)];
347 for (size_t i = 0; i < count; i++)
348 buf[i] = uv_buf_init(data[i], size[i]);
349 int r = uv_write(&write_req_, wrap()->stream(), buf, count, EncOutCb);
351 // Ignore errors, this should be already handled in js
353 if (wrap()->is_tcp()) {
354 NODE_COUNT_NET_BYTES_SENT(write_size_);
355 } else if (wrap()->is_named_pipe()) {
356 NODE_COUNT_PIPE_BYTES_SENT(write_size_);
362 void TLSCallbacks::EncOutCb(uv_write_t* req, int status) {
363 TLSCallbacks* callbacks = static_cast<TLSCallbacks*>(req->data);
367 // Ignore errors after shutdown
368 if (callbacks->shutdown_)
371 // Notify about error
372 callbacks->InvokeQueued(status);
377 NodeBIO::FromBIO(callbacks->enc_out_)->Read(NULL, callbacks->write_size_);
379 // Try writing more data
380 callbacks->write_size_ = 0;
385 int TLSCallbacks::PrintErrorsCb(const char* str, size_t len, void* arg) {
386 size_t to_copy = error_off_;
387 size_t avail = sizeof(error_buf_) - error_off_ - 1;
392 memcpy(error_buf_, str, avail);
394 assert(error_off_ < sizeof(error_buf_));
397 error_buf_[error_off_] = '\0';
403 const char* TLSCallbacks::PrintErrors() {
405 ERR_print_errors_cb(PrintErrorsCb, this);
411 Local<Value> TLSCallbacks::GetSSLError(int status, int* err, const char** msg) {
412 EscapableHandleScope scope(env()->isolate());
414 *err = SSL_get_error(ssl_, status);
417 case SSL_ERROR_WANT_READ:
418 case SSL_ERROR_WANT_WRITE:
420 case SSL_ERROR_ZERO_RETURN:
421 return scope.Escape(env()->zero_return_string());
425 assert(*err == SSL_ERROR_SSL || *err == SSL_ERROR_SYSCALL);
427 const char* buf = PrintErrors();
429 Local<String> message =
430 OneByteString(env()->isolate(), buf, strlen(buf));
431 Local<Value> exception = Exception::Error(message);
434 assert(*msg == NULL);
438 return scope.Escape(exception);
441 return Local<Value>();
445 void TLSCallbacks::ClearOut() {
446 // Ignore cycling data if ClientHello wasn't yet parsed
447 if (!hello_parser_.IsEnded())
450 HandleScope handle_scope(env()->isolate());
451 Context::Scope context_scope(env()->context());
453 assert(ssl_ != NULL);
455 char out[kClearOutChunkSize];
458 read = SSL_read(ssl_, out, sizeof(out));
460 Local<Value> argv[] = {
461 Integer::New(env()->isolate(), read),
462 Buffer::New(env(), out, read)
464 wrap()->MakeCallback(env()->onread_string(), ARRAY_SIZE(argv), argv);
468 int flags = SSL_get_shutdown(ssl_);
469 if (!eof_ && flags & SSL_RECEIVED_SHUTDOWN) {
471 Local<Value> arg = Integer::New(env()->isolate(), UV_EOF);
472 wrap()->MakeCallback(env()->onread_string(), 1, &arg);
477 Local<Value> arg = GetSSLError(read, &err, NULL);
479 if (!arg.IsEmpty()) {
480 MakeCallback(env()->onerror_string(), 1, &arg);
486 bool TLSCallbacks::ClearIn() {
487 // Ignore cycling data if ClientHello wasn't yet parsed
488 if (!hello_parser_.IsEnded())
492 while (clear_in_->Length() > 0) {
494 char* data = clear_in_->Peek(&avail);
495 written = SSL_write(ssl_, data, avail);
496 assert(written == -1 || written == static_cast<int>(avail));
499 clear_in_->Read(NULL, avail);
503 if (clear_in_->Length() == 0) {
504 assert(written >= 0);
508 HandleScope handle_scope(env()->isolate());
509 Context::Scope context_scope(env()->context());
511 // Error or partial write
513 Local<Value> arg = GetSSLError(written, &err, &error_);
514 if (!arg.IsEmpty()) {
516 if (!InvokeQueued(UV_EPROTO))
525 const char* TLSCallbacks::Error() {
526 const char* ret = error_;
532 int TLSCallbacks::TryWrite(uv_buf_t** bufs, size_t* count) {
533 // TODO(indutny): Support it
538 int TLSCallbacks::DoWrite(WriteWrap* w,
541 uv_stream_t* send_handle,
543 assert(send_handle == NULL);
545 // Queue callback to execute it on next tick
546 WriteItem* wi = new WriteItem(w, cb);
549 // Empty writes should not go through encryption process
551 for (i = 0; i < count; i++)
552 if (bufs[i].len > 0) {
558 // However if there any data that should be written to socket,
559 // callback should not be invoked immediately
560 if (BIO_pending(enc_out_) == 0)
561 return uv_write(&w->req_, wrap()->stream(), bufs, count, cb);
564 QUEUE_INSERT_TAIL(&write_item_queue_, &wi->member_);
572 // Process enqueued data first
574 // If there're still data to process - enqueue current one
575 for (i = 0; i < count; i++)
576 clear_in_->Write(bufs[i].base, bufs[i].len);
581 for (i = 0; i < count; i++) {
582 written = SSL_write(ssl_, bufs[i].base, bufs[i].len);
583 assert(written == -1 || written == static_cast<int>(bufs[i].len));
590 HandleScope handle_scope(env()->isolate());
591 Context::Scope context_scope(env()->context());
592 Local<Value> arg = GetSSLError(written, &err, &error_);
596 // No errors, queue rest
597 for (; i < count; i++)
598 clear_in_->Write(bufs[i].base, bufs[i].len);
601 // Try writing data immediately
608 void TLSCallbacks::AfterWrite(WriteWrap* w) {
609 // Intentionally empty
613 void TLSCallbacks::DoAlloc(uv_handle_t* handle,
614 size_t suggested_size,
616 buf->base = NodeBIO::FromBIO(enc_in_)->PeekWritable(&suggested_size);
617 buf->len = suggested_size;
621 void TLSCallbacks::DoRead(uv_stream_t* handle,
624 uv_handle_type pending) {
626 // Error should be emitted only after all data was read
629 // Ignore EOF if received close_notify
630 if (nread == UV_EOF) {
636 HandleScope handle_scope(env()->isolate());
637 Context::Scope context_scope(env()->context());
638 Local<Value> arg = Integer::New(env()->isolate(), nread);
639 wrap()->MakeCallback(env()->onread_string(), 1, &arg);
643 // Only client connections can receive data
644 assert(ssl_ != NULL);
647 NodeBIO* enc_in = NodeBIO::FromBIO(enc_in_);
648 enc_in->Commit(nread);
650 // Parse ClientHello first
651 if (!hello_parser_.IsEnded()) {
653 uint8_t* data = reinterpret_cast<uint8_t*>(enc_in->Peek(&avail));
654 assert(avail == 0 || data != NULL);
655 return hello_parser_.Parse(data, avail);
658 // Cycle OpenSSL's state
663 int TLSCallbacks::DoShutdown(ShutdownWrap* req_wrap, uv_shutdown_cb cb) {
664 if (SSL_shutdown(ssl_) == 0)
668 return StreamWrapCallbacks::DoShutdown(req_wrap, cb);
672 void TLSCallbacks::SetVerifyMode(const FunctionCallbackInfo<Value>& args) {
673 Environment* env = Environment::GetCurrent(args.GetIsolate());
674 HandleScope scope(env->isolate());
676 TLSCallbacks* wrap = Unwrap<TLSCallbacks>(args.This());
678 if (args.Length() < 2 || !args[0]->IsBoolean() || !args[1]->IsBoolean())
679 return env->ThrowTypeError("Bad arguments, expected two booleans");
682 if (wrap->is_server()) {
683 bool request_cert = args[0]->IsTrue();
685 // Note reject_unauthorized ignored.
686 verify_mode = SSL_VERIFY_NONE;
688 bool reject_unauthorized = args[1]->IsTrue();
689 verify_mode = SSL_VERIFY_PEER;
690 if (reject_unauthorized)
691 verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
694 // Note request_cert and reject_unauthorized are ignored for clients.
695 verify_mode = SSL_VERIFY_NONE;
698 // Always allow a connection. We'll reject in javascript.
699 SSL_set_verify(wrap->ssl_, verify_mode, crypto::VerifyCallback);
703 void TLSCallbacks::EnableSessionCallbacks(
704 const FunctionCallbackInfo<Value>& args) {
705 Environment* env = Environment::GetCurrent(args.GetIsolate());
706 HandleScope scope(env->isolate());
708 TLSCallbacks* wrap = Unwrap<TLSCallbacks>(args.This());
710 wrap->enable_session_callbacks();
711 EnableHelloParser(args);
715 void TLSCallbacks::EnableHelloParser(const FunctionCallbackInfo<Value>& args) {
716 Environment* env = Environment::GetCurrent(args.GetIsolate());
717 HandleScope scope(env->isolate());
719 TLSCallbacks* wrap = Unwrap<TLSCallbacks>(args.This());
721 wrap->hello_parser_.Start(SSLWrap<TLSCallbacks>::OnClientHello,
722 OnClientHelloParseEnd,
727 void TLSCallbacks::OnClientHelloParseEnd(void* arg) {
728 TLSCallbacks* c = static_cast<TLSCallbacks*>(arg);
733 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
734 void TLSCallbacks::GetServername(const FunctionCallbackInfo<Value>& args) {
735 Environment* env = Environment::GetCurrent(args.GetIsolate());
736 HandleScope scope(env->isolate());
738 TLSCallbacks* wrap = Unwrap<TLSCallbacks>(args.This());
740 const char* servername = SSL_get_servername(wrap->ssl_,
741 TLSEXT_NAMETYPE_host_name);
742 if (servername != NULL) {
743 args.GetReturnValue().Set(OneByteString(env->isolate(), servername));
745 args.GetReturnValue().Set(false);
750 void TLSCallbacks::SetServername(const FunctionCallbackInfo<Value>& args) {
751 Environment* env = Environment::GetCurrent(args.GetIsolate());
752 HandleScope scope(env->isolate());
754 TLSCallbacks* wrap = Unwrap<TLSCallbacks>(args.This());
756 if (args.Length() < 1 || !args[0]->IsString())
757 return env->ThrowTypeError("First argument should be a string");
760 return env->ThrowError("Already started.");
762 if (!wrap->is_client())
765 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
766 String::Utf8Value servername(args[0].As<String>());
767 SSL_set_tlsext_host_name(wrap->ssl_, *servername);
768 #endif // SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
772 int TLSCallbacks::SelectSNIContextCallback(SSL* s, int* ad, void* arg) {
773 TLSCallbacks* p = static_cast<TLSCallbacks*>(arg);
774 Environment* env = p->env();
776 const char* servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
778 if (servername == NULL)
779 return SSL_TLSEXT_ERR_OK;
781 HandleScope scope(env->isolate());
782 // Call the SNI callback and use its return value as context
783 Local<Object> object = p->object();
784 Local<Value> ctx = object->Get(env->sni_context_string());
786 // Not an object, probably undefined or null
787 if (!ctx->IsObject())
788 return SSL_TLSEXT_ERR_NOACK;
790 Local<FunctionTemplate> cons = env->secure_context_constructor_template();
791 if (!cons->HasInstance(ctx)) {
792 // Failure: incorrect SNI context object
793 Local<Value> err = Exception::TypeError(env->sni_context_err_string());
794 p->MakeCallback(env->onerror_string(), 1, &err);
795 return SSL_TLSEXT_ERR_NOACK;
798 p->sni_context_.Reset();
799 p->sni_context_.Reset(env->isolate(), ctx);
801 SecureContext* sc = Unwrap<SecureContext>(ctx.As<Object>());
803 SSL_set_SSL_CTX(s, sc->ctx_);
804 return SSL_TLSEXT_ERR_OK;
806 #endif // SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
809 void TLSCallbacks::Initialize(Handle<Object> target,
810 Handle<Value> unused,
811 Handle<Context> context) {
812 Environment* env = Environment::GetCurrent(context);
814 NODE_SET_METHOD(target, "wrap", TLSCallbacks::Wrap);
816 Local<FunctionTemplate> t = FunctionTemplate::New(env->isolate());
817 t->InstanceTemplate()->SetInternalFieldCount(1);
818 t->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "TLSWrap"));
820 NODE_SET_PROTOTYPE_METHOD(t, "receive", Receive);
821 NODE_SET_PROTOTYPE_METHOD(t, "start", Start);
822 NODE_SET_PROTOTYPE_METHOD(t, "setVerifyMode", SetVerifyMode);
823 NODE_SET_PROTOTYPE_METHOD(t,
824 "enableSessionCallbacks",
825 EnableSessionCallbacks);
826 NODE_SET_PROTOTYPE_METHOD(t,
830 SSLWrap<TLSCallbacks>::AddMethods(env, t);
832 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
833 NODE_SET_PROTOTYPE_METHOD(t, "getServername", GetServername);
834 NODE_SET_PROTOTYPE_METHOD(t, "setServername", SetServername);
835 #endif // SSL_CRT_SET_TLSEXT_SERVERNAME_CB
837 env->set_tls_wrap_constructor_function(t->GetFunction());
842 NODE_MODULE_CONTEXT_AWARE_BUILTIN(tls_wrap, node::TLSCallbacks::Initialize)