0
0
mirror of https://github.com/nodejs/node.git synced 2024-12-01 16:10:02 +01:00
nodejs/lib/_tls_common.js
James M Snell dcccbfdc79 src: refactor require('constants')
The require('constants') module is currently undocumented and mashes
together unrelated constants. This refactors the require('constants')
in favor of distinct os.constants, fs.constants, and crypto.constants
that are specific to the modules for which they are relevant. The
next step is to document those within the specific modules.

PR-URL: https://github.com/nodejs/node/pull/6534
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Robert Lindstaedt <robert.lindstaedt@gmail.com>
2016-05-17 11:05:18 -07:00

178 lines
4.4 KiB
JavaScript

'use strict';
const internalUtil = require('internal/util');
const tls = require('tls');
const SSL_OP_CIPHER_SERVER_PREFERENCE =
process.binding('constants').crypto.SSL_OP_CIPHER_SERVER_PREFERENCE;
// 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 |= 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 (let 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 (let 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 (let 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) {
var warning = c.context.setDHParam(options.dhparam);
if (warning)
internalUtil.trace(warning);
}
if (options.crl) {
if (Array.isArray(options.crl)) {
for (let 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);
}
}
// Do not keep read/write buffers in free list
if (options.singleUse) {
c.singleUse = true;
c.context.setFreeListLength(0);
}
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;
};