Ejemplo n.º 1
0
function main(conf) {
  const n = +conf.n;

  var i = 0;
  var m = {};
  // First call dominates results
  if (n > 1) {
    tls.convertNPNProtocols(['ABC', 'XYZ123', 'FOO'], m);
    m = {};
  }
  bench.start();
  for (; i < n; i++) tls.convertNPNProtocols(['ABC', 'XYZ123', 'FOO'], m);
  bench.end(n);
}
Ejemplo n.º 2
0
Server.prototype.setOptions = function(options) {
  this.requestCert = options.requestCert === true;
  this.rejectUnauthorized = options.rejectUnauthorized !== false;

  if (options.pfx) this.pfx = options.pfx;
  if (options.key) this.key = options.key;
  if (options.passphrase) this.passphrase = options.passphrase;
  if (options.cert) this.cert = options.cert;
  if (options.ca) this.ca = options.ca;
  if (options.secureProtocol) this.secureProtocol = options.secureProtocol;
  if (options.crl) this.crl = options.crl;
  if (options.ciphers) this.ciphers = options.ciphers;
  if (options.ecdhCurve !== undefined)
    this.ecdhCurve = options.ecdhCurve;
  if (options.dhparam) this.dhparam = options.dhparam;
  if (options.sessionTimeout) this.sessionTimeout = options.sessionTimeout;
  if (options.ticketKeys) this.ticketKeys = options.ticketKeys;
  var secureOptions = options.secureOptions || 0;
  if (options.honorCipherOrder !== undefined)
    this.honorCipherOrder = !!options.honorCipherOrder;
  else
    this.honorCipherOrder = true;
  if (secureOptions) this.secureOptions = secureOptions;
  if (options.NPNProtocols) tls.convertNPNProtocols(options.NPNProtocols, this);
  if (options.ALPNProtocols)
    tls.convertALPNProtocols(options.ALPNProtocols, this);
  if (options.sessionIdContext) {
    this.sessionIdContext = options.sessionIdContext;
  } else {
    this.sessionIdContext = crypto.createHash('sha1')
                                  .update(process.argv.join(' '))
                                  .digest('hex')
                                  .slice(0, 32);
  }
};
Ejemplo n.º 3
0
function main(conf) {
  const n = +conf.n;

  var i = 0;
  var m = {};
  common.v8ForceOptimization(
    tls.convertNPNProtocols, ['ABC', 'XYZ123', 'FOO'], m);
  bench.start();
  for (; i < n; i++) tls.convertNPNProtocols(['ABC', 'XYZ123', 'FOO'], m);
  bench.end(n);
}
Ejemplo n.º 4
0
function TLSSocket(socket, opts) {
  const tlsOptions = Object.assign({}, opts);

  if (tlsOptions.NPNProtocols)
    tls.convertNPNProtocols(tlsOptions.NPNProtocols, tlsOptions);
  if (tlsOptions.ALPNProtocols)
    tls.convertALPNProtocols(tlsOptions.ALPNProtocols, tlsOptions);

  this._tlsOptions = tlsOptions;
  this._secureEstablished = false;
  this._securePending = false;
  this._newSessionPending = false;
  this._controlReleased = false;
  this._SNICallback = null;
  this.servername = null;
  this.npnProtocol = null;
  this.alpnProtocol = null;
  this.authorized = false;
  this.authorizationError = null;
  this[kRes] = null;

  // Wrap plain JS Stream into StreamWrap
  var wrap;
  if ((socket instanceof net.Socket && socket._handle) || !socket)
    wrap = socket;
  else
    wrap = new StreamWrap(socket);

  // Just a documented property to make secure sockets
  // distinguishable from regular ones.
  this.encrypted = true;

  net.Socket.call(this, {
    handle: this._wrapHandle(wrap),
    allowHalfOpen: socket && socket.allowHalfOpen,
    readable: false,
    writable: false
  });

  // Proxy for API compatibility
  this.ssl = this._handle;

  this.on('error', this._tlsError);

  this._init(socket, wrap);

  // Make sure to setup all required properties like: `connecting` before
  // starting the flow of the data
  this.readable = true;
  this.writable = true;

  // Read on next tick so the caller has a chance to setup listeners
  process.nextTick(initRead, this, socket);
}
Ejemplo n.º 5
0
Server.prototype.setOptions = function(options) {
  if (util.isBoolean(options.requestCert)) {
    this.requestCert = options.requestCert;
  } else {
    this.requestCert = false;
  }

  if (util.isBoolean(options.rejectUnauthorized)) {
    this.rejectUnauthorized = options.rejectUnauthorized;
  } else {
    this.rejectUnauthorized = false;
  }

  if (options.pfx) this.pfx = options.pfx;
  if (options.key) this.key = options.key;
  if (options.passphrase) this.passphrase = options.passphrase;
  if (options.cert) this.cert = options.cert;
  if (options.ca) this.ca = options.ca;
  if (options.secureProtocol) this.secureProtocol = options.secureProtocol;
  if (options.crl) this.crl = options.crl;
  if (options.ciphers) this.ciphers = options.ciphers;
  if (!util.isUndefined(options.ecdhCurve))
    this.ecdhCurve = options.ecdhCurve;
  if (options.dhparam) this.dhparam = options.dhparam;
  if (options.sessionTimeout) this.sessionTimeout = options.sessionTimeout;
  if (options.ticketKeys) this.ticketKeys = options.ticketKeys;

  var secureOptions = common._getSecureOptions(options.secureProtocol,
                                               options.secureOptions);

  if (options.honorCipherOrder) {
    secureOptions |= constants.SSL_OP_CIPHER_SERVER_PREFERENCE;
  }

  if (options.honorCipherOrder)
    this.honorCipherOrder = true;
  else
    this.honorCipherOrder = false;

  this.secureOptions = secureOptions;

  if (options.NPNProtocols) tls.convertNPNProtocols(options.NPNProtocols, this);
  if (options.sessionIdContext) {
    this.sessionIdContext = options.sessionIdContext;
  } else {
    this.sessionIdContext = crypto.createHash('md5')
                                  .update(process.argv.join(' '))
                                  .digest('hex');
  }
};
Ejemplo n.º 6
0
Server.prototype.setOptions = function(options) {
  if (IS_BOOLEAN(options.requestCert)) {
    this.requestCert = options.requestCert;
  } else {
    this.requestCert = false;
  }

  if (IS_BOOLEAN(options.rejectUnauthorized)) {
    this.rejectUnauthorized = options.rejectUnauthorized;
  } else {
    this.rejectUnauthorized = false;
  }

  if (options.pfx) this.pfx = options.pfx;
  if (options.key) this.key = options.key;
  if (options.passphrase) this.passphrase = options.passphrase;
  if (options.cert) this.cert = options.cert;
  if (options.ca) this.ca = options.ca;
  if (options.secureProtocol) this.secureProtocol = options.secureProtocol;
  if (options.crl) this.crl = options.crl;
  if (options.ciphers) this.ciphers = options.ciphers;
  if (options.sessionTimeout) this.sessionTimeout = options.sessionTimeout;
  var secureOptions = options.secureOptions || 0;
  if (options.honorCipherOrder) {
    secureOptions |= constants.SSL_OP_CIPHER_SERVER_PREFERENCE;
  }
  if (secureOptions) this.secureOptions = secureOptions;
  if (options.NPNProtocols) tls.convertNPNProtocols(options.NPNProtocols, this);
  if (options.SNICallback) {
    this.SNICallback = options.SNICallback;
  } else {
    this.SNICallback = this.SNICallback.bind(this);
  }
  if (options.sessionIdContext) {
    this.sessionIdContext = options.sessionIdContext;
  } else if (this.requestCert) {
    this.sessionIdContext = crypto.createHash('md5')
                                  .update(process.argv.join(' '))
                                  .digest('hex');
  }
};
Ejemplo n.º 7
0
exports.connect = function(/* [port, host], options, cb */) {
  var args = normalizeConnectArgs(arguments);
  var options = args[0];
  var cb = args[1];

  var defaults = {
    rejectUnauthorized: '0' !== process.env.NODE_TLS_REJECT_UNAUTHORIZED,
    ciphers: tls.DEFAULT_CIPHERS,
    checkServerIdentity: tls.checkServerIdentity
  };

  options = util._extend(defaults, options || {});
  if (!options.keepAlive)
    options.singleUse = true;

  assert(typeof options.checkServerIdentity === 'function');

  var hostname = options.servername ||
                 options.host ||
                 (options.socket && options.socket._host) ||
                 'localhost',
      NPN = {},
      context = tls.createSecureContext(options);
  tls.convertNPNProtocols(options.NPNProtocols, NPN);

  var socket = new TLSSocket(options.socket, {
    pipe: options.path && !options.port,
    secureContext: context,
    isServer: false,
    requestCert: true,
    rejectUnauthorized: options.rejectUnauthorized,
    session: options.session,
    NPNProtocols: NPN.NPNProtocols,
    requestOCSP: options.requestOCSP
  });

  if (cb)
    socket.once('secureConnect', cb);

  if (!options.socket) {
    var connect_opt;
    if (options.path && !options.port) {
      connect_opt = { path: options.path };
    } else {
      connect_opt = {
        port: options.port,
        host: options.host,
        localAddress: options.localAddress
      };
    }
    socket.connect(connect_opt, function() {
      socket._start();
    });
  }

  socket._releaseControl();

  if (options.session)
    socket.setSession(options.session);

  if (options.servername)
    socket.setServername(options.servername);

  if (options.socket)
    socket._start();

  socket.on('secure', function() {
    var verifyError = socket._handle.verifyError();

    // Verify that server's identity matches it's certificate's names
    if (!verifyError) {
      var cert = socket.getPeerCertificate();
      verifyError = options.checkServerIdentity(hostname, cert);
    }

    if (verifyError) {
      socket.authorized = false;
      socket.authorizationError = verifyError.code || verifyError.message;

      if (options.rejectUnauthorized) {
        socket.emit('error', verifyError);
        socket.destroy();
        return;
      } else {
        socket.emit('secureConnect');
      }
    } else {
      socket.authorized = true;
      socket.emit('secureConnect');
    }

    // Uncork incoming data
    socket.removeListener('end', onHangUp);
  });

  function onHangUp() {
    // NOTE: This logic is shared with _http_client.js
    if (!socket._hadError) {
      socket._hadError = true;
      var error = new Error('socket hang up');
      error.code = 'ECONNRESET';
      socket.destroy();
      socket.emit('error', error);
    }
  }
  socket.once('end', onHangUp);

  return socket;
};
Ejemplo n.º 8
0
exports.connect = function(/* [port, host], options, cb */) {
  var args = normalizeConnectArgs(arguments);
  var options = args[0];
  var cb = args[1];

  var defaults = {
    rejectUnauthorized: '0' !== process.env.NODE_TLS_REJECT_UNAUTHORIZED
  };
  options = util._extend(defaults, options || {});

  var hostname = options.servername || options.host || 'localhost',
      NPN = {},
      credentials = crypto.createCredentials(options);
  tls.convertNPNProtocols(options.NPNProtocols, NPN);

  // Wrapping TLS socket inside another TLS socket was requested -
  // create legacy secure pair
  var socket;
  var legacy;
  var result;
  if (options.socket instanceof TLSSocket) {
    debug('legacy connect');
    legacy = true;
    socket = legacyConnect(hostname, options, NPN, credentials);
    result = socket.cleartext;
  } else {
    legacy = false;
    socket = new TLSSocket(options.socket, {
      credentials: credentials,
      isServer: false,
      requestCert: true,
      rejectUnauthorized: options.rejectUnauthorized,
      NPNProtocols: NPN.NPNProtocols
    });
    result = socket;
  }

  if (socket._handle)
    onHandle();
  else
    socket.once('connect', onHandle);

  if (cb)
    result.once('secureConnect', cb);

  if (!options.socket) {
    assert(!legacy);
    var connect_opt;
    if (options.path && !options.port) {
      connect_opt = { path: options.path };
    } else {
      connect_opt = {
        port: options.port,
        host: options.host,
        localAddress: options.localAddress
      };
    }
    socket.connect(connect_opt);
  }

  return result;

  function onHandle() {
    if (!legacy)
      socket._releaseControl();

    if (options.session)
      socket.setSession(options.session);

    if (!legacy) {
      if (options.servername)
        socket.setServername(options.servername);

      socket._start();
    }
    socket.on('secure', function() {
      var verifyError = socket.ssl.verifyError();

      // Verify that server's identity matches it's certificate's names
      if (!verifyError) {
        var cert = result.getPeerCertificate();
        var validCert = tls.checkServerIdentity(hostname, cert);
        if (!validCert) {
          verifyError = new Error('Hostname/IP doesn\'t match certificate\'s ' +
                                  'altnames');
        }
      }

      if (verifyError) {
        result.authorized = false;
        result.authorizationError = verifyError.message;

        if (options.rejectUnauthorized) {
          result.emit('error', verifyError);
          result.destroy();
          return;
        } else {
          result.emit('secureConnect');
        }
      } else {
        result.authorized = true;
        result.emit('secureConnect');
      }

      // Uncork incoming data
      result.removeListener('end', onHangUp);
    });

    function onHangUp() {
      // NOTE: This logic is shared with _http_client.js
      if (!socket._hadError) {
        socket._hadError = true;
        var error = new Error('socket hang up');
        error.code = 'ECONNRESET';
        socket.destroy();
        socket.emit('error', error);
      }
    }
    result.once('end', onHangUp);
  }
};
Ejemplo n.º 9
0
exports.connect = function(/* [port, host], options, cb */) {
  const argsLen = arguments.length;
  var args = new Array(argsLen);
  for (var i = 0; i < argsLen; i++)
    args[i] = arguments[i];
  args = normalizeConnectArgs(args);
  var options = args[0];
  var cb = args[1];

  var defaults = {
    rejectUnauthorized: '0' !== process.env.NODE_TLS_REJECT_UNAUTHORIZED,
    ciphers: tls.DEFAULT_CIPHERS,
    checkServerIdentity: tls.checkServerIdentity,
    minDHSize: 1024
  };

  options = util._extend(defaults, options || {});
  if (!options.keepAlive)
    options.singleUse = true;

  assert(typeof options.checkServerIdentity === 'function');
  assert(typeof options.minDHSize === 'number',
         'options.minDHSize is not a number: ' + options.minDHSize);
  assert(options.minDHSize > 0,
         'options.minDHSize is not a positive number: ' +
         options.minDHSize);

  var hostname = options.servername ||
                 options.host ||
                 (options.socket && options.socket._host) ||
                 'localhost';
  const NPN = {};
  const ALPN = {};
  const context = options.secureContext || tls.createSecureContext(options);
  tls.convertNPNProtocols(options.NPNProtocols, NPN);
  tls.convertALPNProtocols(options.ALPNProtocols, ALPN);

  var socket = new TLSSocket(options.socket, {
    pipe: options.path && !options.port,
    secureContext: context,
    isServer: false,
    requestCert: true,
    rejectUnauthorized: options.rejectUnauthorized,
    session: options.session,
    NPNProtocols: NPN.NPNProtocols,
    ALPNProtocols: ALPN.ALPNProtocols,
    requestOCSP: options.requestOCSP
  });

  if (cb)
    socket.once('secureConnect', cb);

  if (!options.socket) {
    var connect_opt;
    if (options.path && !options.port) {
      connect_opt = { path: options.path };
    } else {
      connect_opt = {
        port: options.port,
        host: options.host,
        localAddress: options.localAddress
      };
    }
    socket.connect(connect_opt, function() {
      socket._start();
    });
  }

  socket._releaseControl();

  if (options.session)
    socket.setSession(options.session);

  if (options.servername)
    socket.setServername(options.servername);

  if (options.socket)
    socket._start();

  socket.on('secure', function() {
    // Check the size of DHE parameter above minimum requirement
    // 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);
      socket.emit('error', err);
      socket.destroy();
      return;
    }

    var verifyError = socket._handle.verifyError();

    // Verify that server's identity matches it's certificate's names
    // Unless server has resumed our existing session
    if (!verifyError && !socket.isSessionReused()) {
      var cert = socket.getPeerCertificate();
      verifyError = options.checkServerIdentity(hostname, cert);
    }

    if (verifyError) {
      socket.authorized = false;
      socket.authorizationError = verifyError.code || verifyError.message;

      if (options.rejectUnauthorized) {
        socket.destroy(verifyError);
        return;
      } else {
        socket.emit('secureConnect');
      }
    } else {
      socket.authorized = true;
      socket.emit('secureConnect');
    }

    // Uncork incoming data
    socket.removeListener('end', onHangUp);
  });

  function onHangUp() {
    // NOTE: This logic is shared with _http_client.js
    if (!socket._hadError) {
      socket._hadError = true;
      var error = new Error('socket hang up');
      error.code = 'ECONNRESET';
      socket.destroy(error);
    }
  }
  socket.once('end', onHangUp);

  return socket;
};
Ejemplo n.º 10
0
assert.throws(() => tls.createSecurePair({}),
              /Error: First argument must be a tls module SecureContext/);

