updates
This commit is contained in:
		
							parent
							
								
									e57203751a
								
							
						
					
					
						commit
						fd4dd009ab
					
				@ -1,9 +1,27 @@
 | 
				
			|||||||
'use strict';
 | 
					'use strict';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// opts = { renewWithin, renew, register, httpsOptions }
 | 
					// opts = { notBefore, notAfter, renew, register, httpsOptions }
 | 
				
			||||||
module.exports.create = function (opts) {
 | 
					module.exports.create = function (opts) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!opts.notBefore) { throw new Error("must supply options.notBefore (and options.notAfter)"); }
 | 
				
			||||||
 | 
					  if (!opts.notAfter) { opts.notAfter = opts.notBefore - (3 * 24 * 60 * 60 * 1000); }
 | 
				
			||||||
 | 
					  if (!opts.httpsOptions) { opts.httpOptions = {}; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  //opts.renewWithin = opts.notBefore;                    // i.e. 15 days
 | 
				
			||||||
 | 
					  opts.renewWindow = opts.notBefore - opts.notAfter;      // i.e. 1 day
 | 
				
			||||||
 | 
					  //opts.renewRatio = opts.notBefore = opts.renewWindow;  // i.e. 1/15 (6.67%)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  var tls = require('tls');
 | 
					  var tls = require('tls');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  var snicb = {
 | 
					  var snicb = {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -11,10 +29,6 @@ module.exports.create = function (opts) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // in-process cache
 | 
					    // in-process cache
 | 
				
			||||||
    _ipc: {}
 | 
					    _ipc: {}
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // just to account for clock skew
 | 
					    // just to account for clock skew
 | 
				
			||||||
  , _fiveMin: 5 * 60 * 1000
 | 
					  , _fiveMin: 5 * 60 * 1000
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -23,12 +37,9 @@ module.exports.create = function (opts) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // cache and format incoming certs
 | 
					    // cache and format incoming certs
 | 
				
			||||||
  , cacheCerts: function (certs) {
 | 
					  , cacheCerts: function (certs) {
 | 
				
			||||||
      certs.altnames.forEach(function (domain) {
 | 
					      var meta = {
 | 
				
			||||||
        snicb._ipc[domain] = { subject: certs.subject };
 | 
					        certs: certs
 | 
				
			||||||
      });
 | 
					      , tlsContext: tls.createSecureContext({
 | 
				
			||||||
      snicb._ipc[certs.subject] = certs;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      certs.tlsContext = tls.createSecureContext({
 | 
					 | 
				
			||||||
          key: certs.privkey
 | 
					          key: certs.privkey
 | 
				
			||||||
        , cert: certs.cert + certs.chain
 | 
					        , cert: certs.cert + certs.chain
 | 
				
			||||||
        , rejectUnauthorized: opts.httpsOptions.rejectUnauthorized
 | 
					        , rejectUnauthorized: opts.httpsOptions.rejectUnauthorized
 | 
				
			||||||
@ -36,9 +47,21 @@ module.exports.create = function (opts) {
 | 
				
			|||||||
        , requestCert: opts.httpsOptions.requestCert  // request peer verification
 | 
					        , requestCert: opts.httpsOptions.requestCert  // request peer verification
 | 
				
			||||||
        , ca: opts.httpsOptions.ca                    // this chain is for incoming peer connctions
 | 
					        , ca: opts.httpsOptions.ca                    // this chain is for incoming peer connctions
 | 
				
			||||||
        , crl: opts.httpsOptions.crl                  // this crl is for incoming peer connections
 | 
					        , crl: opts.httpsOptions.crl                  // this crl is for incoming peer connections
 | 
				
			||||||
      });
 | 
					        })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      return certs;
 | 
					      , subject: certs.subject
 | 
				
			||||||
 | 
					        // stagger renewal time by a little bit of randomness
 | 
				
			||||||
 | 
					      , renewAt: (certs.expiresAt - (opts.notBefore - (opts.renewWindow * Math.random())))
 | 
				
			||||||
 | 
					        // err just barely on the side of safety
 | 
				
			||||||
 | 
					      , expiresNear: certs.expiresAt - snicb._fiveMin
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      certs.altnames.forEach(function (domain) {
 | 
				
			||||||
 | 
					        snicb._ipc[domain] = { subject: certs.subject };
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					      snicb._ipc[certs.subject] = meta;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      return meta;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -46,32 +69,39 @@ module.exports.create = function (opts) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // automate certificate registration on request
 | 
					    // automate certificate registration on request
 | 
				
			||||||
  , sniCallback: function (domain, cb) {
 | 
					  , sniCallback: function (domain, cb) {
 | 
				
			||||||
      var certs = snicb._ipc[domain];
 | 
					      var certMeta = snicb._ipc[domain];
 | 
				
			||||||
      var promise;
 | 
					      var promise;
 | 
				
			||||||
      var now = Date.now();
 | 
					      var now = Date.now();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (certs && certs.subject !== domain) {
 | 
					      if (certMeta && certMeta.subject !== domain) {
 | 
				
			||||||
        certs = snicb._ipc[domain];
 | 
					        certMeta = snicb._ipc[domain];
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      // err just barely on the side of safety
 | 
					      if (!certMeta) {
 | 
				
			||||||
      if (!certs) {
 | 
					        // we don't have a cert and must get one
 | 
				
			||||||
        promise = opts.register(domain);
 | 
					        promise = opts.register(domain);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      else if (now >= (certs.expiresAt - snicb._fiveMin)) {
 | 
					      else if (now >= certMeta.expiresNear) {
 | 
				
			||||||
        promise = opts.renew(domain, certs);
 | 
					        // we have a cert, but it's no good for the average user
 | 
				
			||||||
 | 
					        promise = opts.renew(domain, certMeta.certs);
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // we could stand to try to renew the cert
 | 
				
			||||||
 | 
					        if (now >= certMeta.renewAt) {
 | 
				
			||||||
 | 
					          // give the cert some time to be validated and replaced before trying again
 | 
				
			||||||
 | 
					          certMeta.renewAt = Date.now() + (2 * 60 * 60 * 1000) + (3 * 60 * 60 * 1000 * Math.random());
 | 
				
			||||||
 | 
					          // let the update happen in the background
 | 
				
			||||||
 | 
					          opts.renew(domain, certMeta.certs).then(snicb.cacheCerts);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      else {
 | 
					
 | 
				
			||||||
        if (now >= (certs.expiresAt - opts.renewWithin)) {
 | 
					        // return the valid cert right away
 | 
				
			||||||
          // in background
 | 
					        cb(null, certMeta.certs);
 | 
				
			||||||
          opts.renew(domain, certs).then(snicb.cacheCerts);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        cb(null, certs);
 | 
					 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      promise.then(snicb.cacheCerts).then(function (certs) {
 | 
					      // promise the non-existent or expired cert
 | 
				
			||||||
        cb(null, certs.tlsContext);
 | 
					      promise.then(snicb.cacheCerts).then(function (certMeta) {
 | 
				
			||||||
 | 
					        cb(null, certMeta.tlsContext);
 | 
				
			||||||
      }, cb);
 | 
					      }, cb);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -2,8 +2,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
module.exports.create = function (opts) {
 | 
					module.exports.create = function (opts) {
 | 
				
			||||||
  if (!opts.letsencrypt) { opts.letsencrypt = require('letsencrypt').create({ server: opts.server }); }
 | 
					  if (!opts.letsencrypt) { opts.letsencrypt = require('letsencrypt').create({ server: opts.server }); }
 | 
				
			||||||
  if ('function' === typeof opts.approve) {
 | 
					  if ('function' !== typeof opts.approveDomains) {
 | 
				
			||||||
    throw new Error("You must provide opts.approve(options, certs, callback) to approve certificates");
 | 
					    throw new Error("You must provide opts.approveDomains(options, certs, callback) to approve certificates");
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function log(debug) {
 | 
					  function log(debug) {
 | 
				
			||||||
@ -17,7 +17,6 @@ module.exports.create = function (opts) {
 | 
				
			|||||||
    console.log.apply(console, args);
 | 
					    console.log.apply(console, args);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  opts._pending = {};
 | 
					 | 
				
			||||||
  opts._le = opts.letsencrypt;
 | 
					  opts._le = opts.letsencrypt;
 | 
				
			||||||
  opts.addWorker = function (worker) {
 | 
					  opts.addWorker = function (worker) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user