crypto: move `createCredentials` to tls
authorFedor Indutny <fedor.indutny@gmail.com>
Thu, 6 Mar 2014 23:27:01 +0000 (03:27 +0400)
committerFedor Indutny <fedor@indutny.com>
Sat, 29 Mar 2014 08:01:43 +0000 (12:01 +0400)
Move `createCredentials` to `tls` module and rename it to
`createSecureContext`. Make it use default values from `tls` module:
`DEFAULT_CIPHERS` and `DEFAULT_ECDH_CURVE`.

fix #7249

17 files changed:
doc/api/tls.markdown
lib/_tls_common.js [new file with mode: 0644]
lib/_tls_legacy.js
lib/_tls_wrap.js
lib/crypto.js
lib/tls.js
node.gyp
src/node_crypto.cc
test/pummel/test-tls-securepair-client.js
test/simple/test-crypto-binary-default.js
test/simple/test-crypto.js
test/simple/test-tls-client-default-ciphers.js
test/simple/test-tls-delayed-attach.js
test/simple/test-tls-honorcipherorder.js
test/simple/test-tls-npn-server-client.js
test/simple/test-tls-securepair-server.js
test/simple/test-tls-sni-option.js

index 372bbd9..1c080ca 100644 (file)
@@ -197,7 +197,7 @@ automatically set as a listener for the [secureConnection][] event.  The
     supports SNI TLS extension. Two argument will be passed to it: `servername`,
     and `cb`. `SNICallback` should invoke `cb(null, ctx)`, where `ctx` is a
     SecureContext instance.