{
  const buffer = Buffer.from('abcd');
  const out = {};
  tls.convertALPNProtocols(buffer, out);
  out.ALPNProtocols.write('efgh');
  assert(buffer.equals(Buffer.from('abcd')));
  assert(out.ALPNProtocols.equals(Buffer.from('efgh')));
}

{
  const buffer = Buffer.from('abcd');
  const out = {};
  tls.convertNPNProtocols(buffer, out);
  out.NPNProtocols.write('efgh');
  assert(buffer.equals(Buffer.from('abcd')));
  assert(out.NPNProtocols.equals(Buffer.from('efgh')));
}

{
  const buffer = new Uint8Array(Buffer.from('abcd'));
  const out = {};
  tls.convertALPNProtocols(buffer, out);
  assert(out.ALPNProtocols.equals(Buffer.from('abcd')));
}

{
  const buffer = new Uint8Array(Buffer.from('abcd'));
  const out = {};
Ejemplo n.º 11
0
exports.connect = function(/* [port, host], options, cb */) {
  var args = normalizeConnectArgs(arguments);
  var options = args[0];
  var cb = args[1];

  var defaults = {
    rejectUnauthorized: '0' !== process.env.NODE_TLS_REJECT_UNAUTHORIZED,
    ciphers: tls.DEFAULT_CIPHERS,
    checkServerIdentity: tls.checkServerIdentity
  };

  options = util._extend(defaults, options || {});

  options.secureOptions = common._getSecureOptions(options.secureProtocol,
                                                   options.secureOptions);

  assert(typeof options.checkServerIdentity === 'function');

  var hostname = options.servername ||
                 options.host ||
                 options.socket && options.socket._host,
      NPN = {},
      context = tls.createSecureContext(options);
  tls.convertNPNProtocols(options.NPNProtocols, NPN);

  // Wrapping TLS socket inside another TLS socket was requested -
  // create legacy secure pair
  var socket;
  var legacy;
  var result;
  if (options.socket instanceof TLSSocket) {
    debug('legacy connect');
    legacy = true;
    socket = legacyConnect(hostname, options, NPN, context);
    result = socket.cleartext;
  } else {
    legacy = false;
    socket = new TLSSocket(options.socket, {
      secureContext: context,
      isServer: false,
      requestCert: true,
      rejectUnauthorized: options.rejectUnauthorized,
      session: options.session,
      NPNProtocols: NPN.NPNProtocols,
      requestOCSP: options.requestOCSP
    });
    result = socket;
  }

  if (socket._handle && !socket._connecting) {
    onHandle();
  } else {
    // Not even started connecting yet (or probably resolving dns address),
    // catch socket errors and assign handle.
    if (!legacy && options.socket) {
      options.socket.once('connect', function() {
        assert(options.socket._handle);
        socket._handle = options.socket._handle;
        socket._handle.owner = socket;
        socket.emit('connect');
      });
    }
    socket.once('connect', onHandle);
  }

  if (cb)
    result.once('secureConnect', cb);

  if (!options.socket) {
    assert(!legacy);
    var connect_opt;
    if (options.path && !options.port) {
      connect_opt = { path: options.path };
    } else {
      connect_opt = {
        port: options.port,
        host: options.host,
        localAddress: options.localAddress
      };
    }
    socket.connect(connect_opt);
  }

  return result;

  function onHandle() {
    if (!legacy)
      socket._releaseControl();

    if (options.session)
      socket.setSession(options.session);

    if (!legacy) {
      if (options.servername)
        socket.setServername(options.servername);

      socket._start();
    }
    socket.on('secure', function() {
      var verifyError = socket.ssl.verifyError();

      // Verify that server's identity matches it's certificate's names
      if (!verifyError) {
        var cert = result.getPeerCertificate();
        verifyError = options.checkServerIdentity(hostname, cert);
      }

      if (verifyError) {
        result.authorized = false;
        result.authorizationError = verifyError.code || verifyError.message;

        if (options.rejectUnauthorized) {
          result.emit('error', verifyError);
          result.destroy();
          return;
        } else {
          result.emit('secureConnect');
        }
      } else {
        result.authorized = true;
        result.emit('secureConnect');
      }

      // Uncork incoming data
      result.removeListener('end', onHangUp);
    });

    function onHangUp() {
      // NOTE: This logic is shared with _http_client.js
      if (!socket._hadError) {
        socket._hadError = true;
        var error = new Error('socket hang up');
        error.code = 'ECONNRESET';
        socket.destroy();
        socket.emit('error', error);
      }
    }
    result.once('end', onHangUp);
  }
};