From f67aa566a6eb43c5ea508ad8cf65c2e6fb9ad9da Mon Sep 17 00:00:00 2001 From: Bidisha Pyne Date: Thu, 29 Jun 2017 11:52:06 +0200 Subject: [PATCH] errors: migrate tls_wrap to use internal/errors PR-URL: https://github.com/nodejs/node/pull/13476 Reviewed-By: James M Snell Reviewed-By: Refael Ackermann Reviewed-By: Michael Dawson --- lib/_tls_wrap.js | 32 ++++++++++----------- lib/internal/errors.js | 10 ++++++- test/parallel/test-tls-basic-validations.js | 7 ++++- test/parallel/test-tls-client-mindhsize.js | 3 +- test/parallel/test-tls-no-cert-required.js | 7 ++++- 5 files changed, 38 insertions(+), 21 deletions(-) diff --git a/lib/_tls_wrap.js b/lib/_tls_wrap.js index 8215d92c8b..9536f81b6f 100644 --- a/lib/_tls_wrap.js +++ b/lib/_tls_wrap.js @@ -36,6 +36,7 @@ const Timer = process.binding('timer_wrap').Timer; const tls_wrap = process.binding('tls_wrap'); const TCP = process.binding('tcp_wrap').TCP; const Pipe = process.binding('pipe_wrap').Pipe; +const errors = require('internal/errors'); function onhandshakestart() { debug('onhandshakestart'); @@ -59,7 +60,7 @@ function onhandshakestart() { // 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'); + var err = new errors.Error('ERR_TLS_SESSION_ATTACK'); self._emitTLSError(err); }); } @@ -77,14 +78,14 @@ 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')); + return cb(new errors.Error('ERR_MULTIPLE_CALLBACK')); once = true; if (err) return cb(err); if (!self._handle) - return cb(new Error('Socket is closed')); + return cb(new errors.Error('ERR_SOCKET_CLOSED')); self._handle.loadSession(session); cb(null); @@ -106,14 +107,14 @@ function loadSNI(self, servername, cb) { var once = false; self._SNICallback(servername, function(err, context) { if (once) - return cb(new Error('TLS SNI callback was called 2 times')); + return cb(new errors.Error('ERR_MULTIPLE_CALLBACK')); once = true; if (err) return cb(err); if (!self._handle) - return cb(new Error('Socket is closed')); + return cb(new errors.Error('ERR_SOCKET_CLOSED')); // TODO(indutny): eventually disallow raw `SecureContext` if (context) @@ -152,14 +153,14 @@ function requestOCSP(self, hello, ctx, cb) { var once = false; function onOCSP(err, response) { if (once) - return cb(new Error('TLS OCSP callback was called 2 times')); + return cb(new errors.Error('ERR_MULTIPLE_CALLBACK')); once = true; if (err) return cb(err); if (!self._handle) - return cb(new Error('Socket is closed')); + return cb(new errors.Error('ERR_SOCKET_CLOSED')); if (response) self._handle.setOCSPResponse(response); @@ -192,7 +193,7 @@ function oncertcb(info) { return self.destroy(err); if (!self._handle) - return self.destroy(new Error('Socket is closed')); + return self.destroy(new errors.Error('ERR_SOCKET_CLOSED')); try { self._handle.certCbDone(); @@ -221,7 +222,7 @@ function onnewsession(key, session) { once = true; if (!self._handle) - return self.destroy(new Error('Socket is closed')); + return self.destroy(new errors.Error('ERR_SOCKET_CLOSED')); self._handle.newSessionDone(); @@ -552,7 +553,7 @@ TLSSocket.prototype.renegotiate = function(options, callback) { } if (!this._handle.renegotiate()) { if (callback) { - process.nextTick(callback, new Error('Failed to renegotiate')); + process.nextTick(callback, new errors.Error('ERR_TLS_RENEGOTIATE')); } return false; } @@ -578,7 +579,7 @@ TLSSocket.prototype.getTLSTicket = function getTLSTicket() { }; TLSSocket.prototype._handleTimeout = function() { - this._emitTLSError(new Error('TLS handshake timeout')); + this._emitTLSError(new errors.Error('ERR_TLS_HANDSHAKE_TIMEOUT')); }; TLSSocket.prototype._emitTLSError = function(err) { @@ -780,7 +781,7 @@ function Server(options, listener) { } else if (options == null || typeof options === 'object') { options = options || {}; } else { - throw new TypeError('options must be an object'); + throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'options', 'object'); } @@ -811,7 +812,7 @@ function Server(options, listener) { var timeout = options.handshakeTimeout || (120 * 1000); if (typeof timeout !== 'number') { - throw new TypeError('handshakeTimeout must be a number'); + throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'timeout', 'number'); } if (self.sessionTimeout) { @@ -949,7 +950,7 @@ Server.prototype.setOptions = function(options) { // SNI Contexts High-Level API Server.prototype.addContext = function(servername, context) { if (!servername) { - throw new Error('"servername" is required parameter for Server.addContext'); + throw new errors.Error('ERR_TLS_REQUIRED_SERVER_NAME'); } var re = new RegExp('^' + @@ -1088,8 +1089,7 @@ exports.connect = function(...args /* [port,] [host,] [options,] [cb] */) { // specified in options. var ekeyinfo = socket.getEphemeralKeyInfo(); if (ekeyinfo.type === 'DH' && ekeyinfo.size < options.minDHSize) { - var err = new Error('DH parameter size ' + ekeyinfo.size + - ' is less than ' + options.minDHSize); + var err = new errors.Error('ERR_TLS_DH_PARAM_SIZE', ekeyinfo.size); socket.emit('error', err); socket.destroy(); return; diff --git a/lib/internal/errors.js b/lib/internal/errors.js index 31c8fa945a..9fb0ac07dc 100644 --- a/lib/internal/errors.js +++ b/lib/internal/errors.js @@ -156,16 +156,24 @@ E('ERR_NO_CRYPTO', 'Node.js is not compiled with OpenSSL crypto support'); E('ERR_NO_LONGER_SUPPORTED', '%s is no longer supported'); E('ERR_PARSE_HISTORY_DATA', 'Could not parse history data in %s'); E('ERR_SOCKET_ALREADY_BOUND', 'Socket is already bound'); +E('ERR_SOCKET_BAD_PORT', 'Port should be > 0 and < 65536'); E('ERR_SOCKET_BAD_TYPE', 'Bad socket type specified. Valid types are: udp4, udp6'); E('ERR_SOCKET_CANNOT_SEND', 'Unable to send data'); -E('ERR_SOCKET_BAD_PORT', 'Port should be > 0 and < 65536'); +E('ERR_SOCKET_CLOSED', 'Socket is closed'); E('ERR_SOCKET_DGRAM_NOT_RUNNING', 'Not running'); E('ERR_STDERR_CLOSE', 'process.stderr cannot be closed'); E('ERR_STDOUT_CLOSE', 'process.stdout cannot be closed'); E('ERR_STREAM_WRAP', 'Stream has StringDecoder set or is in objectMode'); E('ERR_TLS_CERT_ALTNAME_INVALID', 'Hostname/IP does not match certificate\'s altnames: %s'); +E('ERR_TLS_DH_PARAM_SIZE', (size) => + `DH parameter size ${size} is less than 2048`); +E('ERR_TLS_HANDSHAKE_TIMEOUT', 'TLS handshake timeout'); +E('ERR_TLS_RENEGOTIATION_FAILED', 'Failed to renegotiate'); +E('ERR_TLS_REQUIRED_SERVER_NAME', + '"servername" is required parameter for Server.addContext'); +E('ERR_TLS_SESSION_ATTACK', 'TSL session renegotiation attack detected'); E('ERR_TRANSFORM_ALREADY_TRANSFORMING', 'Calling transform done when still transforming'); E('ERR_TRANSFORM_WITH_LENGTH_0', diff --git a/test/parallel/test-tls-basic-validations.js b/test/parallel/test-tls-basic-validations.js index 1d494b4ed3..5866eceec4 100644 --- a/test/parallel/test-tls-basic-validations.js +++ b/test/parallel/test-tls-basic-validations.js @@ -23,7 +23,12 @@ assert.throws(() => tls.createServer({ecdhCurve: 1}), /TypeError: ECDH curve name must be a string/); assert.throws(() => tls.createServer({handshakeTimeout: 'abcd'}), - /TypeError: handshakeTimeout must be a number/); + common.expectsError({ + code: 'ERR_INVALID_ARG_TYPE', + type: TypeError, + message: 'The "timeout" argument must be of type number' + }) + ); assert.throws(() => tls.createServer({sessionTimeout: 'abcd'}), /TypeError: Session timeout must be a 32-bit integer/); diff --git a/test/parallel/test-tls-client-mindhsize.js b/test/parallel/test-tls-client-mindhsize.js index 230c6e0845..330f1f468b 100644 --- a/test/parallel/test-tls-client-mindhsize.js +++ b/test/parallel/test-tls-client-mindhsize.js @@ -51,8 +51,7 @@ function test(size, err, next) { if (err) { client.on('error', function(e) { nerror++; - assert.strictEqual(e.message, - 'DH parameter size 1024 is less than 2048'); + assert.strictEqual(e.code, 'ERR_TLS_DH_PARAM_SIZE'); server.close(); }); } diff --git a/test/parallel/test-tls-no-cert-required.js b/test/parallel/test-tls-no-cert-required.js index 11c86efa08..b850a56eb3 100644 --- a/test/parallel/test-tls-no-cert-required.js +++ b/test/parallel/test-tls-no-cert-required.js @@ -40,7 +40,12 @@ tls.createServer({}) .listen(0, common.mustCall(close)); assert.throws(() => tls.createServer('this is not valid'), - /^TypeError: options must be an object$/); + common.expectsError({ + code: 'ERR_INVALID_ARG_TYPE', + type: TypeError, + message: 'The "options" argument must be of type object' + }) +); tls.createServer() .listen(0, common.mustCall(close));