diff --git a/lib/tls.js b/lib/tls.js index e396b592e80..55ff8cc44d8 100644 --- a/lib/tls.js +++ b/lib/tls.js @@ -1119,7 +1119,8 @@ exports.connect = function(/* [port, host], options, cb */) { var sslcontext = crypto.createCredentials(options); convertNPNProtocols(options.NPNProtocols, this); - var pair = new SecurePair(sslcontext, false, true, + + var pair = new SecurePair(sslcontext, options.asServer?true:false, true, options.rejectUnauthorized === true ? true : false, { NPNProtocols: this.NPNProtocols, @@ -1171,6 +1172,53 @@ exports.connect = function(/* [port, host], options, cb */) { return cleartext; }; +// starts TLS on a given socket, be it client or server +// for a server-side socket, asServer has to be passed as a boolean +// var assert = require('assert'); +// var net = require('net'); +// var tls = require('tls'); +// var client = net.connect(443, 'google.com', function() { +// var encryptedStream = tls.start(client, function() { +// // secure connection in here! +// client.end(); +// }); +//}); +exports.start = function(socket /* [options], [asServer], cb */) { + var cb, options = {}, asServer; + + if(!socket) { + throw new Error("First parameter as socket is required"); + } + + + // callback is always last argument + if (typeof arguments[arguments.length - 1] === 'function') { + cb = arguments[arguments.length - 1]; + } + // options passed as second argument + if (typeof arguments[1] === 'object') { + options = arguments[1]; + if (typeof arguments[2] == 'boolean') { + asServer = arguments[2]; + } + } + // no options passed + else if(typeof arguments[1] == 'boolean') { + asServer = arguments[1]; + } + + // revert encoding as TLS requires a binary stream + socket.setEncoding(undefined); + + options = util._extend({ + socket: socket, + // allow asServer to be passed either through argument + // or through options + asServer: asServer || options.asServer + }, options || {}); + return exports.connect(options, cb); +}; + function pipe(pair, socket) { pair.encrypted.pipe(socket); diff --git a/test/simple/test-tls-start-client-server.js b/test/simple/test-tls-start-client-server.js new file mode 100644 index 00000000000..dd6b6aa0cd6 --- /dev/null +++ b/test/simple/test-tls-start-client-server.js @@ -0,0 +1,46 @@ +var assert = require('assert'); +var net = require('net'); +var common = require('../common'); +var fs = require('fs'); +var tls = require('tls'); + +function filenamePEM(n) { + return require('path').join(common.fixturesDir, 'keys', n + '.pem'); +} + +function loadPEM(n) { + return fs.readFileSync(filenamePEM(n)); +} + +var serverOptions = { + key: loadPEM('agent2-key'), + cert: loadPEM('agent2-cert') +}; + + +var serverSecurelyConnected = false; +var clientSecurelyConnected = false; + +net.createServer(function(socket) { + var encryptedStream = tls.start(socket, serverOptions, true, function() { + serverSecurelyConnected = true; + }); +}).listen(9999); + + + +var client = net.connect(9999, function() { + var encryptedStream = tls.start(client, function() { + clientSecurelyConnected = true; + if(serverSecurelyConnected) { + process.exit(0); + } + assert.fail("Client connected securely to the server but server does " + + "not know this", "Both client and server should be " + + "connected", "tls.start failed"); + }); +}); + +setTimeout(function() { + assert.fail("tls.start failed, client has not been able to upgrade connection"); +}, 100); \ No newline at end of file diff --git a/test/simple/test-tls-start-client.js b/test/simple/test-tls-start-client.js new file mode 100644 index 00000000000..bb82e63056f --- /dev/null +++ b/test/simple/test-tls-start-client.js @@ -0,0 +1,11 @@ +var assert = require('assert'); +var net = require('net'); +var tls = require('tls'); + +var client = net.connect(443, 'google.com', function() { + var encryptedStream = tls.start(client, function() { + assert.ok(encryptedStream.authorized, "When connected, connection should yield authorized"); + client.end(); + }); + +}); \ No newline at end of file