openhim-core
Version:
The OpenHIM core application that provides logging and routing of http requests
312 lines (259 loc) • 10.7 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getServerCert = getServerCert;
exports.getCACerts = getCACerts;
exports.getCACert = getCACert;
exports.setServerPassphrase = setServerPassphrase;
exports.setServerCert = setServerCert;
exports.setServerKey = setServerKey;
exports.addTrustedCert = addTrustedCert;
exports.removeCACert = removeCACert;
exports.verifyServerKeys = verifyServerKeys;
exports.getCertKeyStatus = getCertKeyStatus;
var _pem = _interopRequireDefault(require("pem"));
var _keystore = require("../model/keystore");
var authorisation = _interopRequireWildcard(require("./authorisation"));
var utils = _interopRequireWildcard(require("../utils"));
var _config = require("../config");
var _util = require("util");
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
_config.config.certificateManagement = _config.config.get('certificateManagement');
async function getServerCert(ctx) {
// Must be admin
if (authorisation.inGroup('admin', ctx.authenticated) === false) {
utils.logAndSetResponse(ctx, 403, `User ${ctx.authenticated.email} is not an admin, API access to getServerCert denied.`, 'info');
return;
}
try {
const keystoreDoc = await _keystore.KeystoreModelAPI.findOne().lean('cert').exec();
keystoreDoc.cert.watchFSForCert = _config.config.certificateManagement.watchFSForCert;
ctx.body = keystoreDoc.cert;
} catch (err) {
utils.logAndSetResponse(ctx, 500, `Could not fetch the server cert via the API: ${err}`, 'error');
}
}
async function getCACerts(ctx) {
// Must be admin
if (authorisation.inGroup('admin', ctx.authenticated) === false) {
utils.logAndSetResponse(ctx, 403, `User ${ctx.authenticated.email} is not an admin, API access to getCACerts denied.`, 'info');
return;
}
try {
const keystoreDoc = await _keystore.KeystoreModelAPI.findOne().select('ca').exec();
ctx.body = keystoreDoc.ca;
} catch (err) {
utils.logAndSetResponse(ctx, 500, `Could not fetch the ca certs trusted by this server via the API: ${err}`, 'error');
}
}
async function getCACert(ctx, certId) {
// Must be admin
if (authorisation.inGroup('admin', ctx.authenticated) === false) {
utils.logAndSetResponse(ctx, 403, `User ${ctx.authenticated.email} is not an admin, API access to getCACert by id denied.`, 'info');
return;
}
try {
const keystoreDoc = await _keystore.KeystoreModelAPI.findOne().select('ca').exec();
const cert = keystoreDoc.ca.id(certId);
ctx.body = cert;
} catch (err) {
utils.logAndSetResponse(ctx, 500, `Could not fetch ca cert by id via the API: ${err}`, 'error');
}
}
async function setServerPassphrase(ctx) {
// Must be admin
if (authorisation.inGroup('admin', ctx.authenticated) === false) {
utils.logAndSetResponse(ctx, 403, `User ${ctx.authenticated.email} is not an admin, API access to setServerPassphrase denied.`, 'info');
return;
}
try {
const {
passphrase
} = ctx.request.body;
const keystoreDoc = await _keystore.KeystoreModelAPI.findOne().exec();
keystoreDoc.passphrase = passphrase;
await keystoreDoc.save();
ctx.status = 201;
} catch (err) {
utils.logAndSetResponse(ctx, 500, `Could not set the passphrase via the API: ${err}`, 'error');
}
}
async function setServerCert(ctx) {
// Must be admin
let err;
if (authorisation.inGroup('admin', ctx.authenticated) === false) {
utils.logAndSetResponse(ctx, 403, `User ${ctx.authenticated.email} is not an admin, API access to setServerCert by id denied.`, 'info');
return;
}
if (_config.config.certificateManagement.watchFSForCert) {
utils.logAndSetResponse(ctx, 400, 'Failed to upload server certificate: Uploading of certificate while watchFSForCert is true is not allowed.', 'info');
return;
}
try {
let certInfo;
let fingerprint;
const {
cert,
passphrase
} = ctx.request.body;
const readCertificateInfo = (0, _util.promisify)(_pem.default.readCertificateInfo);
const getFingerprint = (0, _util.promisify)(_pem.default.getFingerprint);
try {
certInfo = await readCertificateInfo(cert);
fingerprint = await getFingerprint(cert);
} catch (error) {
err = error;
return utils.logAndSetResponse(ctx, 400, `Could not add server cert via the API: ${err}`, 'error');
}
certInfo.data = cert;
certInfo.fingerprint = fingerprint.fingerprint;
const keystoreDoc = await _keystore.KeystoreModelAPI.findOne().exec();
keystoreDoc.cert = certInfo;
keystoreDoc.passphrase = passphrase;
await keystoreDoc.save();
ctx.status = 201;
} catch (error1) {
err = error1;
utils.logAndSetResponse(ctx, 500, `Could not add server cert via the API: ${err}`, 'error');
}
}
async function setServerKey(ctx) {
// Must be admin
if (authorisation.inGroup('admin', ctx.authenticated) === false) {
utils.logAndSetResponse(ctx, 403, `User ${ctx.authenticated.email} is not an admin, API access to getServerKey by id denied.`, 'info');
return;
}
try {
const {
key,
passphrase
} = ctx.request.body;
const keystoreDoc = await _keystore.KeystoreModelAPI.findOne().exec();
keystoreDoc.key = key;
keystoreDoc.passphrase = passphrase;
await keystoreDoc.save();
ctx.status = 201;
} catch (err) {
return utils.logAndSetResponse(ctx, 500, `Could not add server key via the API: ${err}`, 'error');
}
}
async function addTrustedCert(ctx) {
// Must be admin
let err;
if (authorisation.inGroup('admin', ctx.authenticated) === false) {
utils.logAndSetResponse(ctx, 403, `User ${ctx.authenticated.email} is not an admin, API access to addTrustedCert by id denied.`, 'info');
return;
}
try {
let invalidCert = false;
let chain = ctx.request.body.cert; // Parse into an array in case this is a cert chain
// (code derived from: http://www.benjiegillam.com/2012/06/node-dot-js-ssl-certificate-chain/)
const certs = [];
chain = chain.split('\n');
let cert = [];
for (const line of Array.from(chain)) {
if (line.length !== 0) {
cert.push(line);
if (line.match(/-END CERTIFICATE-/)) {
certs.push(`${cert.join('\n')}\n`);
cert = [];
}
}
}
const keystoreDoc = await _keystore.KeystoreModelAPI.findOne().exec();
const readCertificateInfo = (0, _util.promisify)(_pem.default.readCertificateInfo);
const getFingerprint = (0, _util.promisify)(_pem.default.getFingerprint);
if (certs.length < 1) {
invalidCert = true;
}
for (const cert of Array.from(certs)) {
let certInfo;
let fingerprint;
try {
certInfo = await readCertificateInfo(cert);
fingerprint = await getFingerprint(cert);
} catch (error) {
err = error;
invalidCert = true;
continue;
}
certInfo.data = cert;
certInfo.fingerprint = fingerprint.fingerprint;
keystoreDoc.ca.push(certInfo);
}
await keystoreDoc.save();
if (invalidCert) {
utils.logAndSetResponse(ctx, 400, `Failed to add one more cert, are they valid? ${err}`, 'error');
} else {
ctx.status = 201;
}
} catch (error1) {
err = error1;
utils.logAndSetResponse(ctx, 500, `Could not add trusted cert via the API: ${err}`, 'error');
}
}
async function removeCACert(ctx, certId) {
// Must be admin
if (authorisation.inGroup('admin', ctx.authenticated) === false) {
utils.logAndSetResponse(ctx, 403, `User ${ctx.authenticated.email} is not an admin, API access to removeCACert by id denied.`, 'info');
return;
}
try {
const keystoreDoc = await _keystore.KeystoreModelAPI.findOne().exec();
keystoreDoc.ca.id(certId).remove();
await keystoreDoc.save();
ctx.status = 200;
} catch (err) {
utils.logAndSetResponse(ctx, 500, `Could not remove ca cert by id via the API: ${err}`, 'error');
}
}
async function verifyServerKeys(ctx) {
// Must be admin
if (authorisation.inGroup('admin', ctx.authenticated) === false) {
utils.logAndSetResponse(ctx, 403, `User ${ctx.authenticated.email} is not an admin, API access to verifyServerKeys.`, 'info');
return;
}
try {
let result;
try {
result = await (0, _util.promisify)(getCertKeyStatus)();
} catch (error) {
return utils.logAndSetResponse(ctx, 400, `Could not verify certificate and key, are they valid? ${error}`, 'error');
}
ctx.body = {
valid: result
};
ctx.status = 200;
} catch (error) {
utils.logAndSetResponse(ctx, 500, `Could not determine validity via the API: ${error}`, 'error');
}
}
function getCertKeyStatus(callback) {
return _keystore.KeystoreModelAPI.findOne((err, keystoreDoc) => {
if (err) {
return callback(err, null);
} // if the key is encrypted but no passphrase is supplied, return false instantly
if (/Proc-Type:.*ENCRYPTED/.test(keystoreDoc.key) && (keystoreDoc.passphrase == null || keystoreDoc.passphrase.length === 0)) {
return callback(null, false);
}
return _pem.default.getModulus(keystoreDoc.key, keystoreDoc.passphrase, (err, keyModulus) => {
if (err) {
return callback(err, null);
}
return _pem.default.getModulus(keystoreDoc.cert.data, (err, certModulus) => {
if (err) {
return callback(err, null);
} // if cert/key match and are valid
if (keyModulus.modulus === certModulus.modulus) {
return callback(null, true);
} else {
return callback(null, false);
}
});
});
});
}
//# sourceMappingURL=keystore.js.map