node/lib/_tls_common.js
cjihrig 6ac8bdc0ab lib: reduce util.is*() usage
Many of the util.is*() methods used to check data types
simply compare against a single value or the result of
typeof. This commit replaces calls to these methods with
equivalent checks. This commit does not touch calls to the
more complex methods (isRegExp(), isDate(), etc.).

Fixes: https://github.com/iojs/io.js/issues/607
PR-URL: https://github.com/iojs/io.js/pull/647
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
2015-01-31 23:47:29 -05:00

165 lines
4.1 KiB
JavaScript

'use strict';
const constants = require('constants');
const tls = require('tls');
// Lazily loaded
var crypto = null;
const binding = process.binding('crypto');
const 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 secureOptions = options.secureOptions;
if (options.honorCipherOrder)
secureOptions |= constants.SSL_OP_CIPHER_SERVER_PREFERENCE;
var c = new SecureContext(options.secureProtocol, secureOptions, context);
if (context) return c;
// NOTE: It's important to add CA before the cert to be able to load
// cert's issuer in C++ code.
if (options.ca) {
if (Array.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.cert) {
if (Array.isArray(options.cert)) {
for (var i = 0; i < options.cert.length; i++)
c.context.setCert(options.cert[i]);
} else {
c.context.setCert(options.cert);
}
}
// NOTE: It is important to set the key after the cert.
// `ssl_set_pkey` returns `0` when the key does not much the cert, but
// `ssl_set_cert` returns `1` and nullifies the key in the SSL structure
// which leads to the crash later on.
if (options.key) {
if (Array.isArray(options.key)) {
for (var i = 0; i < options.key.length; i++) {
var key = options.key[i];
if (key.passphrase)
c.context.setKey(key.pem, key.passphrase);
else
c.context.setKey(key);
}
} else {
if (options.passphrase) {
c.context.setKey(options.key, options.passphrase);
} else {
c.context.setKey(options.key);
}
}
}
if (options.ciphers)
c.context.setCiphers(options.ciphers);
else
c.context.setCiphers(tls.DEFAULT_CIPHERS);
if (options.ecdhCurve === undefined)
c.context.setECDHCurve(tls.DEFAULT_ECDH_CURVE);
else if (options.ecdhCurve)
c.context.setECDHCurve(options.ecdhCurve);
if (options.dhparam) c.context.setDHParam(options.dhparam);
if (options.crl) {
if (Array.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;
};
exports.translatePeerCertificate = function translatePeerCertificate(c) {
if (!c)
return null;
if (c.issuer) c.issuer = tls.parseCertString(c.issuer);
if (c.issuerCertificate && c.issuerCertificate !== c) {
c.issuerCertificate = translatePeerCertificate(c.issuerCertificate);
}
if (c.subject) c.subject = tls.parseCertString(c.subject);
if (c.infoAccess) {
var info = c.infoAccess;
c.infoAccess = {};
// XXX: More key validation?
info.replace(/([^\n:]*):([^\n]*)(?:\n|$)/g, function(all, key, val) {
if (key === '__proto__')
return;
if (c.infoAccess.hasOwnProperty(key))
c.infoAccess[key].push(val);
else
c.infoAccess[key] = [val];
});
}
return c;
};