-    (You can use `crypto.createCredentials(...).context` to get proper
+    (You can use `tls.createSecureContext(...)` to get proper
     SecureContext). If `SNICallback` wasn't provided - default callback with
     high-level API will be used (see below).
 
@@ -391,8 +391,8 @@ Construct a new TLSSocket object from existing TCP socket.
 
 `options` is an object that might contain following properties:
 
-  - `credentials`: An optional credentials object from
-     `crypto.createCredentials( ... )`
+  - `secureContext`: An optional TLS context object from
+     `tls.createSecureContext( ... )`
 
   - `isServer`: If true - TLS socket will be instantiated in server-mode
 
@@ -408,7 +408,7 @@ Construct a new TLSSocket object from existing TCP socket.
 
   - `session`: Optional, a `Buffer` instance, containing TLS session
 
-## tls.createSecurePair([credentials], [isServer], [requestCert], [rejectUnauthorized])
+## tls.createSecurePair([context], [isServer], [requestCert], [rejectUnauthorized])
 
     Stability: 0 - Deprecated. Use tls.TLSSocket instead.
 
@@ -417,7 +417,7 @@ encrypted data, and one reads/writes cleartext data.
 Generally the encrypted one is piped to/from an incoming encrypted data stream,
 and the cleartext one is used as a replacement for the initial encrypted stream.
 
- - `credentials`: A credentials object from crypto.createCredentials( ... )
+ - `credentials`: A secure context object from tls.createSecureContext( ... )
 
  - `isServer`: A boolean indicating whether this tls connection should be
    opened as a server or a client.
@@ -532,10 +532,10 @@ Returns the bound address, the address family name and port of the
 server as reported by the operating system.  See [net.Server.address()][] for
 more information.
 
-### server.addContext(hostname, credentials)
+### server.addContext(hostname, context)
 
 Add secure context that will be used if client request's SNI hostname is
-matching passed `hostname` (wildcards can be used). `credentials` can contain
+matching passed `hostname` (wildcards can be used). `context` can contain
 `key`, `cert` and `ca`.
 
 ### server.maxConnections
diff --git a/lib/_tls_common.js b/lib/_tls_common.js
new file mode 100644 (file)
index 0000000..ce011bc
--- /dev/null
@@ -0,0 +1,128 @@
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+var util = require('util');
+var tls = require('tls');
+
+// Lazily loaded
+var crypto = null;
+
+var binding = process.binding('crypto');
+var NativeSecureContext = binding.SecureContext;
+
+function SecureContext(secureProtocol, flags, context) {
+  if (!(this instanceof SecureContext)) {
+    return new SecureContext(secureProtocol, flags, context);
+  }
+
+  if (context) {
+    this.context = context;
+  } else {
+    this.context = new NativeSecureContext();
+
+    if (secureProtocol) {
+      this.context.init(secureProtocol);
+    } else {
+      this.context.init();
+    }
+  }
+
+  if (flags) this.context.setOptions(flags);
+}
+
+exports.SecureContext = SecureContext;
+
+
+exports.createSecureContext = function createSecureContext(options, context) {
+  if (!options) options = {};
+
+  var c = new SecureContext(options.secureProtocol,
+                            options.secureOptions,
+                            context);
+
+  if (context) return c;
+
+  if (options.key) {
+    if (options.passphrase) {
+      c.context.setKey(options.key, options.passphrase);
+    } else {
+      c.context.setKey(options.key);
+    }
+  }
+
+  if (options.cert) c.context.setCert(options.cert);
+
+  if (options.ciphers)
+    c.context.setCiphers(options.ciphers);
+  else
+    c.context.setCiphers(tls.DEFAULT_CIPHERS);
+
+  if (util.isUndefined(options.ecdhCurve))
+    c.context.setECDHCurve(tls.DEFAULT_ECDH_CURVE);
+  else if (options.ecdhCurve)
+    c.context.setECDHCurve(options.ecdhCurve);
+
+  if (options.ca) {
+    if (util.isArray(options.ca)) {
+      for (var i = 0, len = options.ca.length; i < len; i++) {
+        c.context.addCACert(options.ca[i]);
+      }
+    } else {
+      c.context.addCACert(options.ca);
+    }
+  } else {
+    c.context.addRootCerts();
+  }
+
+  if (options.crl) {
+    if (util.isArray(options.crl)) {
+      for (var i = 0, len = options.crl.length; i < len; i++) {
+        c.context.addCRL(options.crl[i]);
+      }
+    } else {
+      c.context.addCRL(options.crl);
+    }
+  }
+
+  if (options.sessionIdContext) {
+    c.context.setSessionIdContext(options.sessionIdContext);
+  }
+
+  if (options.pfx) {
+    var pfx = options.pfx;
+    var passphrase = options.passphrase;
+
+    if (!crypto)
+      crypto = require('crypto');
+
+    pfx = crypto._toBuf(pfx);
+    if (passphrase)
+      passphrase = crypto._toBuf(passphrase);
+
+    if (passphrase) {
+      c.context.loadPKCS12(pfx, passphrase);
+    } else {
+      c.context.loadPKCS12(pfx);
+    }
+  }
+
+  return c;
+};
index 6916c1e..1d62ed6 100644 (file)
@@ -681,10 +681,10 @@ function onnewsessiondone() {
  * Provides a pair of streams to do encrypted communication.
  */
 
-function SecurePair(credentials, isServer, requestCert, rejectUnauthorized,
+function SecurePair(context, isServer, requestCert, rejectUnauthorized,
                     options) {
   if (!(this instanceof SecurePair)) {
-    return new SecurePair(credentials,
+    return new SecurePair(context,
                           isServer,
                           requestCert,
                           rejectUnauthorized,
@@ -705,10 +705,10 @@ function SecurePair(credentials, isServer, requestCert, rejectUnauthorized,
   this._doneFlag = false;
   this._destroying = false;
 
-  if (!credentials) {
-    this.credentials = crypto.createCredentials();
+  if (!context) {
+    this.credentials = tls.createSecureContext();
   } else {
-    this.credentials = credentials;
+    this.credentials = context;
   }
 
   if (!this._isServer) {
@@ -774,11 +774,11 @@ function SecurePair(credentials, isServer, requestCert, rejectUnauthorized,
 util.inherits(SecurePair, events.EventEmitter);
 
 
-exports.createSecurePair = function(credentials,
+exports.createSecurePair = function(context,
                                     isServer,
                                     requestCert,
                                     rejectUnauthorized) {
-  var pair = new SecurePair(credentials,
+  var pair = new SecurePair(context,
                             isServer,
                             requestCert,
                             rejectUnauthorized);
index 941bc70..fc515bb 100644 (file)
@@ -123,8 +123,9 @@ function onclienthello(hello) {
     if (err)
       return self.destroy(err);
 
+    // TODO(indutny): eventually disallow raw `SecureContext`
     if (context)
-      self.ssl.sni_context = context;
+      self.ssl.sni_context = context.context || context;
 
     self.ssl.endParser();
   }
@@ -226,8 +227,10 @@ TLSSocket.prototype._init = function(socket) {
   var options = this._tlsOptions;
 
   // Wrap socket's handle
-  var credentials = options.credentials || crypto.createCredentials();
-  this.ssl = tls_wrap.wrap(this._handle, credentials.context, options.isServer);
+  var context = options.secureContext ||
+                options.credentials ||
+                tls.createSecureContext();
+  this.ssl = tls_wrap.wrap(this._handle, context.context, options.isServer);
   this.server = options.server || null;
 
   // For clients, we will always have either a given ca list or be using
@@ -530,15 +533,14 @@ function Server(/* [options], listener */) {
   // Handle option defaults:
   this.setOptions(options);
 
-  var sharedCreds = crypto.createCredentials({
+  var sharedCreds = tls.createSecureContext({
     pfx: self.pfx,
     key: self.key,
     passphrase: self.passphrase,
     cert: self.cert,
     ca: self.ca,
-    ciphers: self.ciphers || tls.DEFAULT_CIPHERS,
-    ecdhCurve: util.isUndefined(self.ecdhCurve) ?
-        tls.DEFAULT_ECDH_CURVE : self.ecdhCurve,
+    ciphers: self.ciphers,
+    ecdhCurve: self.ecdhCurve,
     secureProtocol: self.secureProtocol,
     secureOptions: self.secureOptions,
     crl: self.crl,
@@ -563,7 +565,7 @@ function Server(/* [options], listener */) {
   // constructor call
   net.Server.call(this, function(raw_socket) {
     var socket = new TLSSocket(raw_socket, {
-      credentials: sharedCreds,
+      secureContext: sharedCreds,
       isServer: true,
       server: self,
       requestCert: self.requestCert,
@@ -674,7 +676,7 @@ Server.prototype.setOptions = function(options) {
 };
 
 // SNI Contexts High-Level API
-Server.prototype.addContext = function(servername, credentials) {
+Server.prototype.addContext = function(servername, context) {
   if (!servername) {
     throw 'Servername is required parameter for Server.addContext';
   }
@@ -683,7 +685,7 @@ Server.prototype.addContext = function(servername, credentials) {
                       servername.replace(/([\.^$+?\-\\[\]{}])/g, '\\$1')
                                 .replace(/\*/g, '[^\.]*') +
                       '$');
-  this._contexts.push([re, crypto.createCredentials(credentials).context]);
+  this._contexts.push([re, tls.createSecureContext(context).context]);
 };
 
 function SNICallback(servername, callback) {
@@ -728,12 +730,12 @@ function normalizeConnectArgs(listArgs) {
   return (cb) ? [options, cb] : [options];
 }
 
-function legacyConnect(hostname, options, NPN, credentials) {
+function legacyConnect(hostname, options, NPN, context) {
   assert(options.socket);
   if (!tls_legacy)
     tls_legacy = require('_tls_legacy');
 
-  var pair = tls_legacy.createSecurePair(credentials,
+  var pair = tls_legacy.createSecurePair(context,
                                          false,
                                          true,
                                          !!options.rejectUnauthorized,
@@ -765,7 +767,7 @@ exports.connect = function(/* [port, host], options, cb */) {
                  options.host ||
                  options.socket && options.socket._host,
       NPN = {},
-      credentials = crypto.createCredentials(options);
+      context = tls.createSecureContext(options);
   tls.convertNPNProtocols(options.NPNProtocols, NPN);
 
   // Wrapping TLS socket inside another TLS socket was requested -
@@ -776,12 +778,12 @@ exports.connect = function(/* [port, host], options, cb */) {
   if (options.socket instanceof TLSSocket) {
     debug('legacy connect');
     legacy = true;
-    socket = legacyConnect(hostname, options, NPN, credentials);
+    socket = legacyConnect(hostname, options, NPN, context);
     result = socket.cleartext;
   } else {
     legacy = false;
     socket = new TLSSocket(options.socket, {
-      credentials: credentials,
+      secureContext: context,
       isServer: false,
       requestCert: true,
       rejectUnauthorized: options.rejectUnauthorized,
index 464d5be..80d8369 100644 (file)
@@ -26,7 +26,6 @@ exports.DEFAULT_ENCODING = 'buffer';
 
 try {
   var binding = process.binding('crypto');
-  var SecureContext = binding.SecureContext;
   var randomBytes = binding.randomBytes;
   var pseudoRandomBytes = binding.pseudoRandomBytes;
   var getCiphers = binding.getCiphers;
@@ -53,101 +52,12 @@ function toBuf(str, encoding) {
   }
   return str;
 }
+exports._toBuf = toBuf;
 
 
 var assert = require('assert');
 var StringDecoder = require('string_decoder').StringDecoder;
 
-function Credentials(secureProtocol, flags, context) {
-  if (!(this instanceof Credentials)) {
-    return new Credentials(secureProtocol, flags, context);
-  }
-
-  if (context) {
-    this.context = context;
-  } else {
-    this.context = new SecureContext();
-
-    if (secureProtocol) {
-      this.context.init(secureProtocol);
-    } else {
-      this.context.init();
-    }
-  }
-
-  if (flags) this.context.setOptions(flags);
-}
-
-exports.Credentials = Credentials;
-
-
-exports.createCredentials = function(options, context) {
-  if (!options) options = {};
-
-  var c = new Credentials(options.secureProtocol,
-                          options.secureOptions,
-                          context);
-
-  if (context) return c;
-
-  if (options.key) {
-    if (options.passphrase) {
-      c.context.setKey(options.key, options.passphrase);
-    } else {
-      c.context.setKey(options.key);
-    }
-  }
-
-  if (options.cert) c.context.setCert(options.cert);
-
-  if (options.ciphers) c.context.setCiphers(options.ciphers);
-
-  if (options.ecdhCurve) c.context.setECDHCurve(options.ecdhCurve);
-
-  if (options.ca) {
-    if (util.isArray(options.ca)) {
-      for (var i = 0, len = options.ca.length; i < len; i++) {
-        c.context.addCACert(options.ca[i]);
-      }
-    } else {
-      c.context.addCACert(options.ca);
-    }
-  } else {
-    c.context.addRootCerts();
-  }
-
-  if (options.crl) {
-    if (util.isArray(options.crl)) {
-      for (var i = 0, len = options.crl.length; i < len; i++) {
-        c.context.addCRL(options.crl[i]);
-      }
-    } else {
-      c.context.addCRL(options.crl);
-    }
-  }
-
-  if (options.sessionIdContext) {
-    c.context.setSessionIdContext(options.sessionIdContext);
-  }
-
-  if (options.pfx) {
-    var pfx = options.pfx;
-    var passphrase = options.passphrase;
-
-    pfx = toBuf(pfx);
-    if (passphrase)
-      passphrase = toBuf(passphrase);
-
-    if (passphrase) {
-      c.context.loadPKCS12(pfx, passphrase);
-    } else {
-      c.context.loadPKCS12(pfx);
-    }
-  }
-
-  return c;
-};
-
 
 function LazyTransform(options) {
   this._options = options;
@@ -711,3 +621,12 @@ function filterDuplicates(names) {
     return ctx[key];
   }).sort();
 }
+
+// Legacy API
+exports.__defineGetter__('createCredentials', util.deprecate(function() {
+  return require('tls').createSecureContext;
+}, 'createCredentials() is deprecated, use tls.createSecureContext instead'));
+
+exports.__defineGetter__('Credentials', util.deprecate(function() {
+  return require('tls').SecureContext;
+}, 'Credentials is deprecated, use tls.createSecureContext instead'));
index 3004c32..197e968 100644 (file)
@@ -23,12 +23,6 @@ var net = require('net');
 var url = require('url');
 var util = require('util');
 
-exports.DEFAULT_CIPHERS =
-    'ECDHE-RSA-AES128-SHA256:AES128-GCM-SHA256:' + // TLS 1.2
-    'RC4:HIGH:!MD5:!aNULL:!EDH';                   // TLS 1.0
-
-exports.DEFAULT_ECDH_CURVE = 'prime256v1';
-
 // Allow {CLIENT_RENEG_LIMIT} client-initiated session renegotiations
 // every {CLIENT_RENEG_WINDOW} seconds. An error event is emitted if more
 // renegotations are seen. The settings are applied to all remote client
@@ -38,6 +32,12 @@ exports.CLIENT_RENEG_WINDOW = 600;
 
 exports.SLAB_BUFFER_SIZE = 10 * 1024 * 1024;
 
+exports.DEFAULT_CIPHERS =
+    'ECDHE-RSA-AES128-SHA256:AES128-GCM-SHA256:' + // TLS 1.2
+    'RC4:HIGH:!MD5:!aNULL:!EDH';                   // TLS 1.0
+
+exports.DEFAULT_ECDH_CURVE = 'prime256v1';
+
 exports.getCiphers = function() {
   var names = process.binding('crypto').getSSLCiphers();
   // Drop all-caps names in favor of their lowercase aliases,
@@ -209,6 +209,8 @@ exports.parseCertString = function parseCertString(s) {
 };
 
 // Public API
+exports.createSecureContext = require('_tls_common').createSecureContext;
+exports.SecureContext = require('_tls_common').SecureContext;
 exports.TLSSocket = require('_tls_wrap').TLSSocket;
 exports.Server = require('_tls_wrap').Server;
 exports.createServer = require('_tls_wrap').createServer;
index 86fa64a..a44a4fd 100644 (file)
--- a/node.gyp
+++ b/node.gyp
@@ -59,6 +59,7 @@
       'lib/timers.js',
       'lib/tracing.js',
       'lib/tls.js',
+      'lib/_tls_common.js',
       'lib/_tls_legacy.js',
       'lib/_tls_wrap.js',
       'lib/tty.js',
index c5dcae2..45c745c 100644 (file)
@@ -1834,7 +1834,7 @@ void Connection::New(const FunctionCallbackInfo<Value>& args) {
   HandleScope scope(env->isolate());
 
   if (args.Length() < 1 || !args[0]->IsObject()) {
-    env->ThrowError("First argument must be a crypto module Credentials");
+    env->ThrowError("First argument must be a tls module SecureContext");
     return;
   }
 
index 9ef2f6e..711fae3 100644 (file)
@@ -128,7 +128,7 @@ function test(keyfn, certfn, check, next) {
   function startClient() {
     var s = new net.Stream();
 
-    var sslcontext = crypto.createCredentials({key: key, cert: cert});
+    var sslcontext = tls.createSecureContext({key: key, cert: cert});
     sslcontext.context.setCiphers('RC4-SHA:AES128-SHA:AES256-SHA');
 
     var pair = tls.createSecurePair(sslcontext, false);
index ad0a30f..fe7da66 100644 (file)
@@ -29,6 +29,7 @@ var constants = require('constants');
 
 try {
   var crypto = require('crypto');
+  var tls = require('tls');
 } catch (e) {
   console.log('Not compiled with OPENSSL support.');
   process.exit();
@@ -49,11 +50,13 @@ var rsaPubPem = fs.readFileSync(common.fixturesDir + '/test_rsa_pubkey.pem',
 var rsaKeyPem = fs.readFileSync(common.fixturesDir + '/test_rsa_privkey.pem',
     'ascii');
 
+// TODO(indutny): Move to a separate test eventually
 try {
-  var credentials = crypto.createCredentials(
-                                             {key: keyPem,
-                                               cert: certPem,
-                                               ca: caPem});
+  var context = tls.createSecureContext({
+    key: keyPem,
+    cert: certPem,
+    ca: caPem
+  });
 } catch (e) {
   console.log('Not compiled with OPENSSL support.');
   process.exit();
@@ -61,19 +64,19 @@ try {
 
 // PFX tests
 assert.doesNotThrow(function() {
-  crypto.createCredentials({pfx:certPfx, passphrase:'sample'});
+  tls.createSecureContext({pfx:certPfx, passphrase:'sample'});
 });
 
 assert.throws(function() {
-  crypto.createCredentials({pfx:certPfx});
+  tls.createSecureContext({pfx:certPfx});
 }, 'mac verify failure');
 
 assert.throws(function() {
-  crypto.createCredentials({pfx:certPfx, passphrase:'test'});
+  tls.createSecureContext({pfx:certPfx, passphrase:'test'});
 }, 'mac verify failure');
 
 assert.throws(function() {
-  crypto.createCredentials({pfx:'sample', passphrase:'test'});
+  tls.createSecureContext({pfx:'sample', passphrase:'test'});
 }, 'not enough data');
 
 // Test HMAC
index e1b2682..cdf066c 100644 (file)
@@ -58,11 +58,13 @@ var dsaKeyPemEncrypted = fs.readFileSync(
   common.fixturesDir + '/test_dsa_privkey_encrypted.pem', 'ascii');
 
 
+// TODO(indunty): move to a separate test eventually
 try {
-  var credentials = crypto.createCredentials(
-                                             {key: keyPem,
-                                               cert: certPem,
-                                               ca: caPem});
+  var context = tls.createSecureContext({
+    key: keyPem,
+    cert: certPem,
+    ca: caPem
+  });
 } catch (e) {
   console.log('Not compiled with OPENSSL support.');
   process.exit();
@@ -70,19 +72,19 @@ try {
 
 // PFX tests
 assert.doesNotThrow(function() {
-  crypto.createCredentials({pfx:certPfx, passphrase:'sample'});
+  crypto.createSecureContext({pfx:certPfx, passphrase:'sample'});
 });
 
 assert.throws(function() {
-  crypto.createCredentials({pfx:certPfx});
+  tls.createSecureContext({pfx:certPfx});
 }, 'mac verify failure');
 
 assert.throws(function() {
-  crypto.createCredentials({pfx:certPfx, passphrase:'test'});
+  tls.createSecureContext({pfx:certPfx, passphrase:'test'});
 }, 'mac verify failure');
 
 assert.throws(function() {
-  crypto.createCredentials({pfx:'sample', passphrase:'test'});
+  tls.createSecureContext({pfx:'sample', passphrase:'test'});
 }, 'not enough data');
 
 // Test HMAC
index bc5e33b..83f8f86 100644 (file)
 // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
 // USE OR OTHER DEALINGS IN THE SOFTWARE.
 
-var crypto = require('crypto');
 var assert = require('assert');
 var tls = require('tls');
 
 function test1() {
   var ciphers = '';
-  crypto.createCredentials = function(options) {
+  tls.createSecureContext = function(options) {
     ciphers = options.ciphers
   }
   tls.connect(443);
index 17ccb0b..ceacedc 100644 (file)
@@ -28,7 +28,6 @@ var assert = require('assert');
 var fs = require('fs');
 var net = require('net');
 var tls = require('tls');
-var crypto = require('crypto');
 
 var common = require('../common');
 
@@ -45,7 +44,7 @@ var server = net.createServer(function(c) {
   setTimeout(function() {
     var s = new tls.TLSSocket(c, {
       isServer: true,
-      credentials: crypto.createCredentials(options)
+      secureContext: tls.createSecureContext(options)
     });
 
     s.on('data', function(chunk) {
index dac13d7..6b24d75 100644 (file)
@@ -30,7 +30,7 @@ var SSL_Method = 'TLSv1_method';
 var localhost = '127.0.0.1';
 
 process.on('exit', function() {
-  assert.equal(nconns, 5);
+  assert.equal(nconns, 6);
 });
 
 function test(honorCipherOrder, clientCipher, expectedCipher, cb) {
@@ -38,7 +38,7 @@ function test(honorCipherOrder, clientCipher, expectedCipher, cb) {
     secureProtocol: SSL_Method,
     key: fs.readFileSync(common.fixturesDir + '/keys/agent2-key.pem'),
     cert: fs.readFileSync(common.fixturesDir + '/keys/agent2-cert.pem'),
-    ciphers: 'DES-CBC-SHA:AES256-SHA:RC4-SHA',
+    ciphers: 'DES-CBC-SHA:AES256-SHA:RC4-SHA:ECDHE-RSA-AES256-SHA',
     honorCipherOrder: !!honorCipherOrder
   };
 
@@ -96,5 +96,12 @@ function test5() {
   // Client did not explicitly set ciphers. Ensure that client defaults to
   // sane ciphers. Even though server gives top priority to DES-CBC-SHA
   // it should not be negotiated because it's not in default client ciphers.
-  test(true, null, 'AES256-SHA');
+  test(true, null, 'AES256-SHA', test6);
+}
+
+function test6() {
+  // Ensure that `tls.DEFAULT_CIPHERS` is used
+  SSL_Method = 'TLSv1_2_method';
+  tls.DEFAULT_CIPHERS = 'ECDHE-RSA-AES256-SHA';
+  test(true, null, 'ECDHE-RSA-AES256-SHA');
 }
index ef89bd2..0849cc8 100644 (file)
@@ -28,8 +28,7 @@ if (!process.features.tls_npn) {
 var common = require('../common'),
     assert = require('assert'),
     fs = require('fs'),
-    tls = require('tls'),
-    crypto = require('crypto');
+    tls = require('tls');
 
 function filenamePEM(n) {
   return require('path').join(common.fixturesDir, 'keys', n + '.pem');
@@ -43,12 +42,12 @@ var serverOptions = {
   key: loadPEM('agent2-key'),
   cert: loadPEM('agent2-cert'),
   crl: loadPEM('ca2-crl'),
-  SNICallback: function() {
-    return crypto.createCredentials({
+  SNICallback: function(servername, cb) {
+    cb(null, tls.createSecureContext({
       key: loadPEM('agent2-key'),
       cert: loadPEM('agent2-cert'),
       crl: loadPEM('ca2-crl'),
-    }).context;
+    }));
   },
   NPNProtocols: ['a', 'b', 'c']
 };
index 0d98ad7..ece965c 100644 (file)
@@ -31,7 +31,6 @@ var assert = require('assert');
 var join = require('path').join;
 var net = require('net');
 var fs = require('fs');
-var crypto = require('crypto');
 var tls = require('tls');
 var spawn = require('child_process').spawn;
 
@@ -46,7 +45,7 @@ function log(a) {
 var server = net.createServer(function(socket) {
   connections++;
   log('connection fd=' + socket.fd);
-  var sslcontext = crypto.createCredentials({key: key, cert: cert});
+  var sslcontext = tls.createSecureContext({key: key, cert: cert});
   sslcontext.context.setCiphers('RC4-SHA:AES128-SHA:AES256-SHA');
 
   var pair = tls.createSecurePair(sslcontext, true);
index 7de7dea..57c1716 100644 (file)
@@ -27,7 +27,6 @@ if (!process.features.tls_sni) {
 
 var common = require('../common'),
     assert = require('assert'),
-    crypto = require('crypto'),
     fs = require('fs'),
     tls = require('tls');
 
@@ -43,15 +42,15 @@ var serverOptions = {
   key: loadPEM('agent2-key'),
   cert: loadPEM('agent2-cert'),
   SNICallback: function(servername, callback) {
-    var credentials = SNIContexts[servername];
+    var context = SNIContexts[servername];
 
     // Just to test asynchronous callback
     setTimeout(function() {
-      if (credentials) {
-        if (credentials.emptyRegression)
+      if (context) {
+        if (context.emptyRegression)
           callback(null, {});
         else
-          callback(null, crypto.createCredentials(credentials).context);
+          callback(null, tls.createSecureContext(context));
       } else {
         callback(null, null);
       }