|
|
@ -194,6 +194,8 @@ TLSSocket.prototype._init = function() { |
|
|
|
var requestCert = !!options.requestCert || !options.isServer, |
|
|
|
rejectUnauthorized = !!options.rejectUnauthorized; |
|
|
|
|
|
|
|
this._requestCert = requestCert; |
|
|
|
this._rejectUnauthorized = rejectUnauthorized; |
|
|
|
if (requestCert || rejectUnauthorized) |
|
|
|
this.ssl.setVerifyMode(requestCert, rejectUnauthorized); |
|
|
|
|
|
|
@ -246,6 +248,49 @@ TLSSocket.prototype._init = function() { |
|
|
|
|
|
|
|
if (process.features.tls_npn && options.NPNProtocols) |
|
|
|
this.ssl.setNPNProtocols(options.NPNProtocols); |
|
|
|
|
|
|
|
if (options.handshakeTimeout > 0) |
|
|
|
this.setTimeout(options.handshakeTimeout, this._handleTimeout); |
|
|
|
}; |
|
|
|
|
|
|
|
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) { |
|
|
|
this.ssl.setVerifyMode(requestCert, rejectUnauthorized); |
|
|
|
this._requestCert = requestCert; |
|
|
|
this._rejectUnauthorized = rejectUnauthorized; |
|
|
|
} |
|
|
|
if (!this.ssl.renegotiate()) { |
|
|
|
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; |
|
|
|
}; |
|
|
|
|
|
|
|
TLSSocket.prototype._handleTimeout = function() { |
|
|
|
this._tlsError(new Error('TLS handshake timeout')); |
|
|
|
}; |
|
|
|
|
|
|
|
TLSSocket.prototype._tlsError = function(err) { |
|
|
@ -256,9 +301,10 @@ TLSSocket.prototype._tlsError = function(err) { |
|
|
|
|
|
|
|
TLSSocket.prototype._releaseControl = function() { |
|
|
|
if (this._controlReleased) |
|
|
|
return; |
|
|
|
return false; |
|
|
|
this._controlReleased = true; |
|
|
|
this.removeListener('error', this._tlsError); |
|
|
|
return true; |
|
|
|
}; |
|
|
|
|
|
|
|
TLSSocket.prototype._finishInit = function() { |
|
|
@ -272,6 +318,8 @@ TLSSocket.prototype._finishInit = function() { |
|
|
|
|
|
|
|
debug('secure established'); |
|
|
|
this._secureEstablished = true; |
|
|
|
if (this._tlsOptions.handshakeTimeout > 0) |
|
|
|
this.setTimeout(0, this._handleTimeout); |
|
|
|
this.emit('secure'); |
|
|
|
}; |
|
|
|
|
|
|
@ -453,37 +501,26 @@ function Server(/* [options], listener */) { |
|
|
|
server: self, |
|
|
|
requestCert: self.requestCert, |
|
|
|
rejectUnauthorized: self.rejectUnauthorized, |
|
|
|
handshakeTimeout: timeout, |
|
|
|
NPNProtocols: self.NPNProtocols, |
|
|
|
SNICallback: options.SNICallback || SNICallback |
|
|
|
}); |
|
|
|
|
|
|
|
function listener() { |
|
|
|
socket._tlsError(new Error('TLS handshake timeout')); |
|
|
|
} |
|
|
|
|
|
|
|
if (timeout > 0) { |
|
|
|
socket.setTimeout(timeout, listener); |
|
|
|
} |
|
|
|
|
|
|
|
socket.once('secure', function() { |
|
|
|
socket.setTimeout(0, listener); |
|
|
|
|
|
|
|
if (self.requestCert) { |
|
|
|
socket.on('secure', function() { |
|
|
|
if (socket._requestCert) { |
|
|
|
var verifyError = socket.ssl.verifyError(); |
|
|
|
if (verifyError) { |
|
|
|
socket.authorizationError = verifyError.message; |
|
|
|
|
|
|
|
if (self.rejectUnauthorized) |
|
|
|
if (socket._rejectUnauthorized) |
|
|
|
socket.destroy(); |
|
|
|
} else { |
|
|
|
socket.authorized = true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (!socket.destroyed) { |
|
|
|
socket._releaseControl(); |
|
|
|
if (!socket.destroyed && socket._releaseControl()) |
|
|
|
self.emit('secureConnection', socket); |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
socket.on('_tlsError', function(err) { |
|
|
@ -546,7 +583,7 @@ Server.prototype.setOptions = function(options) { |
|
|
|
if (options.NPNProtocols) tls.convertNPNProtocols(options.NPNProtocols, this); |
|
|
|
if (options.sessionIdContext) { |
|
|
|
this.sessionIdContext = options.sessionIdContext; |
|
|
|
} else if (this.requestCert) { |
|
|
|
} else { |
|
|
|
this.sessionIdContext = crypto.createHash('md5') |
|
|
|
.update(process.argv.join(' ')) |
|
|
|
.digest('hex'); |
|
|
|