stream_wrap: use `uv_try_write` where possible
[platform/upstream/nodejs.git] / src / tls_wrap.cc
1 // Copyright Joyent, Inc. and other Node contributors.
2 //
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:
10 //
11 // The above copyright notice and this permission notice shall be included
12 // in all copies or substantial portions of the Software.
13 //
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.
21
22 #include "tls_wrap.h"
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"
33 #include "util.h"
34 #include "util-inl.h"
35
36 namespace node {
37
38 using crypto::SSLWrap;
39 using crypto::SecureContext;
40 using v8::Boolean;
41 using v8::Context;
42 using v8::Exception;
43 using v8::Function;
44 using v8::FunctionCallbackInfo;
45 using v8::FunctionTemplate;
46 using v8::Handle;
47 using v8::HandleScope;
48 using v8::Integer;
49 using v8::Local;
50 using v8::Null;
51 using v8::Object;
52 using v8::String;
53 using v8::Value;
54
55 static const int X509_NAME_FLAGS = ASN1_STRFLGS_ESC_CTRL
56                                  | ASN1_STRFLGS_ESC_MSB
57                                  | XN_FLAG_SEP_MULTILINE
58                                  | XN_FLAG_FN_SN;
59
60
61 size_t TLSCallbacks::error_off_;
62 char TLSCallbacks::error_buf_[1024];
63
64
65 TLSCallbacks::TLSCallbacks(Environment* env,
66                            Kind kind,
67                            Handle<Object> sc,
68                            StreamWrapCallbacks* old)
69     : SSLWrap<TLSCallbacks>(env, Unwrap<SecureContext>(sc), kind),
70       StreamWrapCallbacks(old),
71       AsyncWrap(env, env->tls_wrap_constructor_function()->NewInstance()),
72       sc_(Unwrap<SecureContext>(sc)),
73       sc_handle_(env->isolate(), sc),
74       enc_in_(NULL),
75       enc_out_(NULL),
76       clear_in_(NULL),
77       write_size_(0),
78       started_(false),
79       established_(false),
80       shutdown_(false),
81       error_(NULL),
82       eof_(false) {
83   node::Wrap<TLSCallbacks>(object(), this);
84
85   // Initialize queue for clearIn writes
86   QUEUE_INIT(&write_item_queue_);
87   QUEUE_INIT(&pending_write_items_);
88
89   // We've our own session callbacks
90   SSL_CTX_sess_set_get_cb(sc_->ctx_, SSLWrap<TLSCallbacks>::GetSessionCallback);
91   SSL_CTX_sess_set_new_cb(sc_->ctx_, SSLWrap<TLSCallbacks>::NewSessionCallback);
92
93   InitSSL();
94 }
95
96
97 TLSCallbacks::~TLSCallbacks() {
98   enc_in_ = NULL;
99   enc_out_ = NULL;
100   delete clear_in_;
101   clear_in_ = NULL;
102
103   sc_ = NULL;
104   sc_handle_.Dispose();
105   persistent().Dispose();
106
107 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
108   sni_context_.Dispose();
109 #endif  // SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
110
111   // Move all writes to pending
112   MakePending();
113
114   // And destroy
115   while (!QUEUE_EMPTY(&pending_write_items_)) {
116     QUEUE* q = QUEUE_HEAD(&pending_write_items_);
117     QUEUE_REMOVE(q);
118
119     WriteItem* wi = QUEUE_DATA(q, WriteItem, member_);
120     delete wi;
121   }
122 }
123
124
125 void TLSCallbacks::MakePending() {
126   // Aliases
127   QUEUE* from = &write_item_queue_;
128   QUEUE* to = &pending_write_items_;
129
130   if (QUEUE_EMPTY(from))
131     return;
132
133   // Add items to pending
134   QUEUE_ADD(to, from);
135
136   // Empty original queue
137   QUEUE_INIT(from);
138 }
139
140
141 bool TLSCallbacks::InvokeQueued(int status) {
142   if (QUEUE_EMPTY(&pending_write_items_))
143     return false;
144
145   // Process old queue
146   while (!QUEUE_EMPTY(&pending_write_items_)) {
147     QUEUE* q = QUEUE_HEAD(&pending_write_items_);
148     QUEUE_REMOVE(q);
149
150     WriteItem* wi = QUEUE_DATA(q, WriteItem, member_);
151     wi->cb_(&wi->w_->req_, status);
152     delete wi;
153   }
154
155   return true;
156 }
157
158
159 void TLSCallbacks::InitSSL() {
160   // Initialize SSL
161   enc_in_ = NodeBIO::New();
162   enc_out_ = NodeBIO::New();
163
164   SSL_set_bio(ssl_, enc_in_, enc_out_);
165
166   // NOTE: This could be overriden in SetVerifyMode
167   SSL_set_verify(ssl_, SSL_VERIFY_NONE, crypto::VerifyCallback);
168
169 #ifdef SSL_MODE_RELEASE_BUFFERS
170   long mode = SSL_get_mode(ssl_);
171   SSL_set_mode(ssl_, mode | SSL_MODE_RELEASE_BUFFERS);
172 #endif  // SSL_MODE_RELEASE_BUFFERS
173
174   SSL_set_app_data(ssl_, this);
175   SSL_set_info_callback(ssl_, SSLInfoCallback);
176
177 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
178   if (is_server()) {
179     SSL_CTX_set_tlsext_servername_callback(sc_->ctx_, SelectSNIContextCallback);
180     SSL_CTX_set_tlsext_servername_arg(sc_->ctx_, this);
181   }
182 #endif  // SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
183
184   InitNPN(sc_, this);
185
186   if (is_server()) {
187     SSL_set_accept_state(ssl_);
188   } else if (is_client()) {
189     SSL_set_connect_state(ssl_);
190   } else {
191     // Unexpected
192     abort();
193   }
194
195   // Initialize ring for queud clear data
196   clear_in_ = new NodeBIO();
197 }
198
199
200 void TLSCallbacks::Wrap(const FunctionCallbackInfo<Value>& args) {
201   HandleScope handle_scope(args.GetIsolate());
202   Environment* env = Environment::GetCurrent(args.GetIsolate());
203
204   if (args.Length() < 1 || !args[0]->IsObject())
205     return ThrowTypeError("First argument should be a StreamWrap instance");
206   if (args.Length() < 2 || !args[1]->IsObject())
207     return ThrowTypeError("Second argument should be a SecureContext instance");
208   if (args.Length() < 3 || !args[2]->IsBoolean())
209     return ThrowTypeError("Third argument should be boolean");
210
211   Local<Object> stream = args[0].As<Object>();
212   Local<Object> sc = args[1].As<Object>();
213   Kind kind = args[2]->IsTrue() ? SSLWrap<TLSCallbacks>::kServer :
214                                   SSLWrap<TLSCallbacks>::kClient;
215
216   TLSCallbacks* callbacks = NULL;
217   WITH_GENERIC_STREAM(env, stream, {
218     callbacks = new TLSCallbacks(env, kind, sc, wrap->callbacks());
219     wrap->OverrideCallbacks(callbacks);
220   });
221
222   if (callbacks == NULL) {
223     return args.GetReturnValue().SetNull();
224   }
225
226   args.GetReturnValue().Set(callbacks->persistent());
227 }
228
229
230 void TLSCallbacks::Receive(const FunctionCallbackInfo<Value>& args) {
231   HandleScope handle_scope(args.GetIsolate());
232
233   TLSCallbacks* wrap = Unwrap<TLSCallbacks>(args.This());
234
235   CHECK(Buffer::HasInstance(args[0]));
236   char* data = Buffer::Data(args[0]);
237   size_t len = Buffer::Length(args[0]);
238
239   uv_buf_t buf;
240   uv_stream_t* stream = wrap->wrap()->stream();
241
242   // Copy given buffer entirely or partiall if handle becomes closed
243   while (len > 0 && !uv_is_closing(reinterpret_cast<uv_handle_t*>(stream))) {
244     wrap->DoAlloc(reinterpret_cast<uv_handle_t*>(stream), len, &buf);
245     size_t copy = buf.len > len ? len : buf.len;
246     memcpy(buf.base, data, copy);
247     wrap->DoRead(stream, buf.len, &buf, UV_UNKNOWN_HANDLE);
248
249     data += copy;
250     len -= copy;
251   }
252 }
253
254
255 void TLSCallbacks::Start(const FunctionCallbackInfo<Value>& args) {
256   HandleScope scope(node_isolate);
257
258   TLSCallbacks* wrap = Unwrap<TLSCallbacks>(args.This());
259
260   if (wrap->started_)
261     return ThrowError("Already started.");
262   wrap->started_ = true;
263
264   // Send ClientHello handshake
265   assert(wrap->is_client());
266   wrap->ClearOut();
267   wrap->EncOut();
268 }
269
270
271 void TLSCallbacks::SSLInfoCallback(const SSL* ssl_, int where, int ret) {
272   if (!(where & (SSL_CB_HANDSHAKE_START | SSL_CB_HANDSHAKE_DONE)))
273     return;
274
275   // Be compatible with older versions of OpenSSL. SSL_get_app_data() wants
276   // a non-const SSL* in OpenSSL <= 0.9.7e.
277   SSL* ssl = const_cast<SSL*>(ssl_);
278   TLSCallbacks* c = static_cast<TLSCallbacks*>(SSL_get_app_data(ssl));
279   Environment* env = c->env();
280   HandleScope handle_scope(env->isolate());
281   Context::Scope context_scope(env->context());
282   Local<Object> object = c->object();
283
284   if (where & SSL_CB_HANDSHAKE_START) {
285     Local<Value> callback = object->Get(env->onhandshakestart_string());
286     if (callback->IsFunction()) {
287       c->MakeCallback(callback.As<Function>(), 0, NULL);
288     }
289   }
290
291   if (where & SSL_CB_HANDSHAKE_DONE) {
292     c->established_ = true;
293     Local<Value> callback = object->Get(env->onhandshakedone_string());
294     if (callback->IsFunction()) {
295       c->MakeCallback(callback.As<Function>(), 0, NULL);
296     }
297   }
298 }
299
300
301 void TLSCallbacks::EncOut() {
302   // Ignore cycling data if ClientHello wasn't yet parsed
303   if (!hello_parser_.IsEnded())
304     return;
305
306   // Write in progress
307   if (write_size_ != 0)
308     return;
309
310   // Split-off queue
311   if (established_ && !QUEUE_EMPTY(&write_item_queue_))
312     MakePending();
313
314   // No data to write
315   if (BIO_pending(enc_out_) == 0) {
316     if (clear_in_->Length() == 0)
317       InvokeQueued(0);
318     return;
319   }
320
321   char* data[kSimultaneousBufferCount];
322   size_t size[ARRAY_SIZE(data)];
323   size_t count = ARRAY_SIZE(data);
324   write_size_ = NodeBIO::FromBIO(enc_out_)->PeekMultiple(data, size, &count);
325   assert(write_size_ != 0 && count != 0);
326
327   write_req_.data = this;
328   uv_buf_t buf[ARRAY_SIZE(data)];
329   for (size_t i = 0; i < count; i++)
330     buf[i] = uv_buf_init(data[i], size[i]);
331   int r = uv_write(&write_req_, wrap()->stream(), buf, count, EncOutCb);
332
333   // Ignore errors, this should be already handled in js
334   if (!r) {
335     if (wrap()->is_tcp()) {
336       NODE_COUNT_NET_BYTES_SENT(write_size_);
337     } else if (wrap()->is_named_pipe()) {
338       NODE_COUNT_PIPE_BYTES_SENT(write_size_);
339     }
340   }
341 }
342
343
344 void TLSCallbacks::EncOutCb(uv_write_t* req, int status) {
345   TLSCallbacks* callbacks = static_cast<TLSCallbacks*>(req->data);
346
347   // Handle error
348   if (status) {
349     // Ignore errors after shutdown
350     if (callbacks->shutdown_)
351       return;
352
353     // Notify about error
354     callbacks->InvokeQueued(status);
355     return;
356   }
357
358   // Commit
359   NodeBIO::FromBIO(callbacks->enc_out_)->Read(NULL, callbacks->write_size_);
360
361   // Try writing more data
362   callbacks->write_size_ = 0;
363   callbacks->EncOut();
364 }
365
366
367 int TLSCallbacks::PrintErrorsCb(const char* str, size_t len, void* arg) {
368   size_t to_copy = error_off_;
369   size_t avail = sizeof(error_buf_) - error_off_ - 1;
370
371   if (avail > to_copy)
372     to_copy = avail;
373
374   memcpy(error_buf_, str, avail);
375   error_off_ += avail;
376   assert(error_off_ < sizeof(error_buf_));
377
378   // Zero-terminate
379   error_buf_[error_off_] = '\0';
380
381   return 0;
382 }
383
384
385 const char* TLSCallbacks::PrintErrors() {
386   error_off_ = 0;
387   ERR_print_errors_cb(PrintErrorsCb, this);
388
389   return error_buf_;
390 }
391
392
393 Local<Value> TLSCallbacks::GetSSLError(int status, int* err, const char** msg) {
394   HandleScope scope(node_isolate);
395
396   *err = SSL_get_error(ssl_, status);
397   switch (*err) {
398     case SSL_ERROR_NONE:
399     case SSL_ERROR_WANT_READ:
400     case SSL_ERROR_WANT_WRITE:
401       break;
402     case SSL_ERROR_ZERO_RETURN:
403       return scope.Close(FIXED_ONE_BYTE_STRING(node_isolate, "ZERO_RETURN"));
404       break;
405     default:
406       {
407         assert(*err == SSL_ERROR_SSL || *err == SSL_ERROR_SYSCALL);
408
409         const char* buf = PrintErrors();
410
411         Local<String> message =
412             OneByteString(node_isolate, buf, strlen(buf));
413         Local<Value> exception = Exception::Error(message);
414
415         if (msg != NULL) {
416           assert(*msg == NULL);
417           *msg = buf;
418         }
419
420         return scope.Close(exception);
421       }
422   }
423   return Local<Value>();
424 }
425
426
427 void TLSCallbacks::ClearOut() {
428   // Ignore cycling data if ClientHello wasn't yet parsed
429   if (!hello_parser_.IsEnded())
430     return;
431
432   HandleScope handle_scope(env()->isolate());
433   Context::Scope context_scope(env()->context());
434
435   assert(ssl_ != NULL);
436
437   char out[kClearOutChunkSize];
438   int read;
439   do {
440     read = SSL_read(ssl_, out, sizeof(out));
441     if (read > 0) {
442       Local<Value> argv[] = {
443         Integer::New(read, node_isolate),
444         Buffer::New(env(), out, read)
445       };
446       wrap()->MakeCallback(env()->onread_string(), ARRAY_SIZE(argv), argv);
447     }
448   } while (read > 0);
449
450   int flags = SSL_get_shutdown(ssl_);
451   if (!eof_ && flags & SSL_RECEIVED_SHUTDOWN) {
452     eof_ = true;
453     Local<Value> arg = Integer::New(UV_EOF, node_isolate);
454     wrap()->MakeCallback(env()->onread_string(), 1, &arg);
455   }
456
457   if (read == -1) {
458     int err;
459     Local<Value> arg = GetSSLError(read, &err, NULL);
460
461     if (!arg.IsEmpty()) {
462       MakeCallback(env()->onerror_string(), 1, &arg);
463     }
464   }
465 }
466
467
468 bool TLSCallbacks::ClearIn() {
469   // Ignore cycling data if ClientHello wasn't yet parsed
470   if (!hello_parser_.IsEnded())
471     return false;
472
473   int written = 0;
474   while (clear_in_->Length() > 0) {
475     size_t avail = 0;
476     char* data = clear_in_->Peek(&avail);
477     written = SSL_write(ssl_, data, avail);
478     assert(written == -1 || written == static_cast<int>(avail));
479     if (written == -1)
480       break;
481     clear_in_->Read(NULL, avail);
482   }
483
484   // All written
485   if (clear_in_->Length() == 0) {
486     assert(written >= 0);
487     return true;
488   }
489
490   HandleScope handle_scope(env()->isolate());
491   Context::Scope context_scope(env()->context());
492
493   // Error or partial write
494   int err;
495   Local<Value> arg = GetSSLError(written, &err, &error_);
496   if (!arg.IsEmpty()) {
497     MakePending();
498     if (!InvokeQueued(UV_EPROTO))
499       error_ = NULL;
500     clear_in_->Reset();
501   }
502
503   return false;
504 }
505
506
507 const char* TLSCallbacks::Error() {
508   const char* ret = error_;
509   error_ = NULL;
510   return ret;
511 }
512
513
514 int TLSCallbacks::TryWrite(uv_buf_t** bufs, size_t* count) {
515   // TODO(indutny): Support it
516   return -1;
517 }
518
519
520 int TLSCallbacks::DoWrite(WriteWrap* w,
521                           uv_buf_t* bufs,
522                           size_t count,
523                           uv_stream_t* send_handle,
524                           uv_write_cb cb) {
525   assert(send_handle == NULL);
526
527   // Queue callback to execute it on next tick
528   WriteItem* wi = new WriteItem(w, cb);
529   bool empty = true;
530
531   // Empty writes should not go through encryption process
532   size_t i;
533   for (i = 0; i < count; i++)
534     if (bufs[i].len > 0) {
535       empty = false;
536       break;
537     }
538   if (empty) {
539     ClearOut();
540     // However if there any data that should be written to socket,
541     // callback should not be invoked immediately
542     if (BIO_pending(enc_out_) == 0)
543       return uv_write(&w->req_, wrap()->stream(), bufs, count, cb);
544   }
545
546   QUEUE_INSERT_TAIL(&write_item_queue_, &wi->member_);
547
548   // Write queued data
549   if (empty) {
550     EncOut();
551     return 0;
552   }
553
554   // Process enqueued data first
555   if (!ClearIn()) {
556     // If there're still data to process - enqueue current one
557     for (i = 0; i < count; i++)
558       clear_in_->Write(bufs[i].base, bufs[i].len);
559     return 0;
560   }
561
562   int written = 0;
563   for (i = 0; i < count; i++) {
564     written = SSL_write(ssl_, bufs[i].base, bufs[i].len);
565     assert(written == -1 || written == static_cast<int>(bufs[i].len));
566     if (written == -1)
567       break;
568   }
569
570   if (i != count) {
571     int err;
572     HandleScope handle_scope(env()->isolate());
573     Context::Scope context_scope(env()->context());
574     Local<Value> arg = GetSSLError(written, &err, &error_);
575     if (!arg.IsEmpty())
576       return UV_EPROTO;
577
578     // No errors, queue rest
579     for (; i < count; i++)
580       clear_in_->Write(bufs[i].base, bufs[i].len);
581   }
582
583   // Try writing data immediately
584   EncOut();
585
586   return 0;
587 }
588
589
590 void TLSCallbacks::AfterWrite(WriteWrap* w) {
591   // Intentionally empty
592 }
593
594
595 void TLSCallbacks::DoAlloc(uv_handle_t* handle,
596                            size_t suggested_size,
597                            uv_buf_t* buf) {
598   buf->base = NodeBIO::FromBIO(enc_in_)->PeekWritable(&suggested_size);
599   buf->len = suggested_size;
600 }
601
602
603 void TLSCallbacks::DoRead(uv_stream_t* handle,
604                           ssize_t nread,
605                           const uv_buf_t* buf,
606                           uv_handle_type pending) {
607   if (nread < 0)  {
608     // Error should be emitted only after all data was read
609     ClearOut();
610
611     // Ignore EOF if received close_notify
612     if (nread == UV_EOF) {
613       if (eof_)
614         return;
615       eof_ = true;
616     }
617
618     HandleScope handle_scope(env()->isolate());
619     Context::Scope context_scope(env()->context());
620     Local<Value> arg = Integer::New(nread, node_isolate);
621     wrap()->MakeCallback(env()->onread_string(), 1, &arg);
622     return;
623   }
624
625   // Only client connections can receive data
626   assert(ssl_ != NULL);
627
628   // Commit read data
629   NodeBIO* enc_in = NodeBIO::FromBIO(enc_in_);
630   enc_in->Commit(nread);
631
632   // Parse ClientHello first
633   if (!hello_parser_.IsEnded()) {
634     size_t avail = 0;
635     uint8_t* data = reinterpret_cast<uint8_t*>(enc_in->Peek(&avail));
636     assert(avail == 0 || data != NULL);
637     return hello_parser_.Parse(data, avail);
638   }
639
640   // Cycle OpenSSL's state
641   Cycle();
642 }
643
644
645 int TLSCallbacks::DoShutdown(ShutdownWrap* req_wrap, uv_shutdown_cb cb) {
646   if (SSL_shutdown(ssl_) == 0)
647     SSL_shutdown(ssl_);
648   shutdown_ = true;
649   EncOut();
650   return StreamWrapCallbacks::DoShutdown(req_wrap, cb);
651 }
652
653
654 void TLSCallbacks::SetVerifyMode(const FunctionCallbackInfo<Value>& args) {
655   HandleScope scope(node_isolate);
656
657   TLSCallbacks* wrap = Unwrap<TLSCallbacks>(args.This());
658
659   if (args.Length() < 2 || !args[0]->IsBoolean() || !args[1]->IsBoolean())
660     return ThrowTypeError("Bad arguments, expected two booleans");
661
662   int verify_mode;
663   if (wrap->is_server()) {
664     bool request_cert = args[0]->IsTrue();
665     if (!request_cert) {
666       // Note reject_unauthorized ignored.
667       verify_mode = SSL_VERIFY_NONE;
668     } else {
669       bool reject_unauthorized = args[1]->IsTrue();
670       verify_mode = SSL_VERIFY_PEER;
671       if (reject_unauthorized)
672         verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
673     }
674   } else {
675     // Note request_cert and reject_unauthorized are ignored for clients.
676     verify_mode = SSL_VERIFY_NONE;
677   }
678
679   // Always allow a connection. We'll reject in javascript.
680   SSL_set_verify(wrap->ssl_, verify_mode, crypto::VerifyCallback);
681 }
682
683
684 void TLSCallbacks::EnableSessionCallbacks(
685     const FunctionCallbackInfo<Value>& args) {
686   HandleScope scope(node_isolate);
687
688   TLSCallbacks* wrap = Unwrap<TLSCallbacks>(args.This());
689
690   wrap->enable_session_callbacks();
691   EnableHelloParser(args);
692 }
693
694
695 void TLSCallbacks::EnableHelloParser(const FunctionCallbackInfo<Value>& args) {
696   HandleScope scope(node_isolate);
697
698   TLSCallbacks* wrap = Unwrap<TLSCallbacks>(args.This());
699
700   wrap->hello_parser_.Start(SSLWrap<TLSCallbacks>::OnClientHello,
701                             OnClientHelloParseEnd,
702                             wrap);
703 }
704
705
706 void TLSCallbacks::OnClientHelloParseEnd(void* arg) {
707   TLSCallbacks* c = static_cast<TLSCallbacks*>(arg);
708   c->Cycle();
709 }
710
711
712 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
713 void TLSCallbacks::GetServername(const FunctionCallbackInfo<Value>& args) {
714   HandleScope scope(node_isolate);
715
716   TLSCallbacks* wrap = Unwrap<TLSCallbacks>(args.This());
717
718   const char* servername = SSL_get_servername(wrap->ssl_,
719                                               TLSEXT_NAMETYPE_host_name);
720   if (servername != NULL) {
721     args.GetReturnValue().Set(OneByteString(node_isolate, servername));
722   } else {
723     args.GetReturnValue().Set(false);
724   }
725 }
726
727
728 void TLSCallbacks::SetServername(const FunctionCallbackInfo<Value>& args) {
729   HandleScope scope(node_isolate);
730
731   TLSCallbacks* wrap = Unwrap<TLSCallbacks>(args.This());
732
733   if (args.Length() < 1 || !args[0]->IsString())
734     return ThrowTypeError("First argument should be a string");
735
736   if (wrap->started_)
737     return ThrowError("Already started.");
738
739   if (!wrap->is_client())
740     return;
741
742 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
743   String::Utf8Value servername(args[0].As<String>());
744   SSL_set_tlsext_host_name(wrap->ssl_, *servername);
745 #endif  // SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
746 }
747
748
749 int TLSCallbacks::SelectSNIContextCallback(SSL* s, int* ad, void* arg) {
750   HandleScope scope(node_isolate);
751
752   TLSCallbacks* p = static_cast<TLSCallbacks*>(arg);
753   Environment* env = p->env();
754
755   const char* servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
756
757   if (servername != NULL) {
758     // Call the SNI callback and use its return value as context
759     Local<Object> object = p->object();
760     Local<Value> ctx = object->Get(env->sni_context_string());
761
762     if (!ctx->IsObject())
763       return SSL_TLSEXT_ERR_NOACK;
764
765     p->sni_context_.Dispose();
766     p->sni_context_.Reset(node_isolate, ctx);
767
768     SecureContext* sc = Unwrap<SecureContext>(ctx.As<Object>());
769     InitNPN(sc, p);
770     SSL_set_SSL_CTX(s, sc->ctx_);
771   }
772
773   return SSL_TLSEXT_ERR_OK;
774 }
775 #endif  // SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
776
777
778 void TLSCallbacks::Initialize(Handle<Object> target,
779                               Handle<Value> unused,
780                               Handle<Context> context) {
781   Environment* env = Environment::GetCurrent(context);
782
783   NODE_SET_METHOD(target, "wrap", TLSCallbacks::Wrap);
784
785   Local<FunctionTemplate> t = FunctionTemplate::New();
786   t->InstanceTemplate()->SetInternalFieldCount(1);
787   t->SetClassName(FIXED_ONE_BYTE_STRING(node_isolate, "TLSWrap"));
788
789   NODE_SET_PROTOTYPE_METHOD(t, "receive", Receive);
790   NODE_SET_PROTOTYPE_METHOD(t, "start", Start);
791   NODE_SET_PROTOTYPE_METHOD(t, "setVerifyMode", SetVerifyMode);
792   NODE_SET_PROTOTYPE_METHOD(t,
793                             "enableSessionCallbacks",
794                             EnableSessionCallbacks);
795   NODE_SET_PROTOTYPE_METHOD(t,
796                             "enableHelloParser",
797                             EnableHelloParser);
798
799   SSLWrap<TLSCallbacks>::AddMethods(t);
800
801 #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
802   NODE_SET_PROTOTYPE_METHOD(t, "getServername", GetServername);
803   NODE_SET_PROTOTYPE_METHOD(t, "setServername", SetServername);
804 #endif  // SSL_CRT_SET_TLSEXT_SERVERNAME_CB
805
806   env->set_tls_wrap_constructor_function(t->GetFunction());
807 }
808
809 }  // namespace node
810
811 NODE_MODULE_CONTEXT_AWARE_BUILTIN(tls_wrap, node::TLSCallbacks::Initialize)