3 const assert = require('assert');
4 const crypto = require('crypto');
5 const net = require('net');
6 const tls = require('tls');
7 const util = require('util');
8 const common = require('_tls_common');
9 const StreamWrap = require('_stream_wrap').StreamWrap;
10 const Buffer = require('buffer').Buffer;
11 const Duplex = require('stream').Duplex;
12 const debug = util.debuglog('tls');
13 const Timer = process.binding('timer_wrap').Timer;
14 const tls_wrap = process.binding('tls_wrap');
15 const TCP = process.binding('tcp_wrap').TCP;
16 const Pipe = process.binding('pipe_wrap').Pipe;
17 const defaultSessionIdContext = getDefaultSessionIdContext();
19 function getDefaultSessionIdContext() {
20 var defaultText = process.argv.join(' ');
21 /* SSL_MAX_SID_CTX_LENGTH is 128 bits */
22 if (process.config.variables.openssl_fips) {
23 return crypto.createHash('sha1')
25 .digest('hex').slice(0, 32);
27 return crypto.createHash('md5')
33 function onhandshakestart() {
34 debug('onhandshakestart');
37 var ssl = self._handle;
38 var now = Timer.now();
40 assert(now >= ssl.lastHandshakeTime);
42 if ((now - ssl.lastHandshakeTime) >= tls.CLIENT_RENEG_WINDOW * 1000) {
46 var first = (ssl.lastHandshakeTime === 0);
47 ssl.lastHandshakeTime = now;
50 if (++ssl.handshakes > tls.CLIENT_RENEG_LIMIT) {
51 // Defer the error event to the next tick. We're being called from OpenSSL's
52 // state machine and OpenSSL is not re-entrant. We cannot allow the user's
53 // callback to destroy the connection right now, it would crash and burn.
54 setImmediate(function() {
55 var err = new Error('TLS session renegotiation attack detected.');
56 self._emitTLSError(err);
62 function onhandshakedone() {
64 debug('onhandshakedone');
69 function loadSession(self, hello, cb) {
71 function onSession(err, session) {
73 return cb(new Error('TLS session callback was called 2 times'));
80 return cb(new Error('Socket is closed'));
82 // NOTE: That we have disabled OpenSSL's internal session storage in
83 // `node_crypto.cc` and hence its safe to rely on getting servername only
84 // from clienthello or this place.
85 var ret = self._handle.loadSession(session);
90 if (hello.sessionId.length <= 0 ||
93 !self.server.emit('resumeSession', hello.sessionId, onSession)) {
99 function loadSNI(self, servername, cb) {
100 if (!servername || !self._SNICallback)
104 self._SNICallback(servername, function(err, context) {
106 return cb(new Error('TLS SNI callback was called 2 times'));
113 return cb(new Error('Socket is closed'));
115 // TODO(indutny): eventually disallow raw `SecureContext`
117 self._handle.sni_context = context.context || context;
119 cb(null, self._handle.sni_context);
124 function requestOCSP(self, hello, ctx, cb) {
125 if (!hello.OCSPRequest || !self.server)
129 ctx = self.server._sharedCreds;
133 if (self.server.listenerCount('OCSPRequest') === 0) {
136 self.server.emit('OCSPRequest',
137 ctx.getCertificate(),
143 function onOCSP(err, response) {
145 return cb(new Error('TLS OCSP callback was called 2 times'));
152 return cb(new Error('Socket is closed'));
155 self._handle.setOCSPResponse(response);
161 function onclienthello(hello) {
164 loadSession(self, hello, function(err, session) {
166 return self.destroy(err);
168 self._handle.endParser();
173 function oncertcb(info) {
175 var servername = info.servername;
177 loadSNI(self, servername, function(err, ctx) {
179 return self.destroy(err);
180 requestOCSP(self, info, ctx, function(err) {
182 return self.destroy(err);
185 return self.destroy(new Error('Socket is closed'));
187 self._handle.certCbDone();
193 function onnewsession(key, session) {
200 this._newSessionPending = true;
201 if (!this.server.emit('newSession', key, session, done))
210 return self.destroy(new Error('Socket is closed'));
212 self._handle.newSessionDone();
214 self._newSessionPending = false;
215 if (self._securePending)
217 self._securePending = false;
222 function onocspresponse(resp) {
223 this.emit('OCSPResponse', resp);
226 function initRead(tls, wrapped) {
227 // If we were destroyed already don't bother reading
231 // Socket already has some buffered data - emulate receiving it
232 if (wrapped && wrapped._readableState && wrapped._readableState.length) {
234 while ((buf = wrapped.read()) !== null)
235 tls._handle.receive(buf);
242 * Provides a wrap of socket stream to do encrypted communication.
245 function TLSSocket(socket, options) {
246 if (options === undefined)
247 this._tlsOptions = {};
249 this._tlsOptions = options;
250 this._secureEstablished = false;
251 this._securePending = false;
252 this._newSessionPending = false;
253 this._controlReleased = false;
254 this._SNICallback = null;
255 this.servername = null;
256 this.npnProtocol = null;
257 this.authorized = false;
258 this.authorizationError = null;
260 // Wrap plain JS Stream into StreamWrap
262 if (!(socket instanceof net.Socket) && socket instanceof Duplex)
263 wrap = new StreamWrap(socket);
264 else if ((socket instanceof net.Socket) && !socket._handle)
265 wrap = new StreamWrap(socket);
269 // Just a documented property to make secure sockets
270 // distinguishable from regular ones.
271 this.encrypted = true;
273 net.Socket.call(this, {
274 handle: this._wrapHandle(wrap),
275 allowHalfOpen: socket && socket.allowHalfOpen,
280 // Proxy for API compatibility
281 this.ssl = this._handle;
283 this.on('error', this._emitTLSError);
285 this._init(socket, wrap);
287 // Make sure to setup all required properties like: `_connecting` before
288 // starting the flow of the data
289 this.readable = true;
290 this.writable = true;
292 // Read on next tick so the caller has a chance to setup listeners
293 process.nextTick(initRead, this, socket);
295 util.inherits(TLSSocket, net.Socket);
296 exports.TLSSocket = TLSSocket;
298 var proxiedMethods = [
299 'ref', 'unref', 'open', 'bind', 'listen', 'connect', 'bind6',
300 'connect6', 'getsockname', 'getpeername', 'setNoDelay', 'setKeepAlive',
301 'setSimultaneousAccepts', 'setBlocking',
304 'setPendingInstances'
307 // Proxy HandleWrap, PipeWrap and TCPWrap methods
308 proxiedMethods.forEach(function(name) {
309 tls_wrap.TLSWrap.prototype[name] = function methodProxy() {
310 if (this._parent[name])
311 return this._parent[name].apply(this._parent, arguments);
315 tls_wrap.TLSWrap.prototype.close = function closeProxy(cb) {
316 if (this._parentWrap && this._parentWrap._handle === this._parent) {
317 this._parentWrap.once('close', cb);
318 return this._parentWrap.destroy();
320 return this._parent.close(cb);
323 TLSSocket.prototype._wrapHandle = function(wrap) {
328 handle = wrap._handle;
330 var options = this._tlsOptions;
332 handle = options.pipe ? new Pipe() : new TCP();
336 // Wrap socket's handle
337 var context = options.secureContext ||
338 options.credentials ||
339 tls.createSecureContext();
340 res = tls_wrap.wrap(handle._externalStream,
343 res._parent = handle;
344 res._parentWrap = wrap;
345 res._secureContext = context;
346 res.reading = handle.reading;
347 Object.defineProperty(handle, 'reading', {
348 get: function readingGetter() {
351 set: function readingSetter(value) {
356 this.on('close', function() {
357 // Make sure we are not doing it on OpenSSL's stack
358 setImmediate(destroySSL, this);
365 function destroySSL(self) {
369 TLSSocket.prototype._destroySSL = function _destroySSL() {
370 if (!this.ssl) return;
371 this.ssl.destroySSL();
372 if (this.ssl._secureContext.singleUse) {
373 this.ssl._secureContext.context.close();
374 this.ssl._secureContext.context = null;
379 TLSSocket.prototype._init = function(socket, wrap) {
381 var options = this._tlsOptions;
382 var ssl = this._handle;
384 // lib/net.js expect this value to be non-zero if write hasn't been flushed
386 // TODO(indutny): rewise this solution, it might be 1 before handshake and
387 // represent real writeQueueSize during regular writes.
388 ssl.writeQueueSize = 1;
390 this.server = options.server;
392 // Move the server to TLSSocket, otherwise both `socket.destroy()` and
393 // `TLSSocket.destroy()` will decrement number of connections of the TLS
394 // server, leading to misfiring `server.close()` callback
395 if (socket && socket.server === this.server)
396 socket.server = null;
398 // For clients, we will always have either a given ca list or be using
400 var requestCert = !!options.requestCert || !options.isServer,
401 rejectUnauthorized = !!options.rejectUnauthorized;
403 this._requestCert = requestCert;
404 this._rejectUnauthorized = rejectUnauthorized;
405 if (requestCert || rejectUnauthorized)
406 ssl.setVerifyMode(requestCert, rejectUnauthorized);
408 if (options.isServer) {
409 ssl.onhandshakestart = onhandshakestart.bind(this);
410 ssl.onhandshakedone = onhandshakedone.bind(this);
411 ssl.onclienthello = onclienthello.bind(this);
412 ssl.oncertcb = oncertcb.bind(this);
413 ssl.onnewsession = onnewsession.bind(this);
414 ssl.lastHandshakeTime = 0;
418 if (this.server.listenerCount('resumeSession') > 0 ||
419 this.server.listenerCount('newSession') > 0) {
420 ssl.enableSessionCallbacks();
422 if (this.server.listenerCount('OCSPRequest') > 0)
426 ssl.onhandshakestart = function() {};
427 ssl.onhandshakedone = this._finishInit.bind(this);
428 ssl.onocspresponse = onocspresponse.bind(this);
431 ssl.setSession(options.session);
434 ssl.onerror = function(err) {
435 if (self._writableState.errorEmitted)
438 // Destroy socket if error happened before handshake's finish
439 if (!self._secureEstablished) {
440 self.destroy(self._tlsError(err));
441 } else if (options.isServer &&
442 rejectUnauthorized &&
443 /peer did not return a certificate/.test(err.message)) {
444 // Ignore server's authorization errors
448 self._emitTLSError(err);
451 self._writableState.errorEmitted = true;
454 // If custom SNICallback was given, or if
455 // there're SNI contexts to perform match against -
456 // set `.onsniselect` callback.
457 if (process.features.tls_sni &&
459 options.SNICallback &&
461 (options.SNICallback !== SNICallback ||
462 options.server._contexts.length)) {
463 assert(typeof options.SNICallback === 'function');
464 this._SNICallback = options.SNICallback;
468 if (process.features.tls_npn && options.NPNProtocols)
469 ssl.setNPNProtocols(options.NPNProtocols);
471 if (options.handshakeTimeout > 0)
472 this.setTimeout(options.handshakeTimeout, this._handleTimeout);
474 if (socket instanceof net.Socket) {
475 this._parent = socket;
477 // To prevent assertion in afterConnect() and properly kick off readStart
478 this._connecting = socket._connecting || !socket._handle;
479 socket.once('connect', function() {
480 self._connecting = false;
481 self.emit('connect');
485 // Assume `tls.connect()`
487 wrap.on('error', function(err) {
488 self._emitTLSError(err);
492 this._connecting = true;
496 TLSSocket.prototype.renegotiate = function(options, callback) {
497 var requestCert = this._requestCert,
498 rejectUnauthorized = this._rejectUnauthorized;
503 if (typeof options.requestCert !== 'undefined')
504 requestCert = !!options.requestCert;
505 if (typeof options.rejectUnauthorized !== 'undefined')
506 rejectUnauthorized = !!options.rejectUnauthorized;
508 if (requestCert !== this._requestCert ||
509 rejectUnauthorized !== this._rejectUnauthorized) {
510 this._handle.setVerifyMode(requestCert, rejectUnauthorized);
511 this._requestCert = requestCert;
512 this._rejectUnauthorized = rejectUnauthorized;
514 if (!this._handle.renegotiate()) {
516 process.nextTick(callback, new Error('Failed to renegotiate'));
521 // Ensure that we'll cycle through internal openssl's state
525 this.once('secure', function() {
533 TLSSocket.prototype.setMaxSendFragment = function setMaxSendFragment(size) {
534 return this._handle.setMaxSendFragment(size) == 1;
537 TLSSocket.prototype.getTLSTicket = function getTLSTicket() {
538 return this._handle.getTLSTicket();
541 TLSSocket.prototype._handleTimeout = function() {
542 this._emitTLSError(new Error('TLS handshake timeout'));
545 TLSSocket.prototype._emitTLSError = function(err) {
546 var e = this._tlsError(err);
548 this.emit('error', e);
551 TLSSocket.prototype._tlsError = function(err) {
552 this.emit('_tlsError', err);
553 if (this._controlReleased)
558 TLSSocket.prototype._releaseControl = function() {
559 if (this._controlReleased)
561 this._controlReleased = true;
562 this.removeListener('error', this._emitTLSError);
566 TLSSocket.prototype._finishInit = function() {
567 // `newSession` callback wasn't called yet
568 if (this._newSessionPending) {
569 this._securePending = true;
573 if (process.features.tls_npn) {
574 this.npnProtocol = this._handle.getNegotiatedProtocol();
577 if (process.features.tls_sni && this._tlsOptions.isServer) {
578 this.servername = this._handle.getServername();
581 debug('secure established');
582 this._secureEstablished = true;
583 if (this._tlsOptions.handshakeTimeout > 0)
584 this.setTimeout(0, this._handleTimeout);
588 TLSSocket.prototype._start = function() {
589 if (this._connecting) {
590 this.once('connect', function() {
596 // Socket was destroyed before the connection was established
601 if (this._tlsOptions.requestOCSP)
602 this._handle.requestOCSP();
603 this._handle.start();
606 TLSSocket.prototype.setServername = function(name) {
607 this._handle.setServername(name);
610 TLSSocket.prototype.setSession = function(session) {
611 if (typeof session === 'string')
612 session = new Buffer(session, 'binary');
613 this._handle.setSession(session);
616 TLSSocket.prototype.getPeerCertificate = function(detailed) {
618 return common.translatePeerCertificate(
619 this._handle.getPeerCertificate(detailed));
625 TLSSocket.prototype.getSession = function() {
627 return this._handle.getSession();
633 TLSSocket.prototype.isSessionReused = function() {
635 return this._handle.isSessionReused();
641 TLSSocket.prototype.getCipher = function(err) {
643 return this._handle.getCurrentCipher();
649 // TODO: support anonymous (nocert) and PSK
652 // AUTHENTICATION MODES
654 // There are several levels of authentication that TLS/SSL supports.
655 // Read more about this in "man SSL_set_verify".
657 // 1. The server sends a certificate to the client but does not request a
658 // cert from the client. This is common for most HTTPS servers. The browser
659 // can verify the identity of the server, but the server does not know who
660 // the client is. Authenticating the client is usually done over HTTP using
661 // login boxes and cookies and stuff.
663 // 2. The server sends a cert to the client and requests that the client
664 // also send it a cert. The client knows who the server is and the server is
665 // requesting the client also identify themselves. There are several
668 // A) verifyError returns null meaning the client's certificate is signed
669 // by one of the server's CAs. The server know's the client idenity now
670 // and the client is authorized.
672 // B) For some reason the client's certificate is not acceptable -
673 // verifyError returns a string indicating the problem. The server can
674 // either (i) reject the client or (ii) allow the client to connect as an
675 // unauthorized connection.
677 // The mode is controlled by two boolean variables.
680 // If true the server requests a certificate from client connections. For
681 // the common HTTPS case, users will want this to be false, which is what
684 // rejectUnauthorized
685 // If true clients whose certificates are invalid for any reason will not
686 // be allowed to make connections. If false, they will simply be marked as
687 // unauthorized but secure communication will continue. By default this is
693 // - requestCert. Send verify request. Default to false.
694 // - rejectUnauthorized. Boolean, default to true.
697 // - ca: string or array of strings.
698 // - sessionTimeout: integer.
700 // emit 'secureConnection'
701 // function (tlsSocket) { }
703 // "UNABLE_TO_GET_ISSUER_CERT", "UNABLE_TO_GET_CRL",
704 // "UNABLE_TO_DECRYPT_CERT_SIGNATURE", "UNABLE_TO_DECRYPT_CRL_SIGNATURE",
705 // "UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY", "CERT_SIGNATURE_FAILURE",
706 // "CRL_SIGNATURE_FAILURE", "CERT_NOT_YET_VALID" "CERT_HAS_EXPIRED",
707 // "CRL_NOT_YET_VALID", "CRL_HAS_EXPIRED" "ERROR_IN_CERT_NOT_BEFORE_FIELD",
708 // "ERROR_IN_CERT_NOT_AFTER_FIELD", "ERROR_IN_CRL_LAST_UPDATE_FIELD",
709 // "ERROR_IN_CRL_NEXT_UPDATE_FIELD", "OUT_OF_MEM",
710 // "DEPTH_ZERO_SELF_SIGNED_CERT", "SELF_SIGNED_CERT_IN_CHAIN",
711 // "UNABLE_TO_GET_ISSUER_CERT_LOCALLY", "UNABLE_TO_VERIFY_LEAF_SIGNATURE",
712 // "CERT_CHAIN_TOO_LONG", "CERT_REVOKED" "INVALID_CA",
713 // "PATH_LENGTH_EXCEEDED", "INVALID_PURPOSE" "CERT_UNTRUSTED",
716 function Server(/* [options], listener */) {
717 var options, listener;
719 if (arguments[0] !== null && typeof arguments[0] === 'object') {
720 options = arguments[0];
721 listener = arguments[1];
722 } else if (typeof arguments[0] === 'function') {
724 listener = arguments[0];
727 if (!(this instanceof Server)) return new Server(options, listener);
733 // Handle option defaults:
734 this.setOptions(options);
736 var sharedCreds = tls.createSecureContext({
739 passphrase: self.passphrase,
742 ciphers: self.ciphers,
743 ecdhCurve: self.ecdhCurve,
744 dhparam: self.dhparam,
745 secureProtocol: self.secureProtocol,
746 secureOptions: self.secureOptions,
747 honorCipherOrder: self.honorCipherOrder,
749 sessionIdContext: self.sessionIdContext
751 this._sharedCreds = sharedCreds;
753 var timeout = options.handshakeTimeout || (120 * 1000);
755 if (typeof timeout !== 'number') {
756 throw new TypeError('handshakeTimeout must be a number');
759 if (self.sessionTimeout) {
760 sharedCreds.context.setSessionTimeout(self.sessionTimeout);
763 if (self.ticketKeys) {
764 sharedCreds.context.setTicketKeys(self.ticketKeys);
768 net.Server.call(this, function(raw_socket) {
769 var socket = new TLSSocket(raw_socket, {
770 secureContext: sharedCreds,
773 requestCert: self.requestCert,
774 rejectUnauthorized: self.rejectUnauthorized,
775 handshakeTimeout: timeout,
776 NPNProtocols: self.NPNProtocols,
777 SNICallback: options.SNICallback || SNICallback
780 socket.on('secure', function() {
781 if (socket._requestCert) {
782 var verifyError = socket._handle.verifyError();
784 socket.authorizationError = verifyError.code;
786 if (socket._rejectUnauthorized)
789 socket.authorized = true;
793 if (!socket.destroyed && socket._releaseControl())
794 self.emit('secureConnection', socket);
797 var errorEmitted = false;
798 socket.on('close', function(err) {
799 // Closed because of error - no need to emit it twice
804 if (!socket._controlReleased && !errorEmitted) {
806 var connReset = new Error('socket hang up');
807 connReset.code = 'ECONNRESET';
808 self.emit('clientError', connReset, socket);
812 socket.on('_tlsError', function(err) {
813 if (!socket._controlReleased && !errorEmitted) {
815 self.emit('clientError', err, socket);
821 this.on('secureConnection', listener);
825 util.inherits(Server, net.Server);
826 exports.Server = Server;
827 exports.createServer = function(options, listener) {
828 return new Server(options, listener);
832 Server.prototype._getServerData = function() {
834 ticketKeys: this.getTicketKeys().toString('hex')
839 Server.prototype._setServerData = function(data) {
840 this.setTicketKeys(new Buffer(data.ticketKeys, 'hex'));
844 Server.prototype.getTicketKeys = function getTicketKeys(keys) {
845 return this._sharedCreds.context.getTicketKeys(keys);
849 Server.prototype.setTicketKeys = function setTicketKeys(keys) {
850 this._sharedCreds.context.setTicketKeys(keys);
854 Server.prototype.setOptions = function(options) {
855 if (typeof options.requestCert === 'boolean') {
856 this.requestCert = options.requestCert;
858 this.requestCert = false;
861 if (typeof options.rejectUnauthorized === 'boolean') {
862 this.rejectUnauthorized = options.rejectUnauthorized;
864 this.rejectUnauthorized = false;
867 if (options.pfx) this.pfx = options.pfx;
868 if (options.key) this.key = options.key;
869 if (options.passphrase) this.passphrase = options.passphrase;
870 if (options.cert) this.cert = options.cert;
871 if (options.ca) this.ca = options.ca;
872 if (options.secureProtocol) this.secureProtocol = options.secureProtocol;
873 if (options.crl) this.crl = options.crl;
874 if (options.ciphers) this.ciphers = options.ciphers;
875 if (options.ecdhCurve !== undefined)
876 this.ecdhCurve = options.ecdhCurve;
877 if (options.dhparam) this.dhparam = options.dhparam;
878 if (options.sessionTimeout) this.sessionTimeout = options.sessionTimeout;
879 if (options.ticketKeys) this.ticketKeys = options.ticketKeys;
880 var secureOptions = options.secureOptions || 0;
881 if (options.honorCipherOrder !== undefined)
882 this.honorCipherOrder = !!options.honorCipherOrder;
884 this.honorCipherOrder = true;
885 if (secureOptions) this.secureOptions = secureOptions;
886 if (options.NPNProtocols) tls.convertNPNProtocols(options.NPNProtocols, this);
887 if (options.sessionIdContext) {
888 this.sessionIdContext = options.sessionIdContext;
890 this.sessionIdContext = defaultSessionIdContext;
894 // SNI Contexts High-Level API
895 Server.prototype.addContext = function(servername, context) {
897 throw new Error('Servername is required parameter for Server.addContext');
900 var re = new RegExp('^' +
901 servername.replace(/([\.^$+?\-\\[\]{}])/g, '\\$1')
902 .replace(/\*/g, '[^\.]*') +
904 this._contexts.push([re, tls.createSecureContext(context).context]);
907 function SNICallback(servername, callback) {
910 this.server._contexts.some(function(elem) {
911 if (servername.match(elem[0]) !== null) {
923 // var s = tls.connect({port: 8000, host: "google.com"}, function() {
924 // if (!s.authorized) {
931 // s.end("hello world\n");
935 function normalizeConnectArgs(listArgs) {
936 var args = net._normalizeConnectArgs(listArgs);
937 var options = args[0];
940 if (listArgs[1] !== null && typeof listArgs[1] === 'object') {
941 options = util._extend(options, listArgs[1]);
942 } else if (listArgs[2] !== null && typeof listArgs[2] === 'object') {
943 options = util._extend(options, listArgs[2]);
946 return (cb) ? [options, cb] : [options];
949 exports.connect = function(/* [port, host], options, cb */) {
950 var args = normalizeConnectArgs(arguments);
951 var options = args[0];
955 rejectUnauthorized: '0' !== process.env.NODE_TLS_REJECT_UNAUTHORIZED,
956 ciphers: tls.DEFAULT_CIPHERS,
957 checkServerIdentity: tls.checkServerIdentity
960 options = util._extend(defaults, options || {});
961 if (!options.keepAlive)
962 options.singleUse = true;
964 assert(typeof options.checkServerIdentity === 'function');
966 var hostname = options.servername ||
968 (options.socket && options.socket._host) ||
971 context = tls.createSecureContext(options);
972 tls.convertNPNProtocols(options.NPNProtocols, NPN);
974 var socket = new TLSSocket(options.socket, {
975 pipe: options.path && !options.port,
976 secureContext: context,
979 rejectUnauthorized: options.rejectUnauthorized,
980 session: options.session,
981 NPNProtocols: NPN.NPNProtocols,
982 requestOCSP: options.requestOCSP
986 socket.once('secureConnect', cb);
988 if (!options.socket) {
990 if (options.path && !options.port) {
991 connect_opt = { path: options.path };
996 localAddress: options.localAddress
999 socket.connect(connect_opt, function() {
1004 socket._releaseControl();
1006 if (options.session)
1007 socket.setSession(options.session);
1009 if (options.servername)
1010 socket.setServername(options.servername);
1015 socket.on('secure', function() {
1016 var verifyError = socket._handle.verifyError();
1018 // Verify that server's identity matches it's certificate's names
1019 // Unless server has resumed our existing session
1020 if (!verifyError && !socket.isSessionReused()) {
1021 var cert = socket.getPeerCertificate();
1022 verifyError = options.checkServerIdentity(hostname, cert);
1026 socket.authorized = false;
1027 socket.authorizationError = verifyError.code || verifyError.message;
1029 if (options.rejectUnauthorized) {
1030 socket.destroy(verifyError);
1033 socket.emit('secureConnect');
1036 socket.authorized = true;
1037 socket.emit('secureConnect');
1040 // Uncork incoming data
1041 socket.removeListener('end', onHangUp);
1044 function onHangUp() {
1045 // NOTE: This logic is shared with _http_client.js
1046 if (!socket._hadError) {
1047 socket._hadError = true;
1048 var error = new Error('socket hang up');
1049 error.code = 'ECONNRESET';
1050 socket.destroy(error);
1053 socket.once('end', onHangUp);