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