From c15f16cfe49a1afd7561c1fbf5dc071d68e1251f Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Wed, 10 Aug 2016 04:45:12 -0400 Subject: [PATCH] isolate sniCallback logic --- lib/sni-callback.js | 61 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 lib/sni-callback.js diff --git a/lib/sni-callback.js b/lib/sni-callback.js new file mode 100644 index 0000000..872340f --- /dev/null +++ b/lib/sni-callback.js @@ -0,0 +1,61 @@ +'use strict'; + +// renewWithin, renew, register, httpsOptions +module.exports.create = function (opts) { + var tls = require('tls'); + // just to account for clock skew + var fiveMin = 5 * 60 * 1000; + var snicb = { + // in-process cache + _ipc: {} + , 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; + } + , 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 - fiveMin)) { + promise = opts.renew(domain, certs); + } + else { + if (now >= (certs.expiresAt - opts.renewWithin)) { + // in background + opts.renew(domain, certs); + } + cb(null, certs); + return; + } + + promise.then(snicb.cacheCerts).then(function (certs) { + cb(null, certs.tlsContext); + }, cb); + } + }; + + return snicb; +};