From 0ec57ea34c5e97b611ad668f1d4ce2662e4808a9 Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Wed, 8 Dec 2010 11:22:08 -0800 Subject: [PATCH] Some TLS clean ups --- lib/tls.js | 96 +++++++++++++++++++---------------- test/simple/test-tls-server-verify.js | 9 ++-- 2 files changed, 59 insertions(+), 46 deletions(-) diff --git a/lib/tls.js b/lib/tls.js index c8e7fcb..c7d2a99 100644 --- a/lib/tls.js +++ b/lib/tls.js @@ -24,7 +24,10 @@ var SecureStream = null; function SecurePair(credentials, isServer, requestCert, rejectUnauthorized) { if (!(this instanceof SecurePair)) { - return new SecurePair(credentials, isServer, requestCert, rejectUnauthorized); + return new SecurePair(credentials, + isServer, + requestCert, + rejectUnauthorized); } var self = this; @@ -183,6 +186,39 @@ exports.createSecurePair = function(credentials, }; +SecurePair.prototype._mover = function(reader, writer, checker) { + var bytesRead; + var pool; + var chunkBytes; + var chunk; + + do { + bytesRead = 0; + chunkBytes = 0; + pool = new Buffer(4096); // alloc every time? + pool.used = 0; + + do { + try { + chunkBytes = reader(pool, + pool.used + bytesRead, + pool.length - pool.used - bytesRead); + } catch (e) { + return this._error(e); + } + if (chunkBytes >= 0) { + bytesRead += chunkBytes; + } + } while ((chunkBytes > 0) && (pool.used + bytesRead < pool.length)); + + if (bytesRead > 0) { + chunk = pool.slice(0, bytesRead); + writer(chunk); + } + } while (bytesRead > 0 && checker()); +}; + + /** * Attempt to cycle OpenSSLs buffers in various directions. * @@ -221,7 +257,6 @@ SecurePair.prototype._cycle = function() { var tmp; var bytesRead; var bytesWritten; - var chunkBytes; var chunk = null; var pool = null; @@ -272,40 +307,10 @@ SecurePair.prototype._cycle = function() { assert(rv === tmp.length); } - function mover(reader, writer, checker) { - var bytesRead; - var pool; - var chunkBytes; - do { - bytesRead = 0; - chunkBytes = 0; - pool = new Buffer(4096); - pool.used = 0; - - do { - try { - chunkBytes = reader(pool, - pool.used + bytesRead, - pool.length - pool.used - bytesRead); - } catch (e) { - return self._error(e); - } - if (chunkBytes >= 0) { - bytesRead += chunkBytes; - } - } while ((chunkBytes > 0) && (pool.used + bytesRead < pool.length)); - - if (bytesRead > 0) { - chunk = pool.slice(0, bytesRead); - writer(chunk); - } - } while (checker(bytesRead)); - } - - // Move decryptoed, clear data out into the application. + // Move decrypted, clear data out into the application. // From the user's perspective this occurs as a 'data' event // on the pair.cleartext. - mover( + this._mover( function(pool, offset, length) { debug('reading from clearOut'); return self._ssl.clearOut(pool, offset, length); @@ -313,8 +318,8 @@ SecurePair.prototype._cycle = function() { function(chunk) { self.cleartext.emit('data', chunk); }, - function(bytesRead) { - return bytesRead > 0 && self._cleartextWriteState === true; + function() { + return self._cleartextWriteState === true; }); // Move encrypted data to the stream. From the user's perspective this @@ -325,7 +330,7 @@ SecurePair.prototype._cycle = function() { // socket.write(d); // }); // - mover( + this._mover( function(pool, offset, length) { debug('reading from encOut'); if (!self._ssl) return -1; @@ -334,13 +339,12 @@ SecurePair.prototype._cycle = function() { function(chunk) { self.encrypted.emit('data', chunk); }, - function(bytesRead) { + function() { if (!self._ssl) return false; - return bytesRead > 0 && self._encryptedWriteState === true; + return self._encryptedWriteState === true; }); - if (this._ssl && !this._secureEstablished && this._ssl.isInitFinished()) { this._secureEstablished = true; debug('secure established'); @@ -359,6 +363,7 @@ SecurePair.prototype._destroy = function(err) { this.cleartext.emit('close'); this.emit('end', err); } + this._cycle(); }; @@ -498,7 +503,12 @@ function Server(/* [options], listener */) { } else { var verifyError = pair._ssl.verifyError(); if (verifyError) { - self.emit('unauthorized', pair.cleartext, verifyError); + if (self.rejectUnauthorized) { + socket.destroy(); + pair._destroy(); + } else { + self.emit('unauthorized', pair.cleartext, verifyError); + } } else { self.emit('authorized', pair.cleartext); } @@ -506,12 +516,12 @@ function Server(/* [options], listener */) { }); pair.on('error', function(e) { - console.log('pair got error: ' + e); + console.error('pair got error: ' + e); self.emit('error', e); }); pair.cleartext.on('error', function(err) { - console.log('cleartext got error: ' + err); + console.error('cleartext got error: ' + err); }); pair.encrypted.on('error', function(err) { diff --git a/test/simple/test-tls-server-verify.js b/test/simple/test-tls-server-verify.js index 3a927d3..2c10b5b 100644 --- a/test/simple/test-tls-server-verify.js +++ b/test/simple/test-tls-server-verify.js @@ -112,7 +112,7 @@ function runClient (options, cb) { // To test use: openssl s_client -connect localhost:8000 var client = spawn('openssl', args); - //console.error(args); + console.error(args); var out = ''; @@ -141,10 +141,13 @@ function runClient (options, cb) { //client.stdout.pipe(process.stdout); client.on('exit', function(code) { + assert.equal(0, code); if (options.shouldReject) { - assert.equal(true, rejected); + assert.equal(true, rejected, options.name + + " NOT rejected, but should have been"); } else { - assert.equal(false, rejected); + assert.equal(false, rejected, options.name + + " rejected, but should NOT have been"); assert.equal(options.shouldAuth, authed); } -- 2.7.4