2014-11-22 15:59:48 +00:00
|
|
|
'use strict';
|
|
|
|
|
2015-01-21 16:36:59 +00:00
|
|
|
const assert = require('assert');
|
|
|
|
const crypto = require('crypto');
|
|
|
|
const net = require('net');
|
|
|
|
const tls = require('tls');
|
|
|
|
const util = require('util');
|
|
|
|
const listenerCount = require('events').listenerCount;
|
|
|
|
const common = require('_tls_common');
|
|
|
|
const debug = util.debuglog('tls');
|
|
|
|
const Timer = process.binding('timer_wrap').Timer;
|
|
|
|
const tls_wrap = process.binding('tls_wrap');
|
2013-06-13 13:36:00 +00:00
|
|
|
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
// constructor for lazy loading
|
|
|
|
function createTCP() {
|
|
|
|
var TCP = process.binding('tcp_wrap').TCP;
|
|
|
|
return new TCP();
|
|
|
|
}
|
|
|
|
|
|
|
|
// constructor for lazy loading
|
|
|
|
function createPipe() {
|
|
|
|
var Pipe = process.binding('pipe_wrap').Pipe;
|
|
|
|
return new Pipe();
|
|
|
|
}
|
2013-09-24 12:53:49 +00:00
|
|
|
|
2013-06-13 13:36:00 +00:00
|
|
|
function onhandshakestart() {
|
|
|
|
debug('onhandshakestart');
|
|
|
|
|
|
|
|
var self = this;
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
var ssl = self._handle;
|
2013-06-13 13:36:00 +00:00
|
|
|
var now = Timer.now();
|
|
|
|
|
|
|
|
assert(now >= ssl.lastHandshakeTime);
|
|
|
|
|
|
|
|
if ((now - ssl.lastHandshakeTime) >= tls.CLIENT_RENEG_WINDOW * 1000) {
|
|
|
|
ssl.handshakes = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
var first = (ssl.lastHandshakeTime === 0);
|
|
|
|
ssl.lastHandshakeTime = now;
|
|
|
|
if (first) return;
|
|
|
|
|
|
|
|
if (++ssl.handshakes > tls.CLIENT_RENEG_LIMIT) {
|
|
|
|
// Defer the error event to the next tick. We're being called from OpenSSL's
|
|
|
|
// state machine and OpenSSL is not re-entrant. We cannot allow the user's
|
|
|
|
// callback to destroy the connection right now, it would crash and burn.
|
|
|
|
setImmediate(function() {
|
|
|
|
var err = new Error('TLS session renegotiation attack detected.');
|
|
|
|
self._tlsError(err);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function onhandshakedone() {
|
|
|
|
// for future use
|
|
|
|
debug('onhandshakedone');
|
|
|
|
this._finishInit();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-04-14 17:15:57 +00:00
|
|
|
function loadSession(self, hello, cb) {
|
|
|
|
var once = false;
|
|
|
|
function onSession(err, session) {
|
|
|
|
if (once)
|
|
|
|
return cb(new Error('TLS session callback was called 2 times'));
|
|
|
|
once = true;
|
2013-06-17 10:11:13 +00:00
|
|
|
|
|
|
|
if (err)
|
2014-04-14 17:15:57 +00:00
|
|
|
return cb(err);
|
2013-06-17 10:11:13 +00:00
|
|
|
|
2013-08-03 17:29:54 +00:00
|
|
|
// NOTE: That we have disabled OpenSSL's internal session storage in
|
|
|
|
// `node_crypto.cc` and hence its safe to rely on getting servername only
|
|
|
|
// from clienthello or this place.
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
var ret = self._handle.loadSession(session);
|
2013-08-03 17:29:54 +00:00
|
|
|
|
2014-04-14 17:15:57 +00:00
|
|
|
cb(null, ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (hello.sessionId.length <= 0 ||
|
|
|
|
hello.tlsTicket ||
|
|
|
|
self.server &&
|
|
|
|
!self.server.emit('resumeSession', hello.sessionId, onSession)) {
|
|
|
|
cb(null);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function loadSNI(self, servername, cb) {
|
|
|
|
if (!servername || !self._SNICallback)
|
|
|
|
return cb(null);
|
|
|
|
|
|
|
|
var once = false;
|
|
|
|
self._SNICallback(servername, function(err, context) {
|
|
|
|
if (once)
|
|
|
|
return cb(new Error('TLS SNI callback was called 2 times'));
|
|
|
|
once = true;
|
|
|
|
|
|
|
|
if (err)
|
|
|
|
return cb(err);
|
|
|
|
|
|
|
|
// TODO(indutny): eventually disallow raw `SecureContext`
|
|
|
|
if (context)
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
self._handle.sni_context = context.context || context;
|
2014-04-14 17:15:57 +00:00
|
|
|
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
cb(null, self._handle.sni_context);
|
2014-04-14 17:15:57 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function requestOCSP(self, hello, ctx, cb) {
|
|
|
|
if (!hello.OCSPRequest || !self.server)
|
|
|
|
return cb(null);
|
|
|
|
|
|
|
|
if (!ctx)
|
|
|
|
ctx = self.server._sharedCreds;
|
|
|
|
if (ctx.context)
|
|
|
|
ctx = ctx.context;
|
|
|
|
|
2014-08-11 08:41:18 +00:00
|
|
|
if (listenerCount(self.server, 'OCSPRequest') === 0) {
|
2014-04-14 17:15:57 +00:00
|
|
|
return cb(null);
|
|
|
|
} else {
|
|
|
|
self.server.emit('OCSPRequest',
|
|
|
|
ctx.getCertificate(),
|
|
|
|
ctx.getIssuer(),
|
|
|
|
onOCSP);
|
|
|
|
}
|
|
|
|
|
|
|
|
var once = false;
|
|
|
|
function onOCSP(err, response) {
|
|
|
|
if (once)
|
|
|
|
return cb(new Error('TLS OCSP callback was called 2 times'));
|
|
|
|
once = true;
|
|
|
|
|
|
|
|
if (err)
|
|
|
|
return cb(err);
|
|
|
|
|
|
|
|
if (response)
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
self._handle.setOCSPResponse(response);
|
2014-04-14 17:15:57 +00:00
|
|
|
cb(null);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function onclienthello(hello) {
|
|
|
|
var self = this;
|
|
|
|
|
|
|
|
loadSession(self, hello, function(err, session) {
|
|
|
|
if (err)
|
|
|
|
return self.destroy(err);
|
|
|
|
|
2013-08-03 17:29:54 +00:00
|
|
|
// Servername came from SSL session
|
|
|
|
// NOTE: TLS Session ticket doesn't include servername information
|
|
|
|
//
|
|
|
|
// Another note, From RFC3546:
|
|
|
|
//
|
|
|
|
// If, on the other hand, the older
|
|
|
|
// session is resumed, then the server MUST ignore extensions appearing
|
|
|
|
// in the client hello, and send a server hello containing no
|
|
|
|
// extensions; in this case the extension functionality negotiated
|
|
|
|
// during the original session initiation is applied to the resumed
|
|
|
|
// session.
|
|
|
|
//
|
|
|
|
// Therefore we should account session loading when dealing with servername
|
2014-04-14 17:15:57 +00:00
|
|
|
var servername = session && session.servername || hello.servername;
|
|
|
|
loadSNI(self, servername, function(err, ctx) {
|
|
|
|
if (err)
|
|
|
|
return self.destroy(err);
|
|
|
|
requestOCSP(self, hello, ctx, function(err) {
|
|
|
|
if (err)
|
|
|
|
return self.destroy(err);
|
|
|
|
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
self._handle.endParser();
|
2014-04-14 17:15:57 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
2013-06-17 10:11:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function onnewsession(key, session) {
|
2014-02-14 13:01:34 +00:00
|
|
|
if (!this.server)
|
|
|
|
return;
|
|
|
|
|
|
|
|
var self = this;
|
|
|
|
var once = false;
|
|
|
|
|
|
|
|
this._newSessionPending = true;
|
2014-11-04 16:14:55 +00:00
|
|
|
if (!this.server.emit('newSession', key, session, done))
|
|
|
|
done();
|
|
|
|
|
|
|
|
function done() {
|
2014-02-14 13:01:34 +00:00
|
|
|
if (once)
|
|
|
|
return;
|
|
|
|
once = true;
|
|
|
|
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
self._handle.newSessionDone();
|
2014-02-14 13:01:34 +00:00
|
|
|
|
|
|
|
self._newSessionPending = false;
|
|
|
|
if (self._securePending)
|
|
|
|
self._finishInit();
|
|
|
|
self._securePending = false;
|
2014-11-04 16:14:55 +00:00
|
|
|
}
|
2013-06-17 10:11:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-04-14 17:15:57 +00:00
|
|
|
function onocspresponse(resp) {
|
|
|
|
this.emit('OCSPResponse', resp);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-06-13 13:36:00 +00:00
|
|
|
/**
|
|
|
|
* Provides a wrap of socket stream to do encrypted communication.
|
|
|
|
*/
|
|
|
|
|
|
|
|
function TLSSocket(socket, options) {
|
|
|
|
this._tlsOptions = options;
|
|
|
|
this._secureEstablished = false;
|
2014-02-14 13:01:34 +00:00
|
|
|
this._securePending = false;
|
|
|
|
this._newSessionPending = false;
|
2013-06-13 13:36:00 +00:00
|
|
|
this._controlReleased = false;
|
2013-08-03 17:29:54 +00:00
|
|
|
this._SNICallback = null;
|
2013-06-13 13:36:00 +00:00
|
|
|
this.servername = null;
|
|
|
|
this.npnProtocol = null;
|
|
|
|
this.authorized = false;
|
|
|
|
this.authorizationError = null;
|
|
|
|
|
2013-12-19 09:04:34 +00:00
|
|
|
// Just a documented property to make secure sockets
|
|
|
|
// distinguishable from regular ones.
|
|
|
|
this.encrypted = true;
|
|
|
|
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
net.Socket.call(this, {
|
|
|
|
handle: this._wrapHandle(socket && socket._handle),
|
|
|
|
allowHalfOpen: socket && socket.allowHalfOpen,
|
|
|
|
readable: false,
|
|
|
|
writable: false
|
|
|
|
});
|
|
|
|
|
|
|
|
// Proxy for API compatibility
|
|
|
|
this.ssl = this._handle;
|
|
|
|
|
2013-08-07 12:50:36 +00:00
|
|
|
this.on('error', this._tlsError);
|
|
|
|
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
this._init(socket);
|
2014-04-14 10:12:35 +00:00
|
|
|
|
|
|
|
// Make sure to setup all required properties like: `_connecting` before
|
|
|
|
// starting the flow of the data
|
|
|
|
this.readable = true;
|
|
|
|
this.writable = true;
|
|
|
|
this.read(0);
|
2013-06-13 13:36:00 +00:00
|
|
|
}
|
|
|
|
util.inherits(TLSSocket, net.Socket);
|
2013-07-03 07:46:01 +00:00
|
|
|
exports.TLSSocket = TLSSocket;
|
2013-06-13 13:36:00 +00:00
|
|
|
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
var proxiedMethods = [
|
|
|
|
'close', 'ref', 'unref', 'open', 'bind', 'listen', 'connect', 'bind6',
|
|
|
|
'connect6', 'getsockname', 'getpeername', 'setNoDelay', 'setKeepAlive',
|
|
|
|
'setSimultaneousAccepts', 'setBlocking',
|
2013-06-13 13:36:00 +00:00
|
|
|
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
// PipeWrap
|
|
|
|
'setPendingInstances'
|
|
|
|
];
|
|
|
|
|
|
|
|
TLSSocket.prototype._wrapHandle = function(handle) {
|
|
|
|
var res;
|
2013-06-13 13:36:00 +00:00
|
|
|
|
|
|
|
var options = this._tlsOptions;
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
if (!handle) {
|
|
|
|
handle = options.pipe ? createPipe() : createTCP();
|
|
|
|
handle.owner = this;
|
|
|
|
}
|
2013-06-13 13:36:00 +00:00
|
|
|
|
|
|
|
// Wrap socket's handle
|
2014-03-06 23:27:01 +00:00
|
|
|
var context = options.secureContext ||
|
|
|
|
options.credentials ||
|
|
|
|
tls.createSecureContext();
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
res = tls_wrap.wrap(handle, context.context, options.isServer);
|
|
|
|
res._parent = handle;
|
|
|
|
res._reading = handle._reading;
|
|
|
|
|
|
|
|
// Proxy HandleWrap, PipeWrap and TCPWrap methods
|
|
|
|
proxiedMethods.forEach(function(name) {
|
|
|
|
res[name] = function methodProxy() {
|
|
|
|
return handle[name].apply(handle, arguments);
|
|
|
|
};
|
|
|
|
});
|
|
|
|
|
|
|
|
return res;
|
|
|
|
};
|
|
|
|
|
|
|
|
TLSSocket.prototype._init = function(socket) {
|
|
|
|
var self = this;
|
|
|
|
var options = this._tlsOptions;
|
|
|
|
var ssl = this._handle;
|
|
|
|
|
|
|
|
// lib/net.js expect this value to be non-zero if write hasn't been flushed
|
|
|
|
// immediately
|
|
|
|
// TODO(indutny): rewise this solution, it might be 1 before handshake and
|
|
|
|
// represent real writeQueueSize during regular writes.
|
|
|
|
ssl.writeQueueSize = 1;
|
|
|
|
|
2013-06-17 10:11:13 +00:00
|
|
|
this.server = options.server || null;
|
2013-06-13 13:36:00 +00:00
|
|
|
|
|
|
|
// For clients, we will always have either a given ca list or be using
|
|
|
|
// default one
|
|
|
|
var requestCert = !!options.requestCert || !options.isServer,
|
|
|
|
rejectUnauthorized = !!options.rejectUnauthorized;
|
|
|
|
|
2013-08-23 13:53:16 +00:00
|
|
|
this._requestCert = requestCert;
|
|
|
|
this._rejectUnauthorized = rejectUnauthorized;
|
2013-06-13 13:36:00 +00:00
|
|
|
if (requestCert || rejectUnauthorized)
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
ssl.setVerifyMode(requestCert, rejectUnauthorized);
|
2013-06-13 13:36:00 +00:00
|
|
|
|
|
|
|
if (options.isServer) {
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
ssl.onhandshakestart = onhandshakestart.bind(this);
|
|
|
|
ssl.onhandshakedone = onhandshakedone.bind(this);
|
|
|
|
ssl.onclienthello = onclienthello.bind(this);
|
|
|
|
ssl.onnewsession = onnewsession.bind(this);
|
|
|
|
ssl.lastHandshakeTime = 0;
|
|
|
|
ssl.handshakes = 0;
|
2013-06-17 10:11:13 +00:00
|
|
|
|
2013-07-03 07:46:01 +00:00
|
|
|
if (this.server &&
|
2014-08-11 08:41:18 +00:00
|
|
|
(listenerCount(this.server, 'resumeSession') > 0 ||
|
|
|
|
listenerCount(this.server, 'newSession') > 0 ||
|
|
|
|
listenerCount(this.server, 'OCSPRequest') > 0)) {
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
ssl.enableSessionCallbacks();
|
2013-06-17 10:11:13 +00:00
|
|
|
}
|
2013-06-13 13:36:00 +00:00
|
|
|
} else {
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
ssl.onhandshakestart = function() {};
|
|
|
|
ssl.onhandshakedone = this._finishInit.bind(this);
|
|
|
|
ssl.onocspresponse = onocspresponse.bind(this);
|
2014-02-03 21:32:13 +00:00
|
|
|
|
|
|
|
if (options.session)
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
ssl.setSession(options.session);
|
2013-06-13 13:36:00 +00:00
|
|
|
}
|
|
|
|
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
ssl.onerror = function(err) {
|
2014-02-09 11:09:34 +00:00
|
|
|
if (self._writableState.errorEmitted)
|
2014-01-22 01:07:11 +00:00
|
|
|
return;
|
2014-02-09 11:09:34 +00:00
|
|
|
self._writableState.errorEmitted = true;
|
2014-01-22 01:07:11 +00:00
|
|
|
|
2013-06-13 13:36:00 +00:00
|
|
|
// Destroy socket if error happened before handshake's finish
|
|
|
|
if (!this._secureEstablished) {
|
|
|
|
self._tlsError(err);
|
|
|
|
self.destroy();
|
|
|
|
} else if (options.isServer &&
|
|
|
|
rejectUnauthorized &&
|
|
|
|
/peer did not return a certificate/.test(err.message)) {
|
|
|
|
// Ignore server's authorization errors
|
|
|
|
self.destroy();
|
|
|
|
} else {
|
|
|
|
// Throw error
|
|
|
|
self._tlsError(err);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2013-08-02 16:11:17 +00:00
|
|
|
// If custom SNICallback was given, or if
|
|
|
|
// there're SNI contexts to perform match against -
|
|
|
|
// set `.onsniselect` callback.
|
2013-06-13 13:36:00 +00:00
|
|
|
if (process.features.tls_sni &&
|
|
|
|
options.isServer &&
|
2013-07-03 07:46:01 +00:00
|
|
|
options.server &&
|
2013-08-02 16:11:17 +00:00
|
|
|
(options.SNICallback !== SNICallback ||
|
|
|
|
options.server._contexts.length)) {
|
|
|
|
assert(typeof options.SNICallback === 'function');
|
2013-08-03 17:29:54 +00:00
|
|
|
this._SNICallback = options.SNICallback;
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
ssl.enableHelloParser();
|
2013-06-13 13:36:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (process.features.tls_npn && options.NPNProtocols)
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
ssl.setNPNProtocols(options.NPNProtocols);
|
2013-08-23 13:53:16 +00:00
|
|
|
|
|
|
|
if (options.handshakeTimeout > 0)
|
|
|
|
this.setTimeout(options.handshakeTimeout, this._handleTimeout);
|
2014-01-23 12:55:28 +00:00
|
|
|
|
|
|
|
// Socket already has some buffered data - emulate receiving it
|
|
|
|
if (socket && socket._readableState.length) {
|
|
|
|
var buf;
|
|
|
|
while ((buf = socket.read()) !== null)
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
ssl.receive(buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (socket) {
|
|
|
|
this._parent = socket;
|
|
|
|
|
|
|
|
// To prevent assertion in afterConnect() and properly kick off readStart
|
|
|
|
this._connecting = socket._connecting;
|
|
|
|
socket.once('connect', function() {
|
|
|
|
self._connecting = false;
|
|
|
|
self.emit('connect');
|
|
|
|
});
|
2014-01-23 12:55:28 +00:00
|
|
|
}
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
|
|
|
|
// Assume `tls.connect()`
|
|
|
|
if (!socket)
|
|
|
|
this._connecting = true;
|
2013-08-23 13:53:16 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
TLSSocket.prototype.renegotiate = function(options, callback) {
|
|
|
|
var requestCert = this._requestCert,
|
|
|
|
rejectUnauthorized = this._rejectUnauthorized;
|
|
|
|
|
|
|
|
if (typeof options.requestCert !== 'undefined')
|
|
|
|
requestCert = !!options.requestCert;
|
|
|
|
if (typeof options.rejectUnauthorized !== 'undefined')
|
|
|
|
rejectUnauthorized = !!options.rejectUnauthorized;
|
|
|
|
|
|
|
|
if (requestCert !== this._requestCert ||
|
|
|
|
rejectUnauthorized !== this._rejectUnauthorized) {
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
this._handle.setVerifyMode(requestCert, rejectUnauthorized);
|
2013-08-23 13:53:16 +00:00
|
|
|
this._requestCert = requestCert;
|
|
|
|
this._rejectUnauthorized = rejectUnauthorized;
|
|
|
|
}
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
if (!this._handle.renegotiate()) {
|
2013-08-23 13:53:16 +00:00
|
|
|
if (callback) {
|
|
|
|
process.nextTick(function() {
|
|
|
|
callback(new Error('Failed to renegotiate'));
|
|
|
|
});
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ensure that we'll cycle through internal openssl's state
|
|
|
|
this.write('');
|
|
|
|
|
|
|
|
if (callback) {
|
|
|
|
this.once('secure', function() {
|
|
|
|
callback(null);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
};
|
|
|
|
|
2014-01-17 18:46:49 +00:00
|
|
|
TLSSocket.prototype.setMaxSendFragment = function setMaxSendFragment(size) {
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
return this._handle.setMaxSendFragment(size) == 1;
|
2014-01-17 18:46:49 +00:00
|
|
|
};
|
|
|
|
|
2014-02-03 21:32:13 +00:00
|
|
|
TLSSocket.prototype.getTLSTicket = function getTLSTicket() {
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
return this._handle.getTLSTicket();
|
2014-02-03 21:32:13 +00:00
|
|
|
};
|
|
|
|
|
2013-08-23 13:53:16 +00:00
|
|
|
TLSSocket.prototype._handleTimeout = function() {
|
|
|
|
this._tlsError(new Error('TLS handshake timeout'));
|
2013-06-13 13:36:00 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
TLSSocket.prototype._tlsError = function(err) {
|
|
|
|
this.emit('_tlsError', err);
|
|
|
|
if (this._controlReleased)
|
|
|
|
this.emit('error', err);
|
|
|
|
};
|
|
|
|
|
2013-08-07 12:50:36 +00:00
|
|
|
TLSSocket.prototype._releaseControl = function() {
|
|
|
|
if (this._controlReleased)
|
2013-08-23 13:53:16 +00:00
|
|
|
return false;
|
2013-08-07 12:50:36 +00:00
|
|
|
this._controlReleased = true;
|
|
|
|
this.removeListener('error', this._tlsError);
|
2013-08-23 13:53:16 +00:00
|
|
|
return true;
|
2013-08-07 12:50:36 +00:00
|
|
|
};
|
|
|
|
|
2013-06-13 13:36:00 +00:00
|
|
|
TLSSocket.prototype._finishInit = function() {
|
2014-02-14 13:01:34 +00:00
|
|
|
// `newSession` callback wasn't called yet
|
|
|
|
if (this._newSessionPending) {
|
|
|
|
this._securePending = true;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-06-13 13:36:00 +00:00
|
|
|
if (process.features.tls_npn) {
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
this.npnProtocol = this._handle.getNegotiatedProtocol();
|
2013-06-13 13:36:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (process.features.tls_sni && this._tlsOptions.isServer) {
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
this.servername = this._handle.getServername();
|
2013-06-13 13:36:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
debug('secure established');
|
|
|
|
this._secureEstablished = true;
|
2013-08-23 13:53:16 +00:00
|
|
|
if (this._tlsOptions.handshakeTimeout > 0)
|
|
|
|
this.setTimeout(0, this._handleTimeout);
|
2013-06-13 13:36:00 +00:00
|
|
|
this.emit('secure');
|
|
|
|
};
|
|
|
|
|
|
|
|
TLSSocket.prototype._start = function() {
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
if (this._connecting) {
|
|
|
|
this.once('connect', function() {
|
|
|
|
this._start();
|
|
|
|
});
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-04-14 17:15:57 +00:00
|
|
|
if (this._tlsOptions.requestOCSP)
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
this._handle.requestOCSP();
|
|
|
|
this._handle.start();
|
2013-06-13 13:36:00 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
TLSSocket.prototype.setServername = function(name) {
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
this._handle.setServername(name);
|
2013-06-13 13:36:00 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
TLSSocket.prototype.setSession = function(session) {
|
2015-01-29 01:05:53 +00:00
|
|
|
if (typeof session === 'string')
|
2013-06-13 13:36:00 +00:00
|
|
|
session = new Buffer(session, 'binary');
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
this._handle.setSession(session);
|
2013-06-13 13:36:00 +00:00
|
|
|
};
|
|
|
|
|
2014-04-17 11:57:36 +00:00
|
|
|
TLSSocket.prototype.getPeerCertificate = function(detailed) {
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
if (this._handle) {
|
2014-04-17 11:57:36 +00:00
|
|
|
return common.translatePeerCertificate(
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
this._handle.getPeerCertificate(detailed));
|
2014-04-17 11:57:36 +00:00
|
|
|
}
|
2013-06-13 13:36:00 +00:00
|
|
|
|
|
|
|
return null;
|
|
|
|
};
|
|
|
|
|
|
|
|
TLSSocket.prototype.getSession = function() {
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
if (this._handle) {
|
|
|
|
return this._handle.getSession();
|
2013-06-13 13:36:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
};
|
|
|
|
|
|
|
|
TLSSocket.prototype.isSessionReused = function() {
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
if (this._handle) {
|
|
|
|
return this._handle.isSessionReused();
|
2013-06-13 13:36:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
};
|
|
|
|
|
|
|
|
TLSSocket.prototype.getCipher = function(err) {
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
if (this._handle) {
|
|
|
|
return this._handle.getCurrentCipher();
|
2013-06-13 13:36:00 +00:00
|
|
|
} else {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// TODO: support anonymous (nocert) and PSK
|
|
|
|
|
|
|
|
|
|
|
|
// AUTHENTICATION MODES
|
|
|
|
//
|
|
|
|
// There are several levels of authentication that TLS/SSL supports.
|
|
|
|
// Read more about this in "man SSL_set_verify".
|
|
|
|
//
|
|
|
|
// 1. The server sends a certificate to the client but does not request a
|
|
|
|
// cert from the client. This is common for most HTTPS servers. The browser
|
|
|
|
// can verify the identity of the server, but the server does not know who
|
|
|
|
// the client is. Authenticating the client is usually done over HTTP using
|
|
|
|
// login boxes and cookies and stuff.
|
|
|
|
//
|
|
|
|
// 2. The server sends a cert to the client and requests that the client
|
|
|
|
// also send it a cert. The client knows who the server is and the server is
|
|
|
|
// requesting the client also identify themselves. There are several
|
|
|
|
// outcomes:
|
|
|
|
//
|
|
|
|
// A) verifyError returns null meaning the client's certificate is signed
|
|
|
|
// by one of the server's CAs. The server know's the client idenity now
|
|
|
|
// and the client is authorized.
|
|
|
|
//
|
|
|
|
// B) For some reason the client's certificate is not acceptable -
|
|
|
|
// verifyError returns a string indicating the problem. The server can
|
|
|
|
// either (i) reject the client or (ii) allow the client to connect as an
|
|
|
|
// unauthorized connection.
|
|
|
|
//
|
|
|
|
// The mode is controlled by two boolean variables.
|
|
|
|
//
|
|
|
|
// requestCert
|
|
|
|
// If true the server requests a certificate from client connections. For
|
|
|
|
// the common HTTPS case, users will want this to be false, which is what
|
|
|
|
// it defaults to.
|
|
|
|
//
|
|
|
|
// rejectUnauthorized
|
|
|
|
// If true clients whose certificates are invalid for any reason will not
|
|
|
|
// be allowed to make connections. If false, they will simply be marked as
|
|
|
|
// unauthorized but secure communication will continue. By default this is
|
|
|
|
// true.
|
|
|
|
//
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// Options:
|
|
|
|
// - requestCert. Send verify request. Default to false.
|
|
|
|
// - rejectUnauthorized. Boolean, default to true.
|
|
|
|
// - key. string.
|
|
|
|
// - cert: string.
|
|
|
|
// - ca: string or array of strings.
|
|
|
|
// - sessionTimeout: integer.
|
|
|
|
//
|
|
|
|
// emit 'secureConnection'
|
|
|
|
// function (tlsSocket) { }
|
|
|
|
//
|
|
|
|
// "UNABLE_TO_GET_ISSUER_CERT", "UNABLE_TO_GET_CRL",
|
|
|
|
// "UNABLE_TO_DECRYPT_CERT_SIGNATURE", "UNABLE_TO_DECRYPT_CRL_SIGNATURE",
|
|
|
|
// "UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY", "CERT_SIGNATURE_FAILURE",
|
|
|
|
// "CRL_SIGNATURE_FAILURE", "CERT_NOT_YET_VALID" "CERT_HAS_EXPIRED",
|
|
|
|
// "CRL_NOT_YET_VALID", "CRL_HAS_EXPIRED" "ERROR_IN_CERT_NOT_BEFORE_FIELD",
|
|
|
|
// "ERROR_IN_CERT_NOT_AFTER_FIELD", "ERROR_IN_CRL_LAST_UPDATE_FIELD",
|
|
|
|
// "ERROR_IN_CRL_NEXT_UPDATE_FIELD", "OUT_OF_MEM",
|
|
|
|
// "DEPTH_ZERO_SELF_SIGNED_CERT", "SELF_SIGNED_CERT_IN_CHAIN",
|
|
|
|
// "UNABLE_TO_GET_ISSUER_CERT_LOCALLY", "UNABLE_TO_VERIFY_LEAF_SIGNATURE",
|
|
|
|
// "CERT_CHAIN_TOO_LONG", "CERT_REVOKED" "INVALID_CA",
|
|
|
|
// "PATH_LENGTH_EXCEEDED", "INVALID_PURPOSE" "CERT_UNTRUSTED",
|
|
|
|
// "CERT_REJECTED"
|
|
|
|
//
|
|
|
|
function Server(/* [options], listener */) {
|
|
|
|
var options, listener;
|
2015-01-29 01:05:53 +00:00
|
|
|
|
|
|
|
if (arguments[0] !== null && typeof arguments[0] === 'object') {
|
2013-06-13 13:36:00 +00:00
|
|
|
options = arguments[0];
|
|
|
|
listener = arguments[1];
|
2015-01-29 01:05:53 +00:00
|
|
|
} else if (typeof arguments[0] === 'function') {
|
2013-06-13 13:36:00 +00:00
|
|
|
options = {};
|
|
|
|
listener = arguments[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(this instanceof Server)) return new Server(options, listener);
|
|
|
|
|
|
|
|
this._contexts = [];
|
|
|
|
|
|
|
|
var self = this;
|
|
|
|
|
|
|
|
// Handle option defaults:
|
|
|
|
this.setOptions(options);
|
|
|
|
|
2014-03-06 23:27:01 +00:00
|
|
|
var sharedCreds = tls.createSecureContext({
|
2013-06-13 13:36:00 +00:00
|
|
|
pfx: self.pfx,
|
|
|
|
key: self.key,
|
|
|
|
passphrase: self.passphrase,
|
|
|
|
cert: self.cert,
|
|
|
|
ca: self.ca,
|
2014-03-06 23:27:01 +00:00
|
|
|
ciphers: self.ciphers,
|
|
|
|
ecdhCurve: self.ecdhCurve,
|
2014-08-27 09:00:13 +00:00
|
|
|
dhparam: self.dhparam,
|
2013-06-13 13:36:00 +00:00
|
|
|
secureProtocol: self.secureProtocol,
|
|
|
|
secureOptions: self.secureOptions,
|
2014-06-25 10:47:59 +00:00
|
|
|
honorCipherOrder: self.honorCipherOrder,
|
2013-06-13 13:36:00 +00:00
|
|
|
crl: self.crl,
|
|
|
|
sessionIdContext: self.sessionIdContext
|
|
|
|
});
|
2013-07-21 03:11:02 +00:00
|
|
|
this._sharedCreds = sharedCreds;
|
2013-06-13 13:36:00 +00:00
|
|
|
|
|
|
|
var timeout = options.handshakeTimeout || (120 * 1000);
|
|
|
|
|
2015-01-29 01:05:53 +00:00
|
|
|
if (typeof timeout !== 'number') {
|
2013-06-13 13:36:00 +00:00
|
|
|
throw new TypeError('handshakeTimeout must be a number');
|
|
|
|
}
|
|
|
|
|
|
|
|
if (self.sessionTimeout) {
|
|
|
|
sharedCreds.context.setSessionTimeout(self.sessionTimeout);
|
|
|
|
}
|
|
|
|
|
2013-07-21 03:11:02 +00:00
|
|
|
if (self.ticketKeys) {
|
|
|
|
sharedCreds.context.setTicketKeys(self.ticketKeys);
|
|
|
|
}
|
|
|
|
|
2013-06-13 13:36:00 +00:00
|
|
|
// constructor call
|
|
|
|
net.Server.call(this, function(raw_socket) {
|
|
|
|
var socket = new TLSSocket(raw_socket, {
|
2014-03-06 23:27:01 +00:00
|
|
|
secureContext: sharedCreds,
|
2013-06-13 13:36:00 +00:00
|
|
|
isServer: true,
|
|
|
|
server: self,
|
|
|
|
requestCert: self.requestCert,
|
|
|
|
rejectUnauthorized: self.rejectUnauthorized,
|
2013-08-23 13:53:16 +00:00
|
|
|
handshakeTimeout: timeout,
|
2013-06-13 13:36:00 +00:00
|
|
|
NPNProtocols: self.NPNProtocols,
|
2013-08-06 16:30:21 +00:00
|
|
|
SNICallback: options.SNICallback || SNICallback
|
2013-06-13 13:36:00 +00:00
|
|
|
});
|
|
|
|
|
2013-08-23 13:53:16 +00:00
|
|
|
socket.on('secure', function() {
|
|
|
|
if (socket._requestCert) {
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
var verifyError = socket._handle.verifyError();
|
2013-06-13 13:36:00 +00:00
|
|
|
if (verifyError) {
|
2014-01-17 17:15:36 +00:00
|
|
|
socket.authorizationError = verifyError.code;
|
2013-06-13 13:36:00 +00:00
|
|
|
|
2013-08-23 13:53:16 +00:00
|
|
|
if (socket._rejectUnauthorized)
|
2013-06-13 13:36:00 +00:00
|
|
|
socket.destroy();
|
|
|
|
} else {
|
|
|
|
socket.authorized = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-23 13:53:16 +00:00
|
|
|
if (!socket.destroyed && socket._releaseControl())
|
2013-06-13 13:36:00 +00:00
|
|
|
self.emit('secureConnection', socket);
|
|
|
|
});
|
|
|
|
|
2014-01-22 01:07:11 +00:00
|
|
|
var errorEmitted = false;
|
|
|
|
socket.on('close', function() {
|
|
|
|
// Emit ECONNRESET
|
|
|
|
if (!socket._controlReleased && !errorEmitted) {
|
|
|
|
errorEmitted = true;
|
|
|
|
var connReset = new Error('socket hang up');
|
|
|
|
connReset.code = 'ECONNRESET';
|
|
|
|
self.emit('clientError', connReset, socket);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2013-06-13 13:36:00 +00:00
|
|
|
socket.on('_tlsError', function(err) {
|
2014-01-22 01:07:11 +00:00
|
|
|
if (!socket._controlReleased && !errorEmitted) {
|
|
|
|
errorEmitted = true;
|
2013-06-13 13:36:00 +00:00
|
|
|
self.emit('clientError', err, socket);
|
2014-01-22 01:07:11 +00:00
|
|
|
}
|
2013-06-13 13:36:00 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
if (listener) {
|
|
|
|
this.on('secureConnection', listener);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
util.inherits(Server, net.Server);
|
|
|
|
exports.Server = Server;
|
|
|
|
exports.createServer = function(options, listener) {
|
|
|
|
return new Server(options, listener);
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-07-21 03:11:02 +00:00
|
|
|
Server.prototype._getServerData = function() {
|
|
|
|
return {
|
|
|
|
ticketKeys: this._sharedCreds.context.getTicketKeys().toString('hex')
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
Server.prototype._setServerData = function(data) {
|
|
|
|
this._sharedCreds.context.setTicketKeys(new Buffer(data.ticketKeys, 'hex'));
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2013-06-13 13:36:00 +00:00
|
|
|
Server.prototype.setOptions = function(options) {
|
2015-01-29 01:05:53 +00:00
|
|
|
if (typeof options.requestCert === 'boolean') {
|
2013-06-13 13:36:00 +00:00
|
|
|
this.requestCert = options.requestCert;
|
|
|
|
} else {
|
|
|
|
this.requestCert = false;
|
|
|
|
}
|
|
|
|
|
2015-01-29 01:05:53 +00:00
|
|
|
if (typeof options.rejectUnauthorized === 'boolean') {
|
2013-06-13 13:36:00 +00:00
|
|
|
this.rejectUnauthorized = options.rejectUnauthorized;
|
|
|
|
} else {
|
|
|
|
this.rejectUnauthorized = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (options.pfx) this.pfx = options.pfx;
|
|
|
|
if (options.key) this.key = options.key;
|
|
|
|
if (options.passphrase) this.passphrase = options.passphrase;
|
|
|
|
if (options.cert) this.cert = options.cert;
|
|
|
|
if (options.ca) this.ca = options.ca;
|
|
|
|
if (options.secureProtocol) this.secureProtocol = options.secureProtocol;
|
|
|
|
if (options.crl) this.crl = options.crl;
|
|
|
|
if (options.ciphers) this.ciphers = options.ciphers;
|
2015-01-29 01:05:53 +00:00
|
|
|
if (options.ecdhCurve !== undefined)
|
2013-10-14 14:53:59 +00:00
|
|
|
this.ecdhCurve = options.ecdhCurve;
|
2014-08-27 09:00:13 +00:00
|
|
|
if (options.dhparam) this.dhparam = options.dhparam;
|
2013-06-13 13:36:00 +00:00
|
|
|
if (options.sessionTimeout) this.sessionTimeout = options.sessionTimeout;
|
2014-02-03 21:32:13 +00:00
|
|
|
if (options.ticketKeys) this.ticketKeys = options.ticketKeys;
|
2013-06-13 13:36:00 +00:00
|
|
|
var secureOptions = options.secureOptions || 0;
|
2015-02-15 17:43:36 +00:00
|
|
|
if (options.honorCipherOrder !== undefined)
|
|
|
|
this.honorCipherOrder = !!options.honorCipherOrder;
|
2014-06-25 10:47:59 +00:00
|
|
|
else
|
2015-02-15 17:43:36 +00:00
|
|
|
this.honorCipherOrder = true;
|
2013-06-13 13:36:00 +00:00
|
|
|
if (secureOptions) this.secureOptions = secureOptions;
|
|
|
|
if (options.NPNProtocols) tls.convertNPNProtocols(options.NPNProtocols, this);
|
|
|
|
if (options.sessionIdContext) {
|
|
|
|
this.sessionIdContext = options.sessionIdContext;
|
2013-08-23 13:53:16 +00:00
|
|
|
} else {
|
2013-06-13 13:36:00 +00:00
|
|
|
this.sessionIdContext = crypto.createHash('md5')
|
|
|
|
.update(process.argv.join(' '))
|
|
|
|
.digest('hex');
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// SNI Contexts High-Level API
|
2014-03-06 23:27:01 +00:00
|
|
|
Server.prototype.addContext = function(servername, context) {
|
2013-06-13 13:36:00 +00:00
|
|
|
if (!servername) {
|
2014-08-01 06:08:52 +00:00
|
|
|
throw new Error('Servername is required parameter for Server.addContext');
|
2013-06-13 13:36:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var re = new RegExp('^' +
|
|
|
|
servername.replace(/([\.^$+?\-\\[\]{}])/g, '\\$1')
|
2013-12-05 15:16:01 +00:00
|
|
|
.replace(/\*/g, '[^\.]*') +
|
2013-06-13 13:36:00 +00:00
|
|
|
'$');
|
2014-03-06 23:27:01 +00:00
|
|
|
this._contexts.push([re, tls.createSecureContext(context).context]);
|
2013-06-13 13:36:00 +00:00
|
|
|
};
|
|
|
|
|
2013-08-03 17:29:54 +00:00
|
|
|
function SNICallback(servername, callback) {
|
2013-06-13 13:36:00 +00:00
|
|
|
var ctx;
|
|
|
|
|
2013-08-06 16:30:21 +00:00
|
|
|
this.server._contexts.some(function(elem) {
|
2015-01-29 01:05:53 +00:00
|
|
|
if (servername.match(elem[0]) !== null) {
|
2013-06-13 13:36:00 +00:00
|
|
|
ctx = elem[1];
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2013-08-03 17:29:54 +00:00
|
|
|
callback(null, ctx);
|
2013-08-02 16:11:17 +00:00
|
|
|
}
|
|
|
|
|
2013-06-13 13:36:00 +00:00
|
|
|
|
|
|
|
// Target API:
|
|
|
|
//
|
|
|
|
// var s = tls.connect({port: 8000, host: "google.com"}, function() {
|
|
|
|
// if (!s.authorized) {
|
|
|
|
// s.destroy();
|
|
|
|
// return;
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// // s.socket;
|
|
|
|
//
|
|
|
|
// s.end("hello world\n");
|
|
|
|
// });
|
|
|
|
//
|
|
|
|
//
|
|
|
|
function normalizeConnectArgs(listArgs) {
|
|
|
|
var args = net._normalizeConnectArgs(listArgs);
|
|
|
|
var options = args[0];
|
|
|
|
var cb = args[1];
|
|
|
|
|
2015-01-29 01:05:53 +00:00
|
|
|
if (listArgs[1] !== null && typeof listArgs[1] === 'object') {
|
2013-06-13 13:36:00 +00:00
|
|
|
options = util._extend(options, listArgs[1]);
|
2015-01-29 01:05:53 +00:00
|
|
|
} else if (listArgs[2] !== null && typeof listArgs[2] === 'object') {
|
2013-06-13 13:36:00 +00:00
|
|
|
options = util._extend(options, listArgs[2]);
|
|
|
|
}
|
|
|
|
|
|
|
|
return (cb) ? [options, cb] : [options];
|
|
|
|
}
|
|
|
|
|
|
|
|
exports.connect = function(/* [port, host], options, cb */) {
|
|
|
|
var args = normalizeConnectArgs(arguments);
|
|
|
|
var options = args[0];
|
|
|
|
var cb = args[1];
|
|
|
|
|
|
|
|
var defaults = {
|
2014-01-24 01:28:08 +00:00
|
|
|
rejectUnauthorized: '0' !== process.env.NODE_TLS_REJECT_UNAUTHORIZED,
|
2014-09-05 14:56:55 +00:00
|
|
|
ciphers: tls.DEFAULT_CIPHERS,
|
|
|
|
checkServerIdentity: tls.checkServerIdentity
|
2013-06-13 13:36:00 +00:00
|
|
|
};
|
2014-09-05 14:56:55 +00:00
|
|
|
|
2013-06-13 13:36:00 +00:00
|
|
|
options = util._extend(defaults, options || {});
|
|
|
|
|
2014-09-05 14:56:55 +00:00
|
|
|
assert(typeof options.checkServerIdentity === 'function');
|
|
|
|
|
2013-10-28 10:25:27 +00:00
|
|
|
var hostname = options.servername ||
|
|
|
|
options.host ||
|
2013-10-28 12:10:10 +00:00
|
|
|
options.socket && options.socket._host,
|
2013-09-24 12:53:49 +00:00
|
|
|
NPN = {},
|
2014-03-06 23:27:01 +00:00
|
|
|
context = tls.createSecureContext(options);
|
2013-06-13 13:36:00 +00:00
|
|
|
tls.convertNPNProtocols(options.NPNProtocols, NPN);
|
|
|
|
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
var socket = new TLSSocket(options.socket, {
|
|
|
|
pipe: options.path && !options.port,
|
|
|
|
secureContext: context,
|
|
|
|
isServer: false,
|
|
|
|
requestCert: true,
|
|
|
|
rejectUnauthorized: options.rejectUnauthorized,
|
|
|
|
session: options.session,
|
|
|
|
NPNProtocols: NPN.NPNProtocols,
|
|
|
|
requestOCSP: options.requestOCSP
|
|
|
|
});
|
2013-09-24 12:53:49 +00:00
|
|
|
|
|
|
|
if (cb)
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
socket.once('secureConnect', cb);
|
2013-09-24 12:53:49 +00:00
|
|
|
|
|
|
|
if (!options.socket) {
|
|
|
|
var connect_opt;
|
|
|
|
if (options.path && !options.port) {
|
|
|
|
connect_opt = { path: options.path };
|
|
|
|
} else {
|
|
|
|
connect_opt = {
|
|
|
|
port: options.port,
|
|
|
|
host: options.host,
|
|
|
|
localAddress: options.localAddress
|
|
|
|
};
|
2013-09-24 21:35:30 +00:00
|
|
|
}
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
socket.connect(connect_opt, function() {
|
|
|
|
socket._start();
|
|
|
|
});
|
2013-09-24 12:53:49 +00:00
|
|
|
}
|
|
|
|
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
socket._releaseControl();
|
2013-06-13 13:36:00 +00:00
|
|
|
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
if (options.session)
|
|
|
|
socket.setSession(options.session);
|
2013-06-13 13:36:00 +00:00
|
|
|
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
if (options.servername)
|
|
|
|
socket.setServername(options.servername);
|
2013-06-13 13:36:00 +00:00
|
|
|
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
if (options.socket)
|
|
|
|
socket._start();
|
2013-06-13 13:36:00 +00:00
|
|
|
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
socket.on('secure', function() {
|
|
|
|
var verifyError = socket._handle.verifyError();
|
2013-06-13 13:36:00 +00:00
|
|
|
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
// Verify that server's identity matches it's certificate's names
|
|
|
|
if (!verifyError) {
|
|
|
|
var cert = socket.getPeerCertificate();
|
|
|
|
verifyError = options.checkServerIdentity(hostname, cert);
|
|
|
|
}
|
2013-06-13 13:36:00 +00:00
|
|
|
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
if (verifyError) {
|
|
|
|
socket.authorized = false;
|
|
|
|
socket.authorizationError = verifyError.code || verifyError.message;
|
2013-06-13 13:36:00 +00:00
|
|
|
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
if (options.rejectUnauthorized) {
|
|
|
|
socket.emit('error', verifyError);
|
|
|
|
socket.destroy();
|
|
|
|
return;
|
2013-06-13 13:36:00 +00:00
|
|
|
} else {
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
socket.emit('secureConnect');
|
2013-06-13 13:36:00 +00:00
|
|
|
}
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
} else {
|
|
|
|
socket.authorized = true;
|
|
|
|
socket.emit('secureConnect');
|
|
|
|
}
|
2013-06-13 13:36:00 +00:00
|
|
|
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
// Uncork incoming data
|
|
|
|
socket.removeListener('end', onHangUp);
|
|
|
|
});
|
2013-06-13 13:36:00 +00:00
|
|
|
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
function onHangUp() {
|
|
|
|
// NOTE: This logic is shared with _http_client.js
|
|
|
|
if (!socket._hadError) {
|
|
|
|
socket._hadError = true;
|
|
|
|
var error = new Error('socket hang up');
|
|
|
|
error.code = 'ECONNRESET';
|
|
|
|
socket.destroy();
|
|
|
|
socket.emit('error', error);
|
2013-06-13 13:36:00 +00:00
|
|
|
}
|
|
|
|
}
|
stream_base: introduce StreamBase
StreamBase is an improved way to write C++ streams. The class itself is
for separting `StreamWrap` (with the methods like `.writeAsciiString`,
`.writeBuffer`, `.writev`, etc) from the `HandleWrap` class, making
possible to write abstract C++ streams that are not bound to any uv
socket.
The following methods are important part of the abstraction (which
mimics libuv's stream API):
* Events:
* `OnAlloc(size_t size, uv_buf_t*)`
* `OnRead(ssize_t nread, const uv_buf_t*, uv_handle_type pending)`
* `OnAfterWrite(WriteWrap*)`
* Wrappers:
* `DoShutdown(ShutdownWrap*)`
* `DoTryWrite(uv_buf_t** bufs, size_t* count)`
* `DoWrite(WriteWrap*, uv_buf_t*, size_t count, uv_stream_t* handle)`
* `Error()`
* `ClearError()`
The implementation should provide all of these methods, thus providing
the access to the underlying resource (be it uv handle, TLS socket, or
anything else).
A C++ stream may consume the input of another stream by replacing the
event callbacks and proxying the writes. This kind of API is actually
used now for the TLSWrap implementation, making it possible to wrap TLS
stream into another TLS stream. Thus legacy API calls are no longer
required in `_tls_wrap.js`.
PR-URL: https://github.com/iojs/io.js/pull/840
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
2015-02-22 18:59:07 +00:00
|
|
|
socket.once('end', onHangUp);
|
|
|
|
|
|
|
|
return socket;
|
2013-06-13 13:36:00 +00:00
|
|
|
};
|