UNPKG

openhim-core

Version:

The OpenHIM core application that provides logging and routing of http requests

218 lines (177 loc) 7.84 kB
Keystore = require('../model/keystore').Keystore Q = require 'q' logger = require 'winston' authorisation = require './authorisation' pem = require 'pem' utils = require "../utils" config = require "../config/config" config.certificateManagement = config.get('certificateManagement') exports.getServerCert = -> # Must be admin if authorisation.inGroup('admin', this.authenticated) is false utils.logAndSetResponse this, 403, "User #{this.authenticated.email} is not an admin, API access to getServerCert denied.", 'info' return try keystoreDoc = yield Keystore.findOne().lean('cert').exec() keystoreDoc.cert.watchFSForCert = config.certificateManagement.watchFSForCert this.body = keystoreDoc.cert catch err utils.logAndSetResponse this, 500, "Could not fetch the server cert via the API: #{err}", 'error' exports.getCACerts = -> # Must be admin if authorisation.inGroup('admin', this.authenticated) is false utils.logAndSetResponse this, 403, "User #{this.authenticated.email} is not an admin, API access to getCACerts denied.", 'info' return try keystoreDoc = yield Keystore.findOne().select('ca').exec() this.body = keystoreDoc.ca catch err utils.logAndSetResponse this, 500, "Could not fetch the ca certs trusted by this server via the API: #{err}", 'error' exports.getCACert = (certId) -> # Must be admin if authorisation.inGroup('admin', this.authenticated) is false utils.logAndSetResponse this, 403, "User #{this.authenticated.email} is not an admin, API access to getCACert by id denied.", 'info' return try keystoreDoc = yield Keystore.findOne().select('ca').exec() cert = keystoreDoc.ca.id(certId) this.body = cert catch err utils.logAndSetResponse this, 500, "Could not fetch ca cert by id via the API: #{err}", 'error' exports.setServerPassphrase = -> # Must be admin if authorisation.inGroup('admin', this.authenticated) is false utils.logAndSetResponse this, 403, "User #{this.authenticated.email} is not an admin, API access to setServerPassphrase denied.", 'info' return try passphrase = this.request.body.passphrase keystoreDoc = yield Keystore.findOne().exec() keystoreDoc.passphrase = passphrase yield Q.ninvoke keystoreDoc, 'save' this.status = 201 catch err utils.logAndSetResponse this, 500, "Could not set the passphrase via the API: #{err}", 'error' exports.setServerCert = -> # Must be admin if authorisation.inGroup('admin', this.authenticated) is false utils.logAndSetResponse this, 403, "User #{this.authenticated.email} is not an admin, API access to setServerCert by id denied.", 'info' return if config.certificateManagement.watchFSForCert utils.logAndSetResponse this, 400, "Failed to upload server certificate: Uploading of certificate while watchFSForCert is true is not allowed.", "info" return try cert = this.request.body.cert passphrase = this.request.body.passphrase readCertificateInfo = Q.denodeify pem.readCertificateInfo getFingerprint = Q.denodeify pem.getFingerprint try certInfo = yield readCertificateInfo cert fingerprint = yield getFingerprint cert catch err return utils.logAndSetResponse this, 400, "Could not add server cert via the API: #{err}", 'error' certInfo.data = cert certInfo.fingerprint = fingerprint.fingerprint keystoreDoc = yield Keystore.findOne().exec() keystoreDoc.cert = certInfo keystoreDoc.passphrase = passphrase yield Q.ninvoke keystoreDoc, 'save' this.status = 201 catch err utils.logAndSetResponse this, 500, "Could not add server cert via the API: #{err}", 'error' exports.setServerKey = -> # Must be admin if authorisation.inGroup('admin', this.authenticated) is false utils.logAndSetResponse this, 403, "User #{this.authenticated.email} is not an admin, API access to getServerKey by id denied.", 'info' return try key = this.request.body.key passphrase = this.request.body.passphrase keystoreDoc = yield Keystore.findOne().exec() keystoreDoc.key = key keystoreDoc.passphrase = passphrase yield Q.ninvoke keystoreDoc, 'save' this.status = 201 catch err utils.logAndSetResponse this, 500, "Could not add server key via the API: #{err}", 'error' exports.addTrustedCert = -> # Must be admin if authorisation.inGroup('admin', this.authenticated) is false utils.logAndSetResponse this, 403, "User #{this.authenticated.email} is not an admin, API access to addTrustedCert by id denied.", 'info' return try invalidCert = false chain = this.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/) certs = [] chain = chain.split "\n" cert = [] for line in chain when line.length isnt 0 cert.push line if line.match /-END CERTIFICATE-/ certs.push ((cert.join "\n") + "\n") cert = [] keystoreDoc = yield Keystore.findOne().exec() readCertificateInfo = Q.denodeify pem.readCertificateInfo getFingerprint = Q.denodeify pem.getFingerprint if certs.length < 1 invalidCert = true for cert in certs try certInfo = yield readCertificateInfo cert fingerprint = yield getFingerprint cert catch err invalidCert = true continue certInfo.data = cert certInfo.fingerprint = fingerprint.fingerprint keystoreDoc.ca.push certInfo yield Q.ninvoke keystoreDoc, 'save' if invalidCert utils.logAndSetResponse this, 400, "Failed to add one more cert, are they valid? #{err}", 'error' else this.status = 201 catch err utils.logAndSetResponse this, 500, "Could not add trusted cert via the API: #{err}", 'error' exports.removeCACert = (certId) -> # Must be admin if authorisation.inGroup('admin', this.authenticated) is false utils.logAndSetResponse this, 403, "User #{this.authenticated.email} is not an admin, API access to removeCACert by id denied.", 'info' return try keystoreDoc = yield Keystore.findOne().exec() keystoreDoc.ca.id(certId).remove() yield Q.ninvoke keystoreDoc, 'save' this.status = 200 catch err utils.logAndSetResponse this, 500, "Could not remove ca cert by id via the API: #{err}", 'error' exports.verifyServerKeys = -> # Must be admin if authorisation.inGroup('admin', this.authenticated) is false utils.logAndSetResponse this, 403, "User #{this.authenticated.email} is not an admin, API access to verifyServerKeys.", 'info' return try try result = yield Q.nfcall getCertKeyStatus catch err return utils.logAndSetResponse this, 400, "Could not verify certificate and key, are they valid? #{err}", 'error' this.body = valid: result this.status = 200 catch err utils.logAndSetResponse this, 500, "Could not determine validity via the API: #{err}", 'error' exports.getCertKeyStatus = getCertKeyStatus = (callback) -> Keystore.findOne (err, keystoreDoc) -> return callback err, null if err # if the key is encrypted but no passphrase is supplied, return false instantly if /Proc-Type:.*ENCRYPTED/.test(keystoreDoc.key) and (not keystoreDoc.passphrase? or keystoreDoc.passphrase.length == 0) return callback null, false pem.getModulusFromProtected keystoreDoc.key, keystoreDoc.passphrase, (err, keyModulus) -> return callback err, null if err pem.getModulus keystoreDoc.cert.data, (err, certModulus) -> return callback err, null if err # if cert/key match and are valid if keyModulus.modulus is certModulus.modulus return callback null, true else return callback null, false