| 
									
										
										
										
											2016-08-10 04:45:12 -04:00
										 |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-10 04:49:57 -04:00
										 |  |  | // opts = { renewWithin, renew, register, httpsOptions }
 | 
					
						
							| 
									
										
										
										
											2016-08-10 04:45:12 -04:00
										 |  |  | module.exports.create = function (opts) { | 
					
						
							|  |  |  |   var tls = require('tls'); | 
					
						
							| 
									
										
										
										
											2016-08-10 04:49:57 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-10 04:45:12 -04:00
										 |  |  |   var snicb = { | 
					
						
							| 
									
										
										
										
											2016-08-10 04:49:57 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-10 04:45:12 -04:00
										 |  |  |     // in-process cache
 | 
					
						
							|  |  |  |     _ipc: {} | 
					
						
							| 
									
										
										
										
											2016-08-10 04:49:57 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // just to account for clock skew
 | 
					
						
							|  |  |  |   , _fiveMin: 5 * 60 * 1000 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // cache and format incoming certs
 | 
					
						
							| 
									
										
										
										
											2016-08-10 04:45:12 -04:00
										 |  |  |   , 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; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-08-10 04:49:57 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // automate certificate registration on request
 | 
					
						
							| 
									
										
										
										
											2016-08-10 04:45:12 -04:00
										 |  |  |   , 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); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2016-08-10 04:49:57 -04:00
										 |  |  |       else if (now >= (certs.expiresAt - snicb._fiveMin)) { | 
					
						
							| 
									
										
										
										
											2016-08-10 04:45:12 -04:00
										 |  |  |         promise = opts.renew(domain, certs); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       else { | 
					
						
							|  |  |  |         if (now >= (certs.expiresAt - opts.renewWithin)) { | 
					
						
							|  |  |  |           // in background
 | 
					
						
							| 
									
										
										
										
											2016-08-10 04:49:57 -04:00
										 |  |  |           opts.renew(domain, certs).then(snicb.cacheCerts); | 
					
						
							| 
									
										
										
										
											2016-08-10 04:45:12 -04:00
										 |  |  |         } | 
					
						
							|  |  |  |         cb(null, certs); | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       promise.then(snicb.cacheCerts).then(function (certs) { | 
					
						
							|  |  |  |         cb(null, certs.tlsContext); | 
					
						
							|  |  |  |       }, cb); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-08-10 04:49:57 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-10 04:45:12 -04:00
										 |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return snicb; | 
					
						
							|  |  |  | }; |