openhim-core
Version:
The OpenHIM core application that provides logging and routing of http requests
300 lines (254 loc) • 10 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 = require('pem');
var _pem2 = _interopRequireDefault(_pem);
var _keystore = require('../model/keystore');
var _authorisation = require('./authorisation');
var authorisation = _interopRequireWildcard(_authorisation);
var _utils = require('../utils');
var utils = _interopRequireWildcard(_utils);
var _config = require('../config');
var _util = require('util');
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; 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)(_pem2.default.readCertificateInfo);
const getFingerprint = (0, _util.promisify)(_pem2.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)(_pem2.default.readCertificateInfo);
const getFingerprint = (0, _util.promisify)(_pem2.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 _pem2.default.getModulus(keystoreDoc.key, keystoreDoc.passphrase, (err, keyModulus) => {
if (err) {
return callback(err, null);
}
return _pem2.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