greenlock-express.js/lib/sni-callback.js

85 lines
1.8 KiB
JavaScript

'use strict';
// opts = { renewWithin, renew, register, httpsOptions }
module.exports.create = function (opts) {
var tls = require('tls');
var snicb = {
// in-process cache
_ipc: {}
// just to account for clock skew
, _fiveMin: 5 * 60 * 1000
// cache and format incoming certs
, cacheCerts: function (certs) {
certs.altnames.forEach(function (domain) {
snicb._ipc[domain] = { subject: certs.subject };
});
snicb._ipc[certs.subject] = certs;
certs.tlsContext = tls.createSecureContext({
key: certs.privkey
, cert: certs.cert + certs.chain
, rejectUnauthorized: opts.httpsOptions.rejectUnauthorized
, requestCert: opts.httpsOptions.requestCert // request peer verification
, ca: opts.httpsOptions.ca // this chain is for incoming peer connctions
, crl: opts.httpsOptions.crl // this crl is for incoming peer connections
});
return certs;
}
// automate certificate registration on request
, sniCallback: function (domain, cb) {
var certs = snicb._ipc[domain];
var promise;
var now = Date.now();
if (certs && certs.subject !== domain) {
certs = snicb._ipc[domain];
}
// err just barely on the side of safety
if (!certs) {
promise = opts.register(domain);
}
else if (now >= (certs.expiresAt - snicb._fiveMin)) {
promise = opts.renew(domain, certs);
}
else {
if (now >= (certs.expiresAt - opts.renewWithin)) {
// in background
opts.renew(domain, certs).then(snicb.cacheCerts);
}
cb(null, certs);
return;
}
promise.then(snicb.cacheCerts).then(function (certs) {
cb(null, certs.tlsContext);
}, cb);
}
};
return snicb;
};