mirror of
				https://github.com/therootcompany/acme.js.git
				synced 2024-11-16 17:29:00 +00:00 
			
		
		
		
	Compare commits
	
		
			3 Commits
		
	
	
		
			87e3555a5a
			...
			bef931f28f
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| bef931f28f | |||
| eb432571ca | |||
| 29a47e8fa4 | 
							
								
								
									
										22
									
								
								account.js
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								account.js
									
									
									
									
									
								
							| @ -7,11 +7,11 @@ var Keypairs = require('@root/keypairs'); | |||||||
| var Enc = require('@root/encoding/bytes'); | var Enc = require('@root/encoding/bytes'); | ||||||
| var agreers = {}; | var agreers = {}; | ||||||
| 
 | 
 | ||||||
| A._getAccountKid = function(me, options) { | A._getAccountKid = function (me, options) { | ||||||
| 	// It's just fine if there's no account, we'll go get the key id we need via the existing key
 | 	// It's just fine if there's no account, we'll go get the key id we need via the existing key
 | ||||||
| 	var kid = | 	var kid = | ||||||
| 		options.kid || | 		options.kid || | ||||||
| 		(options.account && (options.account.key && options.account.key.kid)); | 		(options.account && options.account.key && options.account.key.kid); | ||||||
| 
 | 
 | ||||||
| 	if (kid) { | 	if (kid) { | ||||||
| 		return Promise.resolve(kid); | 		return Promise.resolve(kid); | ||||||
| @ -19,7 +19,7 @@ A._getAccountKid = function(me, options) { | |||||||
| 
 | 
 | ||||||
| 	//return Promise.reject(new Error("must include KeyID"));
 | 	//return Promise.reject(new Error("must include KeyID"));
 | ||||||
| 	// This is an idempotent request. It'll return the same account for the same public key.
 | 	// This is an idempotent request. It'll return the same account for the same public key.
 | ||||||
| 	return A._registerAccount(me, options).then(function(account) { | 	return A._registerAccount(me, options).then(function (account) { | ||||||
| 		return account.key.kid; | 		return account.key.kid; | ||||||
| 	}); | 	}); | ||||||
| }; | }; | ||||||
| @ -44,7 +44,7 @@ A._getAccountKid = function(me, options) { | |||||||
|    "signature": "RZPOnYoPs1PhjszF...-nh6X1qtOFPB519I" |    "signature": "RZPOnYoPs1PhjszF...-nh6X1qtOFPB519I" | ||||||
|  } |  } | ||||||
| */ | */ | ||||||
| A._registerAccount = function(me, options) { | A._registerAccount = function (me, options) { | ||||||
| 	//#console.debug('[ACME.js] accounts.create');
 | 	//#console.debug('[ACME.js] accounts.create');
 | ||||||
| 
 | 
 | ||||||
| 	function agree(agreed) { | 	function agree(agreed) { | ||||||
| @ -58,7 +58,7 @@ A._registerAccount = function(me, options) { | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	function getAccount() { | 	function getAccount() { | ||||||
| 		return U._importKeypair(options.accountKey).then(function(pair) { | 		return U._importKeypair(options.accountKey).then(function (pair) { | ||||||
| 			var contact; | 			var contact; | ||||||
| 			if (options.contact) { | 			if (options.contact) { | ||||||
| 				contact = options.contact.slice(0); | 				contact = options.contact.slice(0); | ||||||
| @ -73,14 +73,14 @@ A._registerAccount = function(me, options) { | |||||||
| 			}; | 			}; | ||||||
| 
 | 
 | ||||||
| 			var pub = pair.public; | 			var pub = pair.public; | ||||||
| 			return attachExtAcc(pub, accountRequest).then(function(accReq) { | 			return attachExtAcc(pub, accountRequest).then(function (accReq) { | ||||||
| 				var payload = JSON.stringify(accReq); | 				var payload = JSON.stringify(accReq); | ||||||
| 				return U._jwsRequest(me, { | 				return U._jwsRequest(me, { | ||||||
| 					accountKey: options.accountKey, | 					accountKey: options.accountKey, | ||||||
| 					url: me._directoryUrls.newAccount, | 					url: me._directoryUrls.newAccount, | ||||||
| 					protected: { kid: false, jwk: pair.public }, | 					protected: { kid: false, jwk: pair.public }, | ||||||
| 					payload: Enc.strToBuf(payload) | 					payload: Enc.strToBuf(payload) | ||||||
| 				}).then(function(resp) { | 				}).then(function (resp) { | ||||||
| 					var account = resp.body; | 					var account = resp.body; | ||||||
| 
 | 
 | ||||||
| 					if (resp.statusCode < 200 || resp.statusCode >= 300) { | 					if (resp.statusCode < 200 || resp.statusCode >= 300) { | ||||||
| @ -127,18 +127,18 @@ A._registerAccount = function(me, options) { | |||||||
| 				url: me._directoryUrls.newAccount | 				url: me._directoryUrls.newAccount | ||||||
| 			}, | 			}, | ||||||
| 			payload: Enc.strToBuf(JSON.stringify(pubkey)) | 			payload: Enc.strToBuf(JSON.stringify(pubkey)) | ||||||
| 		}).then(function(jws) { | 		}).then(function (jws) { | ||||||
| 			accountRequest.externalAccountBinding = jws; | 			accountRequest.externalAccountBinding = jws; | ||||||
| 			return accountRequest; | 			return accountRequest; | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return Promise.resolve() | 	return Promise.resolve() | ||||||
| 		.then(function() { | 		.then(function () { | ||||||
| 			//#console.debug('[ACME.js] agreeToTerms');
 | 			//#console.debug('[ACME.js] agreeToTerms');
 | ||||||
| 			var agreeToTerms = options.agreeToTerms; | 			var agreeToTerms = options.agreeToTerms; | ||||||
| 			if (!agreeToTerms) { | 			if (!agreeToTerms) { | ||||||
| 				agreeToTerms = function(terms) { | 				agreeToTerms = function (terms) { | ||||||
| 					if (agreers[options.subscriberEmail]) { | 					if (agreers[options.subscriberEmail]) { | ||||||
| 						return true; | 						return true; | ||||||
| 					} | 					} | ||||||
| @ -161,7 +161,7 @@ A._registerAccount = function(me, options) { | |||||||
| 					return true; | 					return true; | ||||||
| 				}; | 				}; | ||||||
| 			} else if (true === agreeToTerms) { | 			} else if (true === agreeToTerms) { | ||||||
| 				agreeToTerms = function(terms) { | 				agreeToTerms = function (terms) { | ||||||
| 					return terms && true; | 					return terms && true; | ||||||
| 				}; | 				}; | ||||||
| 			} | 			} | ||||||
|  | |||||||
							
								
								
									
										225
									
								
								acme.js
									
									
									
									
									
								
							
							
						
						
									
										225
									
								
								acme.js
									
									
									
									
									
								
							| @ -43,7 +43,7 @@ ACME.create = function create(me) { | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (!me.dns01) { | 	if (!me.dns01) { | ||||||
| 		me.dns01 = function(ch) { | 		me.dns01 = function (ch) { | ||||||
| 			return native._dns01(me, ch); | 			return native._dns01(me, ch); | ||||||
| 		}; | 		}; | ||||||
| 	} | 	} | ||||||
| @ -53,7 +53,7 @@ ACME.create = function create(me) { | |||||||
| 		if (!me._baseUrl) { | 		if (!me._baseUrl) { | ||||||
| 			me._baseUrl = ''; | 			me._baseUrl = ''; | ||||||
| 		} | 		} | ||||||
| 		me.http01 = function(ch) { | 		me.http01 = function (ch) { | ||||||
| 			return native._http01(me, ch); | 			return native._http01(me, ch); | ||||||
| 		}; | 		}; | ||||||
| 	} | 	} | ||||||
| @ -62,11 +62,11 @@ ACME.create = function create(me) { | |||||||
| 		me.__request = http.request; | 		me.__request = http.request; | ||||||
| 	} | 	} | ||||||
| 	// passed to dependencies
 | 	// passed to dependencies
 | ||||||
| 	me.request = function(opts) { | 	me.request = function (opts) { | ||||||
| 		return U._request(me, opts); | 		return U._request(me, opts); | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 	me.init = function(opts) { | 	me.init = function (opts) { | ||||||
| 		M.init(me); | 		M.init(me); | ||||||
| 
 | 
 | ||||||
| 		function fin(dir) { | 		function fin(dir) { | ||||||
| @ -90,14 +90,14 @@ ACME.create = function create(me) { | |||||||
| 		if (!me.skipChallengeTest) { | 		if (!me.skipChallengeTest) { | ||||||
| 			p = native._canCheck(me); | 			p = native._canCheck(me); | ||||||
| 		} | 		} | ||||||
| 		return p.then(function() { | 		return p.then(function () { | ||||||
| 			return ACME._directory(me).then(function(resp) { | 			return ACME._directory(me).then(function (resp) { | ||||||
| 				return fin(resp.body); | 				return fin(resp.body); | ||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
| 	}; | 	}; | ||||||
| 	me.accounts = { | 	me.accounts = { | ||||||
| 		create: function(options) { | 		create: function (options) { | ||||||
| 			try { | 			try { | ||||||
| 				return A._registerAccount(me, options); | 				return A._registerAccount(me, options); | ||||||
| 			} catch (e) { | 			} catch (e) { | ||||||
| @ -126,8 +126,8 @@ ACME.create = function create(me) { | |||||||
| 	}; | 	}; | ||||||
|   */ |   */ | ||||||
| 	me.certificates = { | 	me.certificates = { | ||||||
| 		create: function(options) { | 		create: function (options) { | ||||||
| 			return A._getAccountKid(me, options).then(function(kid) { | 			return A._getAccountKid(me, options).then(function (kid) { | ||||||
| 				ACME._normalizePresenters(me, options, options.challenges); | 				ACME._normalizePresenters(me, options, options.challenges); | ||||||
| 				return ACME._getCertificate(me, options, kid); | 				return ACME._getCertificate(me, options, kid); | ||||||
| 			}); | 			}); | ||||||
| @ -143,9 +143,9 @@ ACME.challengePrefixes = { | |||||||
| 	'dns-01': '_acme-challenge' | 	'dns-01': '_acme-challenge' | ||||||
| }; | }; | ||||||
| ACME.challengeTests = { | ACME.challengeTests = { | ||||||
| 	'http-01': function(me, auth) { | 	'http-01': function (me, auth) { | ||||||
| 		var ch = auth.challenge; | 		var ch = auth.challenge; | ||||||
| 		return me.http01(ch).then(function(keyAuth) { | 		return me.http01(ch).then(function (keyAuth) { | ||||||
| 			var err; | 			var err; | ||||||
| 
 | 
 | ||||||
| 			// TODO limit the number of bytes that are allowed to be downloaded
 | 			// TODO limit the number of bytes that are allowed to be downloaded
 | ||||||
| @ -170,14 +170,14 @@ ACME.challengeTests = { | |||||||
| 			throw err; | 			throw err; | ||||||
| 		}); | 		}); | ||||||
| 	}, | 	}, | ||||||
| 	'dns-01': function(me, auth) { | 	'dns-01': function (me, auth) { | ||||||
| 		// remove leading *. on wildcard domains
 | 		// remove leading *. on wildcard domains
 | ||||||
| 		var ch = auth.challenge; | 		var ch = auth.challenge; | ||||||
| 		return me.dns01(ch).then(function(ans) { | 		return me.dns01(ch).then(function (ans) { | ||||||
| 			var err; | 			var err; | ||||||
| 
 | 
 | ||||||
| 			if ( | 			if ( | ||||||
| 				ans.answer.some(function(txt) { | 				ans.answer.some(function (txt) { | ||||||
| 					return ch.dnsAuthorization === txt.data[0]; | 					return ch.dnsAuthorization === txt.data[0]; | ||||||
| 				}) | 				}) | ||||||
| 			) { | 			) { | ||||||
| @ -199,7 +199,7 @@ ACME.challengeTests = { | |||||||
| 	} | 	} | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| ACME._directory = function(me) { | ACME._directory = function (me) { | ||||||
| 	// TODO cache the directory URL
 | 	// TODO cache the directory URL
 | ||||||
| 
 | 
 | ||||||
| 	// GET-as-GET ok
 | 	// GET-as-GET ok
 | ||||||
| @ -210,13 +210,13 @@ ACME._directory = function(me) { | |||||||
| // postChallenge
 | // postChallenge
 | ||||||
| // finalizeOrder
 | // finalizeOrder
 | ||||||
| // getCertificate
 | // getCertificate
 | ||||||
| ACME._getCertificate = function(me, options, kid) { | ACME._getCertificate = function (me, options, kid) { | ||||||
| 	//#console.debug('[ACME.js] certificates.create');
 | 	//#console.debug('[ACME.js] certificates.create');
 | ||||||
| 	return ACME._orderCert(me, options, kid).then(function(order) { | 	return ACME._orderCert(me, options, kid).then(function (order) { | ||||||
| 		return ACME._finalizeOrder(me, options, kid, order); | 		return ACME._finalizeOrder(me, options, kid, order); | ||||||
| 	}); | 	}); | ||||||
| }; | }; | ||||||
| ACME._normalizePresenters = function(me, options, presenters) { | ACME._normalizePresenters = function (me, options, presenters) { | ||||||
| 	// Prefer this order for efficiency:
 | 	// Prefer this order for efficiency:
 | ||||||
| 	// * http-01 is the fasest
 | 	// * http-01 is the fasest
 | ||||||
| 	// * tls-alpn-01 is for networks that don't allow plain traffic
 | 	// * tls-alpn-01 is for networks that don't allow plain traffic
 | ||||||
| @ -224,7 +224,7 @@ ACME._normalizePresenters = function(me, options, presenters) { | |||||||
| 	//   but is required for private networks and wildcards
 | 	//   but is required for private networks and wildcards
 | ||||||
| 	var presenterTypes = Object.keys(options.challenges || {}); | 	var presenterTypes = Object.keys(options.challenges || {}); | ||||||
| 	options._presenterTypes = ['http-01', 'tls-alpn-01', 'dns-01'].filter( | 	options._presenterTypes = ['http-01', 'tls-alpn-01', 'dns-01'].filter( | ||||||
| 		function(typ) { | 		function (typ) { | ||||||
| 			return -1 !== presenterTypes.indexOf(typ); | 			return -1 !== presenterTypes.indexOf(typ); | ||||||
| 		} | 		} | ||||||
| 	); | 	); | ||||||
| @ -244,7 +244,7 @@ ACME._normalizePresenters = function(me, options, presenters) { | |||||||
| 			ACME._propagationDelayWarning = true; | 			ACME._propagationDelayWarning = true; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	Object.keys(presenters || {}).forEach(function(k) { | 	Object.keys(presenters || {}).forEach(function (k) { | ||||||
| 		var ch = presenters[k]; | 		var ch = presenters[k]; | ||||||
| 		var warned = false; | 		var warned = false; | ||||||
| 
 | 
 | ||||||
| @ -280,9 +280,9 @@ ACME._normalizePresenters = function(me, options, presenters) { | |||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		function promisify(fn) { | 		function promisify(fn) { | ||||||
| 			return function(opts) { | 			return function (opts) { | ||||||
| 				new Promise(function(resolve, reject) { | 				new Promise(function (resolve, reject) { | ||||||
| 					fn(opts, function(err, result) { | 					fn(opts, function (err, result) { | ||||||
| 						if (err) { | 						if (err) { | ||||||
| 							reject(err); | 							reject(err); | ||||||
| 							return; | 							return; | ||||||
| @ -344,7 +344,7 @@ ACME._normalizePresenters = function(me, options, presenters) { | |||||||
|    "signature": "H6ZXtGjTZyUnPeKn...wEA4TklBdh3e454g" |    "signature": "H6ZXtGjTZyUnPeKn...wEA4TklBdh3e454g" | ||||||
|  } |  } | ||||||
| */ | */ | ||||||
| ACME._getAuthorization = function(me, options, kid, zonenames, authUrl) { | ACME._getAuthorization = function (me, options, kid, zonenames, authUrl) { | ||||||
| 	//#console.debug('\n[DEBUG] getAuthorization\n');
 | 	//#console.debug('\n[DEBUG] getAuthorization\n');
 | ||||||
| 
 | 
 | ||||||
| 	return U._jwsRequest(me, { | 	return U._jwsRequest(me, { | ||||||
| @ -352,7 +352,7 @@ ACME._getAuthorization = function(me, options, kid, zonenames, authUrl) { | |||||||
| 		url: authUrl, | 		url: authUrl, | ||||||
| 		protected: { kid: kid }, | 		protected: { kid: kid }, | ||||||
| 		payload: '' | 		payload: '' | ||||||
| 	}).then(function(resp) { | 	}).then(function (resp) { | ||||||
| 		// Pre-emptive rather than lazy for interfaces that need to show the
 | 		// Pre-emptive rather than lazy for interfaces that need to show the
 | ||||||
| 		// challenges to the user first
 | 		// challenges to the user first
 | ||||||
| 		return ACME._computeAuths( | 		return ACME._computeAuths( | ||||||
| @ -362,7 +362,7 @@ ACME._getAuthorization = function(me, options, kid, zonenames, authUrl) { | |||||||
| 			resp.body, | 			resp.body, | ||||||
| 			zonenames, | 			zonenames, | ||||||
| 			false | 			false | ||||||
| 		).then(function(auths) { | 		).then(function (auths) { | ||||||
| 			resp.body._rawChallenges = resp.body.challenges; | 			resp.body._rawChallenges = resp.body.challenges; | ||||||
| 			resp.body.challenges = auths; | 			resp.body.challenges = auths; | ||||||
| 			return resp.body; | 			return resp.body; | ||||||
| @ -370,7 +370,7 @@ ACME._getAuthorization = function(me, options, kid, zonenames, authUrl) { | |||||||
| 	}); | 	}); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| ACME._testChallengeOptions = function() { | ACME._testChallengeOptions = function () { | ||||||
| 	// we want this to be the same for the whole group
 | 	// we want this to be the same for the whole group
 | ||||||
| 	var chToken = ACME._prnd(16); | 	var chToken = ACME._prnd(16); | ||||||
| 	return [ | 	return [ | ||||||
| @ -396,9 +396,9 @@ ACME._testChallengeOptions = function() { | |||||||
| 	]; | 	]; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| ACME._thumber = function(options, thumb) { | ACME._thumber = function (options, thumb) { | ||||||
| 	var thumbPromise; | 	var thumbPromise; | ||||||
| 	return function(key) { | 	return function (key) { | ||||||
| 		if (thumb) { | 		if (thumb) { | ||||||
| 			return Promise.resolve(thumb); | 			return Promise.resolve(thumb); | ||||||
| 		} | 		} | ||||||
| @ -408,7 +408,7 @@ ACME._thumber = function(options, thumb) { | |||||||
| 		if (!key) { | 		if (!key) { | ||||||
| 			key = options.accountKey || options.accountKeypair; | 			key = options.accountKey || options.accountKeypair; | ||||||
| 		} | 		} | ||||||
| 		thumbPromise = U._importKeypair(key).then(function(pair) { | 		thumbPromise = U._importKeypair(key).then(function (pair) { | ||||||
| 			return Keypairs.thumbprint({ | 			return Keypairs.thumbprint({ | ||||||
| 				jwk: pair.public | 				jwk: pair.public | ||||||
| 			}); | 			}); | ||||||
| @ -417,9 +417,9 @@ ACME._thumber = function(options, thumb) { | |||||||
| 	}; | 	}; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| ACME._dryRun = function(me, realOptions, zonenames) { | ACME._dryRun = function (me, realOptions, zonenames) { | ||||||
| 	var noopts = {}; | 	var noopts = {}; | ||||||
| 	Object.keys(realOptions).forEach(function(key) { | 	Object.keys(realOptions).forEach(function (key) { | ||||||
| 		noopts[key] = realOptions[key]; | 		noopts[key] = realOptions[key]; | ||||||
| 	}); | 	}); | ||||||
| 	noopts.order = {}; | 	noopts.order = {}; | ||||||
| @ -428,20 +428,20 @@ ACME._dryRun = function(me, realOptions, zonenames) { | |||||||
| 	var getThumbprint = ACME._thumber(noopts, ''); | 	var getThumbprint = ACME._thumber(noopts, ''); | ||||||
| 
 | 
 | ||||||
| 	return Promise.all( | 	return Promise.all( | ||||||
| 		noopts.domains.map(function(identifierValue) { | 		noopts.domains.map(function (identifierValue) { | ||||||
| 			// TODO we really only need one to pass, not all to pass
 | 			// TODO we really only need one to pass, not all to pass
 | ||||||
| 			var challenges = ACME._testChallengeOptions(); | 			var challenges = ACME._testChallengeOptions(); | ||||||
| 			var wild = '*.' === identifierValue.slice(0, 2); | 			var wild = '*.' === identifierValue.slice(0, 2); | ||||||
| 			if (wild) { | 			if (wild) { | ||||||
| 				challenges = challenges.filter(function(ch) { | 				challenges = challenges.filter(function (ch) { | ||||||
| 					return ch._wildcard; | 					return ch._wildcard; | ||||||
| 				}); | 				}); | ||||||
| 			} | 			} | ||||||
| 			challenges = challenges.filter(function(auth) { | 			challenges = challenges.filter(function (auth) { | ||||||
| 				return me._canCheck[auth.type]; | 				return me._canCheck[auth.type]; | ||||||
| 			}); | 			}); | ||||||
| 
 | 
 | ||||||
| 			return getThumbprint().then(function(accountKeyThumb) { | 			return getThumbprint().then(function (accountKeyThumb) { | ||||||
| 				var resp = { | 				var resp = { | ||||||
| 					body: { | 					body: { | ||||||
| 						identifier: { | 						identifier: { | ||||||
| @ -464,23 +464,23 @@ ACME._dryRun = function(me, realOptions, zonenames) { | |||||||
| 					resp.body, | 					resp.body, | ||||||
| 					zonenames, | 					zonenames, | ||||||
| 					dryrun | 					dryrun | ||||||
| 				).then(function(auths) { | 				).then(function (auths) { | ||||||
| 					resp.body.challenges = auths; | 					resp.body.challenges = auths; | ||||||
| 					return resp.body; | 					return resp.body; | ||||||
| 				}); | 				}); | ||||||
| 			}); | 			}); | ||||||
| 		}) | 		}) | ||||||
| 	).then(function(claims) { | 	).then(function (claims) { | ||||||
| 		var selected = []; | 		var selected = []; | ||||||
| 		noopts.order._claims = claims.slice(0); | 		noopts.order._claims = claims.slice(0); | ||||||
| 		noopts.notify = function(ev, params) { | 		noopts.notify = function (ev, params) { | ||||||
| 			if ('_challenge_select' === ev) { | 			if ('_challenge_select' === ev) { | ||||||
| 				selected.push(params.challenge); | 				selected.push(params.challenge); | ||||||
| 			} | 			} | ||||||
| 		}; | 		}; | ||||||
| 
 | 
 | ||||||
| 		function clear() { | 		function clear() { | ||||||
| 			selected.forEach(function(ch) { | 			selected.forEach(function (ch) { | ||||||
| 				ACME._notify(me, noopts, 'challenge_remove', { | 				ACME._notify(me, noopts, 'challenge_remove', { | ||||||
| 					altname: ch.altname, | 					altname: ch.altname, | ||||||
| 					type: ch.type | 					type: ch.type | ||||||
| @ -489,7 +489,7 @@ ACME._dryRun = function(me, realOptions, zonenames) { | |||||||
| 				// ignore promise return
 | 				// ignore promise return
 | ||||||
| 				noopts.challenges[ch.type] | 				noopts.challenges[ch.type] | ||||||
| 					.remove({ challenge: ch }) | 					.remove({ challenge: ch }) | ||||||
| 					.catch(function(err) { | 					.catch(function (err) { | ||||||
| 						err.action = 'challenge_remove'; | 						err.action = 'challenge_remove'; | ||||||
| 						err.altname = ch.altname; | 						err.altname = ch.altname; | ||||||
| 						err.type = ch.type; | 						err.type = ch.type; | ||||||
| @ -499,7 +499,7 @@ ACME._dryRun = function(me, realOptions, zonenames) { | |||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		return ACME._setChallenges(me, noopts, noopts.order) | 		return ACME._setChallenges(me, noopts, noopts.order) | ||||||
| 			.catch(function(err) { | 			.catch(function (err) { | ||||||
| 				clear(); | 				clear(); | ||||||
| 				throw err; | 				throw err; | ||||||
| 			}) | 			}) | ||||||
| @ -510,12 +510,12 @@ ACME._dryRun = function(me, realOptions, zonenames) { | |||||||
| // Get the list of challenge types we can validate,
 | // Get the list of challenge types we can validate,
 | ||||||
| // which is already ordered by preference.
 | // which is already ordered by preference.
 | ||||||
| // Select the first matching offered challenge type
 | // Select the first matching offered challenge type
 | ||||||
| ACME._chooseChallenge = function(options, results) { | ACME._chooseChallenge = function (options, results) { | ||||||
| 	// For each of the challenge types that we support
 | 	// For each of the challenge types that we support
 | ||||||
| 	var challenge; | 	var challenge; | ||||||
| 	options._presenterTypes.some(function(chType) { | 	options._presenterTypes.some(function (chType) { | ||||||
| 		// And for each of the challenge types that are allowed
 | 		// And for each of the challenge types that are allowed
 | ||||||
| 		return results.challenges.some(function(ch) { | 		return results.challenges.some(function (ch) { | ||||||
| 			// Check to see if there are any matches
 | 			// Check to see if there are any matches
 | ||||||
| 			if (ch.type === chType) { | 			if (ch.type === chType) { | ||||||
| 				challenge = ch; | 				challenge = ch; | ||||||
| @ -527,7 +527,7 @@ ACME._chooseChallenge = function(options, results) { | |||||||
| 	return challenge; | 	return challenge; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| ACME._getZones = function(me, challenges, domains) { | ACME._getZones = function (me, challenges, domains) { | ||||||
| 	var presenter = challenges['dns-01']; | 	var presenter = challenges['dns-01']; | ||||||
| 	if (!presenter) { | 	if (!presenter) { | ||||||
| 		return Promise.resolve([]); | 		return Promise.resolve([]); | ||||||
| @ -538,7 +538,7 @@ ACME._getZones = function(me, challenges, domains) { | |||||||
| 
 | 
 | ||||||
| 	// a little bit of random to ensure that getZones()
 | 	// a little bit of random to ensure that getZones()
 | ||||||
| 	// actually returns the zones and not the hosts as zones
 | 	// actually returns the zones and not the hosts as zones
 | ||||||
| 	var dnsHosts = domains.map(function(d) { | 	var dnsHosts = domains.map(function (d) { | ||||||
| 		var rnd = ACME._prnd(2); | 		var rnd = ACME._prnd(2); | ||||||
| 		return rnd + '.' + d; | 		return rnd + '.' + d; | ||||||
| 	}); | 	}); | ||||||
| @ -552,7 +552,7 @@ ACME._getZones = function(me, challenges, domains) { | |||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| ACME._challengesMap = { 'http-01': 0, 'dns-01': 0, 'tls-alpn-01': 0 }; | ACME._challengesMap = { 'http-01': 0, 'dns-01': 0, 'tls-alpn-01': 0 }; | ||||||
| ACME._computeAuths = function(me, options, thumb, authz, zonenames, dryrun) { | ACME._computeAuths = function (me, options, thumb, authz, zonenames, dryrun) { | ||||||
| 	// we don't poison the dns cache with our dummy request
 | 	// we don't poison the dns cache with our dummy request
 | ||||||
| 	var dnsPrefix = ACME.challengePrefixes['dns-01']; | 	var dnsPrefix = ACME.challengePrefixes['dns-01']; | ||||||
| 	if (dryrun) { | 	if (dryrun) { | ||||||
| @ -565,7 +565,7 @@ ACME._computeAuths = function(me, options, thumb, authz, zonenames, dryrun) { | |||||||
| 	var getThumbprint = ACME._thumber(options, thumb); | 	var getThumbprint = ACME._thumber(options, thumb); | ||||||
| 
 | 
 | ||||||
| 	return Promise.all( | 	return Promise.all( | ||||||
| 		authz.challenges.map(function(challenge) { | 		authz.challenges.map(function (challenge) { | ||||||
| 			// Don't do extra work for challenges that we can't satisfy
 | 			// Don't do extra work for challenges that we can't satisfy
 | ||||||
| 			var _types = options._presenterTypes; | 			var _types = options._presenterTypes; | ||||||
| 			if (_types && !_types.includes(challenge.type)) { | 			if (_types && !_types.includes(challenge.type)) { | ||||||
| @ -576,14 +576,14 @@ ACME._computeAuths = function(me, options, thumb, authz, zonenames, dryrun) { | |||||||
| 
 | 
 | ||||||
| 			// straight copy from the new order response
 | 			// straight copy from the new order response
 | ||||||
| 			// { identifier, status, expires, challenges, wildcard }
 | 			// { identifier, status, expires, challenges, wildcard }
 | ||||||
| 			Object.keys(authz).forEach(function(key) { | 			Object.keys(authz).forEach(function (key) { | ||||||
| 				auth[key] = authz[key]; | 				auth[key] = authz[key]; | ||||||
| 			}); | 			}); | ||||||
| 
 | 
 | ||||||
| 			// copy from the challenge we've chosen
 | 			// copy from the challenge we've chosen
 | ||||||
| 			// { type, status, url, token }
 | 			// { type, status, url, token }
 | ||||||
| 			// (note the duplicate status overwrites the one above, but they should be the same)
 | 			// (note the duplicate status overwrites the one above, but they should be the same)
 | ||||||
| 			Object.keys(challenge).forEach(function(key) { | 			Object.keys(challenge).forEach(function (key) { | ||||||
| 				// don't confused devs with the id url
 | 				// don't confused devs with the id url
 | ||||||
| 				auth[key] = challenge[key]; | 				auth[key] = challenge[key]; | ||||||
| 			}); | 			}); | ||||||
| @ -602,19 +602,19 @@ ACME._computeAuths = function(me, options, thumb, authz, zonenames, dryrun) { | |||||||
| 				challenge: auth, | 				challenge: auth, | ||||||
| 				zone: zone, | 				zone: zone, | ||||||
| 				dnsPrefix: dnsPrefix | 				dnsPrefix: dnsPrefix | ||||||
| 			}).then(function(resp) { | 			}).then(function (resp) { | ||||||
| 				Object.keys(resp).forEach(function(k) { | 				Object.keys(resp).forEach(function (k) { | ||||||
| 					auth[k] = resp[k]; | 					auth[k] = resp[k]; | ||||||
| 				}); | 				}); | ||||||
| 				return auth; | 				return auth; | ||||||
| 			}); | 			}); | ||||||
| 		}) | 		}) | ||||||
| 	).then(function(auths) { | 	).then(function (auths) { | ||||||
| 		return auths.filter(Boolean); | 		return auths.filter(Boolean); | ||||||
| 	}); | 	}); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| ACME.computeChallenge = function(opts) { | ACME.computeChallenge = function (opts) { | ||||||
| 	var auth = opts.challenge; | 	var auth = opts.challenge; | ||||||
| 	var hostname = auth.hostname || opts.hostname; | 	var hostname = auth.hostname || opts.hostname; | ||||||
| 	var zone = opts.zone; | 	var zone = opts.zone; | ||||||
| @ -623,7 +623,7 @@ ACME.computeChallenge = function(opts) { | |||||||
| 	var getThumbprint = opts._getThumbprint || ACME._thumber(opts, thumb); | 	var getThumbprint = opts._getThumbprint || ACME._thumber(opts, thumb); | ||||||
| 	var dnsPrefix = opts.dnsPrefix || ACME.challengePrefixes['dns-01']; | 	var dnsPrefix = opts.dnsPrefix || ACME.challengePrefixes['dns-01']; | ||||||
| 
 | 
 | ||||||
| 	return getThumbprint(accountKey).then(function(thumb) { | 	return getThumbprint(accountKey).then(function (thumb) { | ||||||
| 		var resp = {}; | 		var resp = {}; | ||||||
| 		resp.thumbprint = thumb; | 		resp.thumbprint = thumb; | ||||||
| 		//   keyAuthorization = token + '.' + base64url(JWK_Thumbprint(accountKey))
 | 		//   keyAuthorization = token + '.' + base64url(JWK_Thumbprint(accountKey))
 | ||||||
| @ -651,10 +651,10 @@ ACME.computeChallenge = function(opts) { | |||||||
| 		// _as part of_ the decision making process
 | 		// _as part of_ the decision making process
 | ||||||
| 		return sha2 | 		return sha2 | ||||||
| 			.sum(256, resp.keyAuthorization) | 			.sum(256, resp.keyAuthorization) | ||||||
| 			.then(function(hash) { | 			.then(function (hash) { | ||||||
| 				return Enc.bufToUrlBase64(Uint8Array.from(hash)); | 				return Enc.bufToUrlBase64(Uint8Array.from(hash)); | ||||||
| 			}) | 			}) | ||||||
| 			.then(function(hash64) { | 			.then(function (hash64) { | ||||||
| 				resp.dnsHost = dnsPrefix + '.' + hostname; // .replace('*.', '');
 | 				resp.dnsHost = dnsPrefix + '.' + hostname; // .replace('*.', '');
 | ||||||
| 
 | 
 | ||||||
| 				// deprecated
 | 				// deprecated
 | ||||||
| @ -674,7 +674,7 @@ ACME.computeChallenge = function(opts) { | |||||||
| 	}); | 	}); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| ACME._untame = function(name, wild) { | ACME._untame = function (name, wild) { | ||||||
| 	if (wild) { | 	if (wild) { | ||||||
| 		name = '*.' + name.replace('*.', ''); | 		name = '*.' + name.replace('*.', ''); | ||||||
| 	} | 	} | ||||||
| @ -682,7 +682,7 @@ ACME._untame = function(name, wild) { | |||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| // https://tools.ietf.org/html/draft-ietf-acme-acme-10#section-7.5.1
 | // https://tools.ietf.org/html/draft-ietf-acme-acme-10#section-7.5.1
 | ||||||
| ACME._postChallenge = function(me, options, kid, auth) { | ACME._postChallenge = function (me, options, kid, auth) { | ||||||
| 	var RETRY_INTERVAL = me.retryInterval || 1000; | 	var RETRY_INTERVAL = me.retryInterval || 1000; | ||||||
| 	var DEAUTH_INTERVAL = me.deauthWait || 10 * 1000; | 	var DEAUTH_INTERVAL = me.deauthWait || 10 * 1000; | ||||||
| 	var MAX_POLL = me.retryPoll || 8; | 	var MAX_POLL = me.retryPoll || 8; | ||||||
| @ -716,7 +716,7 @@ ACME._postChallenge = function(me, options, kid, auth) { | |||||||
| 			url: auth.url, | 			url: auth.url, | ||||||
| 			protected: { kid: kid }, | 			protected: { kid: kid }, | ||||||
| 			payload: Enc.strToBuf(JSON.stringify({ status: 'deactivated' })) | 			payload: Enc.strToBuf(JSON.stringify({ status: 'deactivated' })) | ||||||
| 		}).then(function(/*#resp*/) { | 		}).then(function (/*#resp*/) { | ||||||
| 			//#console.debug('deactivate challenge: resp.body:');
 | 			//#console.debug('deactivate challenge: resp.body:');
 | ||||||
| 			//#console.debug(resp.body);
 | 			//#console.debug(resp.body);
 | ||||||
| 			return ACME._wait(DEAUTH_INTERVAL); | 			return ACME._wait(DEAUTH_INTERVAL); | ||||||
| @ -777,7 +777,7 @@ ACME._postChallenge = function(me, options, kid, auth) { | |||||||
| 		try { | 		try { | ||||||
| 			options.challenges[auth.type] | 			options.challenges[auth.type] | ||||||
| 				.remove({ challenge: auth }) | 				.remove({ challenge: auth }) | ||||||
| 				.catch(function(err) { | 				.catch(function (err) { | ||||||
| 					err.action = 'challenge_remove'; | 					err.action = 'challenge_remove'; | ||||||
| 					err.altname = auth.altname; | 					err.altname = auth.altname; | ||||||
| 					err.type = auth.type; | 					err.type = auth.type; | ||||||
| @ -858,7 +858,7 @@ ACME._postChallenge = function(me, options, kid, auth) { | |||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| // options = { domains, claims, challenges }
 | // options = { domains, claims, challenges }
 | ||||||
| ACME._setChallenges = function(me, options, order) { | ACME._setChallenges = function (me, options, order) { | ||||||
| 	var claims = order._claims.slice(0); | 	var claims = order._claims.slice(0); | ||||||
| 	var valids = []; | 	var valids = []; | ||||||
| 	var auths = []; | 	var auths = []; | ||||||
| @ -875,11 +875,11 @@ ACME._setChallenges = function(me, options, order) { | |||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		return Promise.resolve() | 		return Promise.resolve() | ||||||
| 			.then(function() { | 			.then(function () { | ||||||
| 				// For any challenges that are already valid,
 | 				// For any challenges that are already valid,
 | ||||||
| 				// add to the list and skip any checks.
 | 				// add to the list and skip any checks.
 | ||||||
| 				if ( | 				if ( | ||||||
| 					claim.challenges.some(function(ch) { | 					claim.challenges.some(function (ch) { | ||||||
| 						if ('valid' === ch.status) { | 						if ('valid' === ch.status) { | ||||||
| 							valids.push(ch); | 							valids.push(ch); | ||||||
| 							return true; | 							return true; | ||||||
| @ -959,7 +959,7 @@ ACME._setChallenges = function(me, options, order) { | |||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		return ACME.challengeTests[auth.type](me, { challenge: auth }) | 		return ACME.challengeTests[auth.type](me, { challenge: auth }) | ||||||
| 			.then(function() { | 			.then(function () { | ||||||
| 				valids.push(auth); | 				valids.push(auth); | ||||||
| 			}) | 			}) | ||||||
| 			.then(checkNext); | 			.then(checkNext); | ||||||
| @ -968,7 +968,7 @@ ACME._setChallenges = function(me, options, order) { | |||||||
| 	function removeAll(ch) { | 	function removeAll(ch) { | ||||||
| 		options.challenges[ch.type] | 		options.challenges[ch.type] | ||||||
| 			.remove({ challenge: ch }) | 			.remove({ challenge: ch }) | ||||||
| 			.catch(function(err) { | 			.catch(function (err) { | ||||||
| 				err.action = 'challenge_remove'; | 				err.action = 'challenge_remove'; | ||||||
| 				err.altname = ch.altname; | 				err.altname = ch.altname; | ||||||
| 				err.type = ch.type; | 				err.type = ch.type; | ||||||
| @ -981,7 +981,7 @@ ACME._setChallenges = function(me, options, order) { | |||||||
| 	return setNext() | 	return setNext() | ||||||
| 		.then(waitAll) | 		.then(waitAll) | ||||||
| 		.then(checkNext) | 		.then(checkNext) | ||||||
| 		.catch(function(err) { | 		.catch(function (err) { | ||||||
| 			if (!options.debug) { | 			if (!options.debug) { | ||||||
| 				placed.forEach(removeAll); | 				placed.forEach(removeAll); | ||||||
| 			} | 			} | ||||||
| @ -989,7 +989,7 @@ ACME._setChallenges = function(me, options, order) { | |||||||
| 		}); | 		}); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| ACME._presentChallenges = function(me, options, kid, readyToPresent) { | ACME._presentChallenges = function (me, options, kid, readyToPresent) { | ||||||
| 	// Actually sets the challenge via ACME
 | 	// Actually sets the challenge via ACME
 | ||||||
| 	function challengeNext() { | 	function challengeNext() { | ||||||
| 		// First set, First presented
 | 		// First set, First presented
 | ||||||
| @ -1002,12 +1002,12 @@ ACME._presentChallenges = function(me, options, kid, readyToPresent) { | |||||||
| 
 | 
 | ||||||
| 	// BTW, these are done serially rather than parallel on purpose
 | 	// BTW, these are done serially rather than parallel on purpose
 | ||||||
| 	// (rate limits, propagation delays, etc)
 | 	// (rate limits, propagation delays, etc)
 | ||||||
| 	return challengeNext().then(function() { | 	return challengeNext().then(function () { | ||||||
| 		return readyToPresent; | 		return readyToPresent; | ||||||
| 	}); | 	}); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| ACME._pollOrderStatus = function(me, options, kid, order, verifieds) { | ACME._pollOrderStatus = function (me, options, kid, order, verifieds) { | ||||||
| 	var csr64 = ACME._csrToUrlBase64(options.csr); | 	var csr64 = ACME._csrToUrlBase64(options.csr); | ||||||
| 	var body = { csr: csr64 }; | 	var body = { csr: csr64 }; | ||||||
| 	var payload = JSON.stringify(body); | 	var payload = JSON.stringify(body); | ||||||
| @ -1019,7 +1019,7 @@ ACME._pollOrderStatus = function(me, options, kid, order, verifieds) { | |||||||
| 			url: order._finalizeUrl, | 			url: order._finalizeUrl, | ||||||
| 			protected: { kid: kid }, | 			protected: { kid: kid }, | ||||||
| 			payload: Enc.strToBuf(payload) | 			payload: Enc.strToBuf(payload) | ||||||
| 		}).then(function(resp) { | 		}).then(function (resp) { | ||||||
| 			ACME._notify(me, options, 'certificate_status', { | 			ACME._notify(me, options, 'certificate_status', { | ||||||
| 				subject: options.domains[0], | 				subject: options.domains[0], | ||||||
| 				status: resp.body.status | 				status: resp.body.status | ||||||
| @ -1081,7 +1081,7 @@ ACME._pollOrderStatus = function(me, options, kid, order, verifieds) { | |||||||
| 	return pollCert(); | 	return pollCert(); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| ACME._redeemCert = function(me, options, kid, voucher) { | ACME._redeemCert = function (me, options, kid, voucher) { | ||||||
| 	//#console.debug('ACME.js: order was finalized');
 | 	//#console.debug('ACME.js: order was finalized');
 | ||||||
| 
 | 
 | ||||||
| 	// POST-as-GET
 | 	// POST-as-GET
 | ||||||
| @ -1091,7 +1091,7 @@ ACME._redeemCert = function(me, options, kid, voucher) { | |||||||
| 		protected: { kid: kid }, | 		protected: { kid: kid }, | ||||||
| 		payload: Enc.binToBuf(''), | 		payload: Enc.binToBuf(''), | ||||||
| 		json: true | 		json: true | ||||||
| 	}).then(function(resp) { | 	}).then(function (resp) { | ||||||
| 		//#console.debug('ACME.js: csr submitted and cert received:');
 | 		//#console.debug('ACME.js: csr submitted and cert received:');
 | ||||||
| 
 | 
 | ||||||
| 		// https://github.com/certbot/certbot/issues/5721
 | 		// https://github.com/certbot/certbot/issues/5721
 | ||||||
| @ -1110,12 +1110,12 @@ ACME._redeemCert = function(me, options, kid, voucher) { | |||||||
| 	}); | 	}); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| ACME._finalizeOrder = function(me, options, kid, order) { | ACME._finalizeOrder = function (me, options, kid, order) { | ||||||
| 	//#console.debug('[ACME.js] finalizeOrder:');
 | 	//#console.debug('[ACME.js] finalizeOrder:');
 | ||||||
| 	var readyToPresent; | 	var readyToPresent; | ||||||
| 	return A._getAccountKid(me, options).then(function(kid) { | 	return A._getAccountKid(me, options).then(function (kid) { | ||||||
| 		return ACME._setChallenges(me, options, order) | 		return ACME._setChallenges(me, options, order) | ||||||
| 			.then(function(_readyToPresent) { | 			.then(function (_readyToPresent) { | ||||||
| 				readyToPresent = _readyToPresent; | 				readyToPresent = _readyToPresent; | ||||||
| 				return ACME._presentChallenges( | 				return ACME._presentChallenges( | ||||||
| 					me, | 					me, | ||||||
| @ -1124,28 +1124,28 @@ ACME._finalizeOrder = function(me, options, kid, order) { | |||||||
| 					readyToPresent | 					readyToPresent | ||||||
| 				); | 				); | ||||||
| 			}) | 			}) | ||||||
| 			.then(function() { | 			.then(function () { | ||||||
| 				return ACME._pollOrderStatus( | 				return ACME._pollOrderStatus( | ||||||
| 					me, | 					me, | ||||||
| 					options, | 					options, | ||||||
| 					kid, | 					kid, | ||||||
| 					order, | 					order, | ||||||
| 					readyToPresent.map(function(ch) { | 					readyToPresent.map(function (ch) { | ||||||
| 						return ACME._untame(ch.identifier.value, ch.wildcard); | 						return ACME._untame(ch.identifier.value, ch.wildcard); | ||||||
| 					}) | 					}) | ||||||
| 				); | 				); | ||||||
| 			}) | 			}) | ||||||
| 			.then(function(voucher) { | 			.then(function (voucher) { | ||||||
| 				return ACME._redeemCert(me, options, kid, voucher); | 				return ACME._redeemCert(me, options, kid, voucher); | ||||||
| 			}); | 			}); | ||||||
| 	}); | 	}); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| // Order a certificate request with all domains
 | // Order a certificate request with all domains
 | ||||||
| ACME._orderCert = function(me, options, kid) { | ACME._orderCert = function (me, options, kid) { | ||||||
| 	var certificateRequest = { | 	var certificateRequest = { | ||||||
| 		// raw wildcard syntax MUST be used here
 | 		// raw wildcard syntax MUST be used here
 | ||||||
| 		identifiers: options.domains.map(function(hostname) { | 		identifiers: options.domains.map(function (hostname) { | ||||||
| 			return { type: 'dns', value: hostname }; | 			return { type: 'dns', value: hostname }; | ||||||
| 		}) | 		}) | ||||||
| 		//, "notBefore": "2016-01-01T00:00:00Z"
 | 		//, "notBefore": "2016-01-01T00:00:00Z"
 | ||||||
| @ -1153,10 +1153,10 @@ ACME._orderCert = function(me, options, kid) { | |||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 	return ACME._prepRequest(me, options) | 	return ACME._prepRequest(me, options) | ||||||
| 		.then(function() { | 		.then(function () { | ||||||
| 			return ACME._getZones(me, options.challenges, options.domains); | 			return ACME._getZones(me, options.challenges, options.domains); | ||||||
| 		}) | 		}) | ||||||
| 		.then(function(zonenames) { | 		.then(function (zonenames) { | ||||||
| 			var p; | 			var p; | ||||||
| 			// Do a little dry-run / self-test
 | 			// Do a little dry-run / self-test
 | ||||||
| 			if (!me.skipDryRun && !options.skipDryRun) { | 			if (!me.skipDryRun && !options.skipDryRun) { | ||||||
| @ -1165,9 +1165,9 @@ ACME._orderCert = function(me, options, kid) { | |||||||
| 				p = Promise.resolve(null); | 				p = Promise.resolve(null); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			return p.then(function() { | 			return p.then(function () { | ||||||
| 				return A._getAccountKid(me, options) | 				return A._getAccountKid(me, options) | ||||||
| 					.then(function(kid) { | 					.then(function (kid) { | ||||||
| 						ACME._notify(me, options, 'certificate_order', { | 						ACME._notify(me, options, 'certificate_order', { | ||||||
| 							// API-locked
 | 							// API-locked
 | ||||||
| 							account: { key: { kid: kid } }, | 							account: { key: { kid: kid } }, | ||||||
| @ -1185,7 +1185,7 @@ ACME._orderCert = function(me, options, kid) { | |||||||
| 							payload: Enc.binToBuf(payload) | 							payload: Enc.binToBuf(payload) | ||||||
| 						}); | 						}); | ||||||
| 					}) | 					}) | ||||||
| 					.then(function(resp) { | 					.then(function (resp) { | ||||||
| 						var order = resp.body; | 						var order = resp.body; | ||||||
| 						order._orderUrl = resp.headers.location; | 						order._orderUrl = resp.headers.location; | ||||||
| 						order._finalizeUrl = resp.body.finalize; | 						order._finalizeUrl = resp.body.finalize; | ||||||
| @ -1201,14 +1201,14 @@ ACME._orderCert = function(me, options, kid) { | |||||||
| 
 | 
 | ||||||
| 						return order; | 						return order; | ||||||
| 					}) | 					}) | ||||||
| 					.then(function(order) { | 					.then(function (order) { | ||||||
| 						return ACME._getAllChallenges( | 						return ACME._getAllChallenges( | ||||||
| 							me, | 							me, | ||||||
| 							options, | 							options, | ||||||
| 							kid, | 							kid, | ||||||
| 							zonenames, | 							zonenames, | ||||||
| 							order | 							order | ||||||
| 						).then(function(claims) { | 						).then(function (claims) { | ||||||
| 							order._claims = claims; | 							order._claims = claims; | ||||||
| 							return order; | 							return order; | ||||||
| 						}); | 						}); | ||||||
| @ -1217,8 +1217,8 @@ ACME._orderCert = function(me, options, kid) { | |||||||
| 		}); | 		}); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| ACME._prepRequest = function(me, options) { | ACME._prepRequest = function (me, options) { | ||||||
| 	return Promise.resolve().then(function() { | 	return Promise.resolve().then(function () { | ||||||
| 		// TODO check that all presenterTypes are represented in challenges
 | 		// TODO check that all presenterTypes are represented in challenges
 | ||||||
| 		if (!options._presenterTypes.length) { | 		if (!options._presenterTypes.length) { | ||||||
| 			return Promise.reject( | 			return Promise.reject( | ||||||
| @ -1236,14 +1236,8 @@ ACME._prepRequest = function(me, options) { | |||||||
| 		options.domains = options.domains || _csr.altnames; | 		options.domains = options.domains || _csr.altnames; | ||||||
| 		_csr.altnames = _csr.altnames || []; | 		_csr.altnames = _csr.altnames || []; | ||||||
| 		if ( | 		if ( | ||||||
| 			options.domains | 			options.domains.slice(0).sort().join(' ') !== | ||||||
| 				.slice(0) | 			_csr.altnames.slice(0).sort().join(' ') | ||||||
| 				.sort() |  | ||||||
| 				.join(' ') !== |  | ||||||
| 			_csr.altnames |  | ||||||
| 				.slice(0) |  | ||||||
| 				.sort() |  | ||||||
| 				.join(' ') |  | ||||||
| 		) { | 		) { | ||||||
| 			return Promise.reject( | 			return Promise.reject( | ||||||
| 				new Error('certificate altnames do not match requested domains') | 				new Error('certificate altnames do not match requested domains') | ||||||
| @ -1266,7 +1260,7 @@ ACME._prepRequest = function(me, options) { | |||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		// a cheap check to see if there are non-ascii characters in any of the domains
 | 		// a cheap check to see if there are non-ascii characters in any of the domains
 | ||||||
| 		var nonAsciiDomains = options.domains.some(function(d) { | 		var nonAsciiDomains = options.domains.some(function (d) { | ||||||
| 			// IDN / unicode / utf-8 / punycode
 | 			// IDN / unicode / utf-8 / punycode
 | ||||||
| 			return Enc.strToBin(d) !== d; | 			return Enc.strToBin(d) !== d; | ||||||
| 		}); | 		}); | ||||||
| @ -1277,7 +1271,7 @@ ACME._prepRequest = function(me, options) { | |||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		// TODO Promise.all()?
 | 		// TODO Promise.all()?
 | ||||||
| 		(options._presenterTypes || []).forEach(function(key) { | 		(options._presenterTypes || []).forEach(function (key) { | ||||||
| 			var presenter = options.challenges[key]; | 			var presenter = options.challenges[key]; | ||||||
| 			if ( | 			if ( | ||||||
| 				'function' === typeof presenter.init && | 				'function' === typeof presenter.init && | ||||||
| @ -1291,7 +1285,7 @@ ACME._prepRequest = function(me, options) { | |||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| // Request a challenge for each authorization in the order
 | // Request a challenge for each authorization in the order
 | ||||||
| ACME._getAllChallenges = function(me, options, kid, zonenames, order) { | ACME._getAllChallenges = function (me, options, kid, zonenames, order) { | ||||||
| 	var claims = []; | 	var claims = []; | ||||||
| 	//#console.debug("[acme-v2] POST newOrder has authorizations");
 | 	//#console.debug("[acme-v2] POST newOrder has authorizations");
 | ||||||
| 	var challengeAuths = order.authorizations.slice(0); | 	var challengeAuths = order.authorizations.slice(0); | ||||||
| @ -1308,14 +1302,14 @@ ACME._getAllChallenges = function(me, options, kid, zonenames, order) { | |||||||
| 			kid, | 			kid, | ||||||
| 			zonenames, | 			zonenames, | ||||||
| 			authUrl | 			authUrl | ||||||
| 		).then(function(claim) { | 		).then(function (claim) { | ||||||
| 			// var domain = options.domains[i]; // claim.identifier.value
 | 			// var domain = options.domains[i]; // claim.identifier.value
 | ||||||
| 			claims.push(claim); | 			claims.push(claim); | ||||||
| 			return getNext(); | 			return getNext(); | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return getNext().then(function() { | 	return getNext().then(function () { | ||||||
| 		return claims; | 		return claims; | ||||||
| 	}); | 	}); | ||||||
| }; | }; | ||||||
| @ -1333,12 +1327,12 @@ ACME.splitPemChain = function splitPemChain(str) { | |||||||
| 	return str | 	return str | ||||||
| 		.trim() | 		.trim() | ||||||
| 		.split(/[\r\n]{2,}/g) | 		.split(/[\r\n]{2,}/g) | ||||||
| 		.map(function(str) { | 		.map(function (str) { | ||||||
| 			return str + '\n'; | 			return str + '\n'; | ||||||
| 		}); | 		}); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| ACME._csrToUrlBase64 = function(csr) { | ACME._csrToUrlBase64 = function (csr) { | ||||||
| 	// if der, convert to base64
 | 	// if der, convert to base64
 | ||||||
| 	if ('string' !== typeof csr) { | 	if ('string' !== typeof csr) { | ||||||
| 		csr = Enc.bufToUrlBase64(csr); | 		csr = Enc.bufToUrlBase64(csr); | ||||||
| @ -1347,21 +1341,16 @@ ACME._csrToUrlBase64 = function(csr) { | |||||||
| 	// TODO use PEM.parseBlock()
 | 	// TODO use PEM.parseBlock()
 | ||||||
| 	// nix PEM headers, if any
 | 	// nix PEM headers, if any
 | ||||||
| 	if ('-' === csr[0]) { | 	if ('-' === csr[0]) { | ||||||
| 		csr = csr | 		csr = csr.split(/\n+/).slice(1, -1).join(''); | ||||||
| 			.split(/\n+/) |  | ||||||
| 			.slice(1, -1) |  | ||||||
| 			.join(''); |  | ||||||
| 	} | 	} | ||||||
| 	return Enc.base64ToUrlBase64(csr.trim().replace(/\s+/g, '')); | 	return Enc.base64ToUrlBase64(csr.trim().replace(/\s+/g, '')); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| // In v8 this is crypto random, but we're just using it for pseudorandom
 | // In v8 this is crypto random, but we're just using it for pseudorandom
 | ||||||
| ACME._prnd = function(n) { | ACME._prnd = function (n) { | ||||||
| 	var rnd = ''; | 	var rnd = ''; | ||||||
| 	while (rnd.length / 2 < n) { | 	while (rnd.length / 2 < n) { | ||||||
| 		var i = Math.random() | 		var i = Math.random().toString().substr(2); | ||||||
| 			.toString() |  | ||||||
| 			.substr(2); |  | ||||||
| 		var h = parseInt(i, 10).toString(16); | 		var h = parseInt(i, 10).toString(16); | ||||||
| 		if (h.length % 2) { | 		if (h.length % 2) { | ||||||
| 			h = '0' + h; | 			h = '0' + h; | ||||||
| @ -1371,7 +1360,7 @@ ACME._prnd = function(n) { | |||||||
| 	return rnd.substr(0, n * 2); | 	return rnd.substr(0, n * 2); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| ACME._notify = function(me, options, ev, params) { | ACME._notify = function (me, options, ev, params) { | ||||||
| 	if (!options.notify && !me.notify) { | 	if (!options.notify && !me.notify) { | ||||||
| 		//console.info(ev, params);
 | 		//console.info(ev, params);
 | ||||||
| 		return; | 		return; | ||||||
| @ -1385,7 +1374,7 @@ ACME._notify = function(me, options, ev, params) { | |||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| ACME._wait = function wait(ms) { | ACME._wait = function wait(ms) { | ||||||
| 	return new Promise(function(resolve) { | 	return new Promise(function (resolve) { | ||||||
| 		setTimeout(resolve, ms || 1100); | 		setTimeout(resolve, ms || 1100); | ||||||
| 	}); | 	}); | ||||||
| }; | }; | ||||||
| @ -1402,12 +1391,12 @@ function newZoneRegExp(zonename) { | |||||||
| 
 | 
 | ||||||
| function pluckZone(zonenames, dnsHost) { | function pluckZone(zonenames, dnsHost) { | ||||||
| 	return zonenames | 	return zonenames | ||||||
| 		.filter(function(zonename) { | 		.filter(function (zonename) { | ||||||
| 			// the only character that needs to be escaped for regex
 | 			// the only character that needs to be escaped for regex
 | ||||||
| 			// and is allowed in a domain name is '.'
 | 			// and is allowed in a domain name is '.'
 | ||||||
| 			return newZoneRegExp(zonename).test(dnsHost); | 			return newZoneRegExp(zonename).test(dnsHost); | ||||||
| 		}) | 		}) | ||||||
| 		.sort(function(a, b) { | 		.sort(function (a, b) { | ||||||
| 			// longest match first
 | 			// longest match first
 | ||||||
| 			return b.length - a.length; | 			return b.length - a.length; | ||||||
| 		})[0]; | 		})[0]; | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| #!/usr/bin/env node
 | #!/usr/bin/env node
 | ||||||
| (async function() { | (async function () { | ||||||
| 	'use strict'; | 	'use strict'; | ||||||
| 
 | 
 | ||||||
| 	var UglifyJS = require('uglify-js'); | 	var UglifyJS = require('uglify-js'); | ||||||
| @ -22,7 +22,7 @@ | |||||||
| 			'../lib/asn1-parser.js', | 			'../lib/asn1-parser.js', | ||||||
| 			'../lib/csr.js', | 			'../lib/csr.js', | ||||||
| 			'../lib/acme.js' | 			'../lib/acme.js' | ||||||
| 		].map(async function(file) { | 		].map(async function (file) { | ||||||
| 			return (await readFile(path.join(__dirname, file), 'utf8')).trim(); | 			return (await readFile(path.join(__dirname, file), 'utf8')).trim(); | ||||||
| 		}) | 		}) | ||||||
| 	); | 	); | ||||||
|  | |||||||
							
								
								
									
										12
									
								
								errors.js
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								errors.js
									
									
									
									
									
								
							| @ -2,13 +2,13 @@ | |||||||
| 
 | 
 | ||||||
| var E = module.exports; | var E = module.exports; | ||||||
| 
 | 
 | ||||||
| E.NO_SUITABLE_CHALLENGE = function(domain, challenges, presenters) { | E.NO_SUITABLE_CHALLENGE = function (domain, challenges, presenters) { | ||||||
| 	// Bail with a descriptive message if no usable challenge could be selected
 | 	// Bail with a descriptive message if no usable challenge could be selected
 | ||||||
| 	// For example, wildcards require dns-01 and, if we don't have that, we have to bail
 | 	// For example, wildcards require dns-01 and, if we don't have that, we have to bail
 | ||||||
| 	var enabled = presenters.join(', ') || 'none'; | 	var enabled = presenters.join(', ') || 'none'; | ||||||
| 	var suitable = | 	var suitable = | ||||||
| 		challenges | 		challenges | ||||||
| 			.map(function(r) { | 			.map(function (r) { | ||||||
| 				return r.type; | 				return r.type; | ||||||
| 			}) | 			}) | ||||||
| 			.join(', ') || 'none'; | 			.join(', ') || 'none'; | ||||||
| @ -24,7 +24,7 @@ E.NO_SUITABLE_CHALLENGE = function(domain, challenges, presenters) { | |||||||
| 			' ).' | 			' ).' | ||||||
| 	); | 	); | ||||||
| }; | }; | ||||||
| E.UNHANDLED_ORDER_STATUS = function(options, domains, resp) { | E.UNHANDLED_ORDER_STATUS = function (options, domains, resp) { | ||||||
| 	return new Error( | 	return new Error( | ||||||
| 		"Didn't finalize order: Unhandled status '" + | 		"Didn't finalize order: Unhandled status '" + | ||||||
| 			resp.body.status + | 			resp.body.status + | ||||||
| @ -41,7 +41,7 @@ E.UNHANDLED_ORDER_STATUS = function(options, domains, resp) { | |||||||
| 			'Please open an issue at https://git.rootprojects.org/root/acme.js' | 			'Please open an issue at https://git.rootprojects.org/root/acme.js' | ||||||
| 	); | 	); | ||||||
| }; | }; | ||||||
| E.DOUBLE_READY_ORDER = function(options, domains, resp) { | E.DOUBLE_READY_ORDER = function (options, domains, resp) { | ||||||
| 	return new Error( | 	return new Error( | ||||||
| 		"Did not finalize order: status 'ready'." + | 		"Did not finalize order: status 'ready'." + | ||||||
| 			" Hmmm... this state shouldn't be possible here. That was the last state." + | 			" Hmmm... this state shouldn't be possible here. That was the last state." + | ||||||
| @ -57,7 +57,7 @@ E.DOUBLE_READY_ORDER = function(options, domains, resp) { | |||||||
| 			'Please open an issue at https://git.rootprojects.org/root/acme.js' | 			'Please open an issue at https://git.rootprojects.org/root/acme.js' | ||||||
| 	); | 	); | ||||||
| }; | }; | ||||||
| E.ORDER_INVALID = function(options, domains, resp) { | E.ORDER_INVALID = function (options, domains, resp) { | ||||||
| 	return new Error( | 	return new Error( | ||||||
| 		"Did not finalize order: status 'invalid'." + | 		"Did not finalize order: status 'invalid'." + | ||||||
| 			' Best guess: One or more of the domain challenges could not be verified' + | 			' Best guess: One or more of the domain challenges could not be verified' + | ||||||
| @ -71,7 +71,7 @@ E.ORDER_INVALID = function(options, domains, resp) { | |||||||
| 			JSON.stringify(resp.body, null, 2) | 			JSON.stringify(resp.body, null, 2) | ||||||
| 	); | 	); | ||||||
| }; | }; | ||||||
| E.NO_AUTHORIZATIONS = function(options, resp) { | E.NO_AUTHORIZATIONS = function (options, resp) { | ||||||
| 	return new Error( | 	return new Error( | ||||||
| 		"[acme-v2.js] authorizations were not fetched for '" + | 		"[acme-v2.js] authorizations were not fetched for '" + | ||||||
| 			options.domains.join() + | 			options.domains.join() + | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| /*global Promise*/ | /*global Promise*/ | ||||||
| (function() { | (function () { | ||||||
| 	'use strict'; | 	'use strict'; | ||||||
| 
 | 
 | ||||||
| 	var Keypairs = require('@root/keypairs'); | 	var Keypairs = require('@root/keypairs'); | ||||||
| @ -29,8 +29,8 @@ | |||||||
| 		console.log('hello'); | 		console.log('hello'); | ||||||
| 
 | 
 | ||||||
| 		// Show different options for ECDSA vs RSA
 | 		// Show different options for ECDSA vs RSA
 | ||||||
| 		$$('input[name="kty"]').forEach(function($el) { | 		$$('input[name="kty"]').forEach(function ($el) { | ||||||
| 			$el.addEventListener('change', function(ev) { | 			$el.addEventListener('change', function (ev) { | ||||||
| 				console.log(this); | 				console.log(this); | ||||||
| 				console.log(ev); | 				console.log(ev); | ||||||
| 				if ('RSA' === ev.target.value) { | 				if ('RSA' === ev.target.value) { | ||||||
| @ -44,20 +44,20 @@ | |||||||
| 		}); | 		}); | ||||||
| 
 | 
 | ||||||
| 		// Generate a key on submit
 | 		// Generate a key on submit
 | ||||||
| 		$('form.js-keygen').addEventListener('submit', function(ev) { | 		$('form.js-keygen').addEventListener('submit', function (ev) { | ||||||
| 			ev.preventDefault(); | 			ev.preventDefault(); | ||||||
| 			ev.stopPropagation(); | 			ev.stopPropagation(); | ||||||
| 			$('.js-loading').hidden = false; | 			$('.js-loading').hidden = false; | ||||||
| 			$('.js-jwk').hidden = true; | 			$('.js-jwk').hidden = true; | ||||||
| 			$('.js-toc-der-public').hidden = true; | 			$('.js-toc-der-public').hidden = true; | ||||||
| 			$('.js-toc-der-private').hidden = true; | 			$('.js-toc-der-private').hidden = true; | ||||||
| 			$$('.js-toc-pem').forEach(function($el) { | 			$$('.js-toc-pem').forEach(function ($el) { | ||||||
| 				$el.hidden = true; | 				$el.hidden = true; | ||||||
| 			}); | 			}); | ||||||
| 			$$('input').map(function($el) { | 			$$('input').map(function ($el) { | ||||||
| 				$el.disabled = true; | 				$el.disabled = true; | ||||||
| 			}); | 			}); | ||||||
| 			$$('button').map(function($el) { | 			$$('button').map(function ($el) { | ||||||
| 				$el.disabled = true; | 				$el.disabled = true; | ||||||
| 			}); | 			}); | ||||||
| 			var opts = { | 			var opts = { | ||||||
| @ -67,7 +67,7 @@ | |||||||
| 			}; | 			}; | ||||||
| 			var then = Date.now(); | 			var then = Date.now(); | ||||||
| 			console.log('opts', opts); | 			console.log('opts', opts); | ||||||
| 			Keypairs.generate(opts).then(function(results) { | 			Keypairs.generate(opts).then(function (results) { | ||||||
| 				console.log('Key generation time:', Date.now() - then + 'ms'); | 				console.log('Key generation time:', Date.now() - then + 'ms'); | ||||||
| 				var pubDer; | 				var pubDer; | ||||||
| 				var privDer; | 				var privDer; | ||||||
| @ -77,19 +77,19 @@ | |||||||
| 					Eckles.export({ | 					Eckles.export({ | ||||||
| 						jwk: results.private, | 						jwk: results.private, | ||||||
| 						format: 'sec1' | 						format: 'sec1' | ||||||
| 					}).then(function(pem) { | 					}).then(function (pem) { | ||||||
| 						$('.js-input-pem-sec1-private').innerText = pem; | 						$('.js-input-pem-sec1-private').innerText = pem; | ||||||
| 						$('.js-toc-pem-sec1-private').hidden = false; | 						$('.js-toc-pem-sec1-private').hidden = false; | ||||||
| 					}); | 					}); | ||||||
| 					Eckles.export({ | 					Eckles.export({ | ||||||
| 						jwk: results.private, | 						jwk: results.private, | ||||||
| 						format: 'pkcs8' | 						format: 'pkcs8' | ||||||
| 					}).then(function(pem) { | 					}).then(function (pem) { | ||||||
| 						$('.js-input-pem-pkcs8-private').innerText = pem; | 						$('.js-input-pem-pkcs8-private').innerText = pem; | ||||||
| 						$('.js-toc-pem-pkcs8-private').hidden = false; | 						$('.js-toc-pem-pkcs8-private').hidden = false; | ||||||
| 					}); | 					}); | ||||||
| 					Eckles.export({ jwk: results.public, public: true }).then( | 					Eckles.export({ jwk: results.public, public: true }).then( | ||||||
| 						function(pem) { | 						function (pem) { | ||||||
| 							$('.js-input-pem-spki-public').innerText = pem; | 							$('.js-input-pem-spki-public').innerText = pem; | ||||||
| 							$('.js-toc-pem-spki-public').hidden = false; | 							$('.js-toc-pem-spki-public').hidden = false; | ||||||
| 						} | 						} | ||||||
| @ -100,25 +100,25 @@ | |||||||
| 					Rasha.export({ | 					Rasha.export({ | ||||||
| 						jwk: results.private, | 						jwk: results.private, | ||||||
| 						format: 'pkcs1' | 						format: 'pkcs1' | ||||||
| 					}).then(function(pem) { | 					}).then(function (pem) { | ||||||
| 						$('.js-input-pem-pkcs1-private').innerText = pem; | 						$('.js-input-pem-pkcs1-private').innerText = pem; | ||||||
| 						$('.js-toc-pem-pkcs1-private').hidden = false; | 						$('.js-toc-pem-pkcs1-private').hidden = false; | ||||||
| 					}); | 					}); | ||||||
| 					Rasha.export({ | 					Rasha.export({ | ||||||
| 						jwk: results.private, | 						jwk: results.private, | ||||||
| 						format: 'pkcs8' | 						format: 'pkcs8' | ||||||
| 					}).then(function(pem) { | 					}).then(function (pem) { | ||||||
| 						$('.js-input-pem-pkcs8-private').innerText = pem; | 						$('.js-input-pem-pkcs8-private').innerText = pem; | ||||||
| 						$('.js-toc-pem-pkcs8-private').hidden = false; | 						$('.js-toc-pem-pkcs8-private').hidden = false; | ||||||
| 					}); | 					}); | ||||||
| 					Rasha.export({ jwk: results.public, format: 'pkcs1' }).then( | 					Rasha.export({ jwk: results.public, format: 'pkcs1' }).then( | ||||||
| 						function(pem) { | 						function (pem) { | ||||||
| 							$('.js-input-pem-pkcs1-public').innerText = pem; | 							$('.js-input-pem-pkcs1-public').innerText = pem; | ||||||
| 							$('.js-toc-pem-pkcs1-public').hidden = false; | 							$('.js-toc-pem-pkcs1-public').hidden = false; | ||||||
| 						} | 						} | ||||||
| 					); | 					); | ||||||
| 					Rasha.export({ jwk: results.public, format: 'spki' }).then( | 					Rasha.export({ jwk: results.public, format: 'spki' }).then( | ||||||
| 						function(pem) { | 						function (pem) { | ||||||
| 							$('.js-input-pem-spki-public').innerText = pem; | 							$('.js-input-pem-spki-public').innerText = pem; | ||||||
| 							$('.js-toc-pem-spki-public').hidden = false; | 							$('.js-toc-pem-spki-public').hidden = false; | ||||||
| 						} | 						} | ||||||
| @ -132,10 +132,10 @@ | |||||||
| 				$('.js-jwk').innerText = JSON.stringify(results, null, 2); | 				$('.js-jwk').innerText = JSON.stringify(results, null, 2); | ||||||
| 				$('.js-loading').hidden = true; | 				$('.js-loading').hidden = true; | ||||||
| 				$('.js-jwk').hidden = false; | 				$('.js-jwk').hidden = false; | ||||||
| 				$$('input').map(function($el) { | 				$$('input').map(function ($el) { | ||||||
| 					$el.disabled = false; | 					$el.disabled = false; | ||||||
| 				}); | 				}); | ||||||
| 				$$('button').map(function($el) { | 				$$('button').map(function ($el) { | ||||||
| 					$el.disabled = false; | 					$el.disabled = false; | ||||||
| 				}); | 				}); | ||||||
| 				$('.js-toc-jwk').hidden = false; | 				$('.js-toc-jwk').hidden = false; | ||||||
| @ -145,7 +145,7 @@ | |||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
| 
 | 
 | ||||||
| 		$('form.js-acme-account').addEventListener('submit', function(ev) { | 		$('form.js-acme-account').addEventListener('submit', function (ev) { | ||||||
| 			ev.preventDefault(); | 			ev.preventDefault(); | ||||||
| 			ev.stopPropagation(); | 			ev.stopPropagation(); | ||||||
| 			$('.js-loading').hidden = false; | 			$('.js-loading').hidden = false; | ||||||
| @ -155,7 +155,7 @@ | |||||||
| 			}); | 			}); | ||||||
| 			acme.init( | 			acme.init( | ||||||
| 				'https://acme-staging-v02.api.letsencrypt.org/directory' | 				'https://acme-staging-v02.api.letsencrypt.org/directory' | ||||||
| 			).then(function(result) { | 			).then(function (result) { | ||||||
| 				console.log('acme result', result); | 				console.log('acme result', result); | ||||||
| 				var privJwk = JSON.parse($('.js-jwk').innerText).private; | 				var privJwk = JSON.parse($('.js-jwk').innerText).private; | ||||||
| 				var email = $('.js-email').value; | 				var email = $('.js-email').value; | ||||||
| @ -165,7 +165,7 @@ | |||||||
| 						agreeToTerms: checkTos, | 						agreeToTerms: checkTos, | ||||||
| 						accountKeypair: { privateKeyJwk: privJwk } | 						accountKeypair: { privateKeyJwk: privJwk } | ||||||
| 					}) | 					}) | ||||||
| 					.then(function(account) { | 					.then(function (account) { | ||||||
| 						console.log('account created result:', account); | 						console.log('account created result:', account); | ||||||
| 						accountStuff.account = account; | 						accountStuff.account = account; | ||||||
| 						accountStuff.privateJwk = privJwk; | 						accountStuff.privateJwk = privJwk; | ||||||
| @ -177,7 +177,7 @@ | |||||||
| 							'.js-acme-account-response' | 							'.js-acme-account-response' | ||||||
| 						).innerText = JSON.stringify(account, null, 2); | 						).innerText = JSON.stringify(account, null, 2); | ||||||
| 					}) | 					}) | ||||||
| 					.catch(function(err) { | 					.catch(function (err) { | ||||||
| 						console.error('A bad thing happened:'); | 						console.error('A bad thing happened:'); | ||||||
| 						console.error(err); | 						console.error(err); | ||||||
| 						window.alert( | 						window.alert( | ||||||
| @ -187,13 +187,13 @@ | |||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
| 
 | 
 | ||||||
| 		$('form.js-csr').addEventListener('submit', function(ev) { | 		$('form.js-csr').addEventListener('submit', function (ev) { | ||||||
| 			ev.preventDefault(); | 			ev.preventDefault(); | ||||||
| 			ev.stopPropagation(); | 			ev.stopPropagation(); | ||||||
| 			generateCsr(); | 			generateCsr(); | ||||||
| 		}); | 		}); | ||||||
| 
 | 
 | ||||||
| 		$('form.js-acme-order').addEventListener('submit', function(ev) { | 		$('form.js-acme-order').addEventListener('submit', function (ev) { | ||||||
| 			ev.preventDefault(); | 			ev.preventDefault(); | ||||||
| 			ev.stopPropagation(); | 			ev.stopPropagation(); | ||||||
| 			var account = accountStuff.account; | 			var account = accountStuff.account; | ||||||
| @ -204,7 +204,7 @@ | |||||||
| 			var domains = ($('.js-domains').value || 'example.com').split( | 			var domains = ($('.js-domains').value || 'example.com').split( | ||||||
| 				/[, ]+/g | 				/[, ]+/g | ||||||
| 			); | 			); | ||||||
| 			return getDomainPrivkey().then(function(domainPrivJwk) { | 			return getDomainPrivkey().then(function (domainPrivJwk) { | ||||||
| 				console.log('Has CSR already?'); | 				console.log('Has CSR already?'); | ||||||
| 				console.log(accountStuff.csr); | 				console.log(accountStuff.csr); | ||||||
| 				return acme.certificates | 				return acme.certificates | ||||||
| @ -219,11 +219,11 @@ | |||||||
| 						agreeToTerms: checkTos, | 						agreeToTerms: checkTos, | ||||||
| 						challenges: { | 						challenges: { | ||||||
| 							'dns-01': { | 							'dns-01': { | ||||||
| 								set: function(opts) { | 								set: function (opts) { | ||||||
| 									console.info('dns-01 set challenge:'); | 									console.info('dns-01 set challenge:'); | ||||||
| 									console.info('TXT', opts.dnsHost); | 									console.info('TXT', opts.dnsHost); | ||||||
| 									console.info(opts.dnsAuthorization); | 									console.info(opts.dnsAuthorization); | ||||||
| 									return new Promise(function(resolve) { | 									return new Promise(function (resolve) { | ||||||
| 										while ( | 										while ( | ||||||
| 											!window.confirm( | 											!window.confirm( | ||||||
| 												'Did you set the challenge?' | 												'Did you set the challenge?' | ||||||
| @ -232,11 +232,11 @@ | |||||||
| 										resolve(); | 										resolve(); | ||||||
| 									}); | 									}); | ||||||
| 								}, | 								}, | ||||||
| 								remove: function(opts) { | 								remove: function (opts) { | ||||||
| 									console.log('dns-01 remove challenge:'); | 									console.log('dns-01 remove challenge:'); | ||||||
| 									console.info('TXT', opts.dnsHost); | 									console.info('TXT', opts.dnsHost); | ||||||
| 									console.info(opts.dnsAuthorization); | 									console.info(opts.dnsAuthorization); | ||||||
| 									return new Promise(function(resolve) { | 									return new Promise(function (resolve) { | ||||||
| 										while ( | 										while ( | ||||||
| 											!window.confirm( | 											!window.confirm( | ||||||
| 												'Did you delete the challenge?' | 												'Did you delete the challenge?' | ||||||
| @ -247,11 +247,11 @@ | |||||||
| 								} | 								} | ||||||
| 							}, | 							}, | ||||||
| 							'http-01': { | 							'http-01': { | ||||||
| 								set: function(opts) { | 								set: function (opts) { | ||||||
| 									console.info('http-01 set challenge:'); | 									console.info('http-01 set challenge:'); | ||||||
| 									console.info(opts.challengeUrl); | 									console.info(opts.challengeUrl); | ||||||
| 									console.info(opts.keyAuthorization); | 									console.info(opts.keyAuthorization); | ||||||
| 									return new Promise(function(resolve) { | 									return new Promise(function (resolve) { | ||||||
| 										while ( | 										while ( | ||||||
| 											!window.confirm( | 											!window.confirm( | ||||||
| 												'Did you set the challenge?' | 												'Did you set the challenge?' | ||||||
| @ -260,11 +260,11 @@ | |||||||
| 										resolve(); | 										resolve(); | ||||||
| 									}); | 									}); | ||||||
| 								}, | 								}, | ||||||
| 								remove: function(opts) { | 								remove: function (opts) { | ||||||
| 									console.log('http-01 remove challenge:'); | 									console.log('http-01 remove challenge:'); | ||||||
| 									console.info(opts.challengeUrl); | 									console.info(opts.challengeUrl); | ||||||
| 									console.info(opts.keyAuthorization); | 									console.info(opts.keyAuthorization); | ||||||
| 									return new Promise(function(resolve) { | 									return new Promise(function (resolve) { | ||||||
| 										while ( | 										while ( | ||||||
| 											!window.confirm( | 											!window.confirm( | ||||||
| 												'Did you delete the challenge?' | 												'Did you delete the challenge?' | ||||||
| @ -279,7 +279,7 @@ | |||||||
| 							$('input[name="acme-challenge-type"]:checked').value | 							$('input[name="acme-challenge-type"]:checked').value | ||||||
| 						] | 						] | ||||||
| 					}) | 					}) | ||||||
| 					.then(function(results) { | 					.then(function (results) { | ||||||
| 						console.log('Got Certificates:'); | 						console.log('Got Certificates:'); | ||||||
| 						console.log(results); | 						console.log(results); | ||||||
| 						$('.js-toc-acme-order-response').hidden = false; | 						$('.js-toc-acme-order-response').hidden = false; | ||||||
| @ -289,7 +289,7 @@ | |||||||
| 							2 | 							2 | ||||||
| 						); | 						); | ||||||
| 					}) | 					}) | ||||||
| 					.catch(function(err) { | 					.catch(function (err) { | ||||||
| 						console.error('challenge failed:'); | 						console.error('challenge failed:'); | ||||||
| 						console.error(err); | 						console.error(err); | ||||||
| 						window.alert( | 						window.alert( | ||||||
| @ -310,7 +310,7 @@ | |||||||
| 			kty: $('input[name="kty"]:checked').value, | 			kty: $('input[name="kty"]:checked').value, | ||||||
| 			namedCurve: $('input[name="ec-crv"]:checked').value, | 			namedCurve: $('input[name="ec-crv"]:checked').value, | ||||||
| 			modulusLength: $('input[name="rsa-len"]:checked').value | 			modulusLength: $('input[name="rsa-len"]:checked').value | ||||||
| 		}).then(function(pair) { | 		}).then(function (pair) { | ||||||
| 			console.log('domain keypair:', pair); | 			console.log('domain keypair:', pair); | ||||||
| 			accountStuff.domainPrivateJwk = pair.private; | 			accountStuff.domainPrivateJwk = pair.private; | ||||||
| 			return pair.private; | 			return pair.private; | ||||||
| @ -320,9 +320,9 @@ | |||||||
| 	function generateCsr() { | 	function generateCsr() { | ||||||
| 		var domains = ($('.js-domains').value || 'example.com').split(/[, ]+/g); | 		var domains = ($('.js-domains').value || 'example.com').split(/[, ]+/g); | ||||||
| 		//var privJwk = JSON.parse($('.js-jwk').innerText).private;
 | 		//var privJwk = JSON.parse($('.js-jwk').innerText).private;
 | ||||||
| 		return getDomainPrivkey().then(function(privJwk) { | 		return getDomainPrivkey().then(function (privJwk) { | ||||||
| 			accountStuff.domainPrivateJwk = privJwk; | 			accountStuff.domainPrivateJwk = privJwk; | ||||||
| 			return CSR({ jwk: privJwk, domains: domains }).then(function(pem) { | 			return CSR({ jwk: privJwk, domains: domains }).then(function (pem) { | ||||||
| 				// Verify with https://www.sslshopper.com/csr-decoder.html
 | 				// Verify with https://www.sslshopper.com/csr-decoder.html
 | ||||||
| 				accountStuff.csr = pem; | 				accountStuff.csr = pem; | ||||||
| 				console.log('Created CSR:'); | 				console.log('Created CSR:'); | ||||||
|  | |||||||
| @ -5,7 +5,7 @@ async function main() { | |||||||
| 
 | 
 | ||||||
| 	var fs = require('fs'); | 	var fs = require('fs'); | ||||||
| 	// just to trigger the warning message out of the way
 | 	// just to trigger the warning message out of the way
 | ||||||
| 	await fs.promises.readFile().catch(function() {}); | 	await fs.promises.readFile().catch(function () {}); | ||||||
| 	console.warn('\n'); | 	console.warn('\n'); | ||||||
| 	var MY_DOMAINS = process.env.DOMAINS.split(/[,\s]+/); | 	var MY_DOMAINS = process.env.DOMAINS.split(/[,\s]+/); | ||||||
| 
 | 
 | ||||||
| @ -55,7 +55,7 @@ async function main() { | |||||||
| 
 | 
 | ||||||
| 	// If you are multi-tenanted or white-labled and need to present the terms of
 | 	// If you are multi-tenanted or white-labled and need to present the terms of
 | ||||||
| 	// use to the Subscriber running the service, you can do so with a function.
 | 	// use to the Subscriber running the service, you can do so with a function.
 | ||||||
| 	var agreeToTerms = async function() { | 	var agreeToTerms = async function () { | ||||||
| 		return true; | 		return true; | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| @ -126,7 +126,7 @@ async function main() { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| main().catch(function(e) { | main().catch(function (e) { | ||||||
| 	console.error(e.stack); | 	console.error(e.stack); | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -7,9 +7,9 @@ var key = fs.readFileSync('./privkey.pem'); | |||||||
| var cert = fs.readFileSync('./fullchain.pem'); | var cert = fs.readFileSync('./fullchain.pem'); | ||||||
| 
 | 
 | ||||||
| var server = https | var server = https | ||||||
| 	.createSecureServer({ key, cert }, function(req, res) { | 	.createSecureServer({ key, cert }, function (req, res) { | ||||||
| 		res.end('Hello, Encrypted World!'); | 		res.end('Hello, Encrypted World!'); | ||||||
| 	}) | 	}) | ||||||
| 	.listen(443, function() { | 	.listen(443, function () { | ||||||
| 		console.info('Listening on', server.address()); | 		console.info('Listening on', server.address()); | ||||||
| 	}); | 	}); | ||||||
|  | |||||||
| @ -13,9 +13,9 @@ function SNICallback(servername, cb) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| var server = https | var server = https | ||||||
| 	.createSecureServer({ SNICallback: SNICallback }, function(req, res) { | 	.createSecureServer({ SNICallback: SNICallback }, function (req, res) { | ||||||
| 		res.end('Hello, Encrypted World!'); | 		res.end('Hello, Encrypted World!'); | ||||||
| 	}) | 	}) | ||||||
| 	.listen(443, function() { | 	.listen(443, function () { | ||||||
| 		console.info('Listening on', server.address()); | 		console.info('Listening on', server.address()); | ||||||
| 	}); | 	}); | ||||||
|  | |||||||
| @ -13,12 +13,12 @@ var nameserver = nameservers[index]; | |||||||
| 
 | 
 | ||||||
| app.use('/', express.static(__dirname)); | app.use('/', express.static(__dirname)); | ||||||
| app.use('/api', express.json()); | app.use('/api', express.json()); | ||||||
| app.get('/api/dns/:domain', function(req, res, next) { | app.get('/api/dns/:domain', function (req, res, next) { | ||||||
| 	var domain = req.params.domain; | 	var domain = req.params.domain; | ||||||
| 	var casedDomain = domain | 	var casedDomain = domain | ||||||
| 		.toLowerCase() | 		.toLowerCase() | ||||||
| 		.split('') | 		.split('') | ||||||
| 		.map(function(ch) { | 		.map(function (ch) { | ||||||
| 			// dns0x20 takes advantage of the fact that the binary operation for toUpperCase is
 | 			// dns0x20 takes advantage of the fact that the binary operation for toUpperCase is
 | ||||||
| 			// ch = ch | 0x20;
 | 			// ch = ch | 0x20;
 | ||||||
| 			return Math.round(Math.random()) % 2 ? ch : ch.toUpperCase(); | 			return Math.round(Math.random()) % 2 ? ch : ch.toUpperCase(); | ||||||
| @ -46,10 +46,10 @@ app.get('/api/dns/:domain', function(req, res, next) { | |||||||
| 		] | 		] | ||||||
| 	}; | 	}; | ||||||
| 	var opts = { | 	var opts = { | ||||||
| 		onError: function(err) { | 		onError: function (err) { | ||||||
| 			next(err); | 			next(err); | ||||||
| 		}, | 		}, | ||||||
| 		onMessage: function(packet) { | 		onMessage: function (packet) { | ||||||
| 			var fail0x20; | 			var fail0x20; | ||||||
| 
 | 
 | ||||||
| 			if (packet.id !== query.id) { | 			if (packet.id !== query.id) { | ||||||
| @ -62,17 +62,17 @@ app.get('/api/dns/:domain', function(req, res, next) { | |||||||
| 				return; | 				return; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			packet.question.forEach(function(q) { | 			packet.question.forEach(function (q) { | ||||||
| 				// if (-1 === q.name.lastIndexOf(cli.casedQuery))
 | 				// if (-1 === q.name.lastIndexOf(cli.casedQuery))
 | ||||||
| 				if (q.name !== casedDomain) { | 				if (q.name !== casedDomain) { | ||||||
| 					fail0x20 = q.name; | 					fail0x20 = q.name; | ||||||
| 				} | 				} | ||||||
| 			}); | 			}); | ||||||
| 
 | 
 | ||||||
| 			['question', 'answer', 'authority', 'additional'].forEach(function( | 			['question', 'answer', 'authority', 'additional'].forEach(function ( | ||||||
| 				group | 				group | ||||||
| 			) { | 			) { | ||||||
| 				(packet[group] || []).forEach(function(a) { | 				(packet[group] || []).forEach(function (a) { | ||||||
| 					var an = a.name; | 					var an = a.name; | ||||||
| 					var i = domain | 					var i = domain | ||||||
| 						.toLowerCase() | 						.toLowerCase() | ||||||
| @ -133,13 +133,13 @@ app.get('/api/dns/:domain', function(req, res, next) { | |||||||
| 				edns_options: packet.edns_options | 				edns_options: packet.edns_options | ||||||
| 			}); | 			}); | ||||||
| 		}, | 		}, | ||||||
| 		onListening: function() {}, | 		onListening: function () {}, | ||||||
| 		onSent: function(/*res*/) {}, | 		onSent: function (/*res*/) {}, | ||||||
| 		onTimeout: function(res) { | 		onTimeout: function (res) { | ||||||
| 			console.error('dns timeout:', res); | 			console.error('dns timeout:', res); | ||||||
| 			next(new Error('DNS timeout - no response')); | 			next(new Error('DNS timeout - no response')); | ||||||
| 		}, | 		}, | ||||||
| 		onClose: function() {}, | 		onClose: function () {}, | ||||||
| 		//, mdns: cli.mdns
 | 		//, mdns: cli.mdns
 | ||||||
| 		nameserver: nameserver, | 		nameserver: nameserver, | ||||||
| 		port: 53, | 		port: 53, | ||||||
| @ -148,13 +148,13 @@ app.get('/api/dns/:domain', function(req, res, next) { | |||||||
| 
 | 
 | ||||||
| 	dig.resolveJson(query, opts); | 	dig.resolveJson(query, opts); | ||||||
| }); | }); | ||||||
| app.get('/api/http', function(req, res) { | app.get('/api/http', function (req, res) { | ||||||
| 	var url = req.query.url; | 	var url = req.query.url; | ||||||
| 	return request({ method: 'GET', url: url }).then(function(resp) { | 	return request({ method: 'GET', url: url }).then(function (resp) { | ||||||
| 		res.send(resp.body); | 		res.send(resp.body); | ||||||
| 	}); | 	}); | ||||||
| }); | }); | ||||||
| app.get('/api/_acme_api_', function(req, res) { | app.get('/api/_acme_api_', function (req, res) { | ||||||
| 	res.send({ success: true }); | 	res.send({ success: true }); | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -2,27 +2,27 @@ | |||||||
| 
 | 
 | ||||||
| var native = module.exports; | var native = module.exports; | ||||||
| 
 | 
 | ||||||
| native._canCheck = function(me) { | native._canCheck = function (me) { | ||||||
| 	me._canCheck = {}; | 	me._canCheck = {}; | ||||||
| 	return me | 	return me | ||||||
| 		.request({ url: me._baseUrl + '/api/_acme_api_/' }) | 		.request({ url: me._baseUrl + '/api/_acme_api_/' }) | ||||||
| 		.then(function(resp) { | 		.then(function (resp) { | ||||||
| 			if (resp.body.success) { | 			if (resp.body.success) { | ||||||
| 				me._canCheck['http-01'] = true; | 				me._canCheck['http-01'] = true; | ||||||
| 				me._canCheck['dns-01'] = true; | 				me._canCheck['dns-01'] = true; | ||||||
| 			} | 			} | ||||||
| 		}) | 		}) | ||||||
| 		.catch(function() { | 		.catch(function () { | ||||||
| 			// ignore
 | 			// ignore
 | ||||||
| 		}); | 		}); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| native._dns01 = function(me, ch) { | native._dns01 = function (me, ch) { | ||||||
| 	return me | 	return me | ||||||
| 		.request({ | 		.request({ | ||||||
| 			url: me._baseUrl + '/api/dns/' + ch.dnsHost + '?type=TXT' | 			url: me._baseUrl + '/api/dns/' + ch.dnsHost + '?type=TXT' | ||||||
| 		}) | 		}) | ||||||
| 		.then(function(resp) { | 		.then(function (resp) { | ||||||
| 			var err; | 			var err; | ||||||
| 			if (!resp.body || !Array.isArray(resp.body.answer)) { | 			if (!resp.body || !Array.isArray(resp.body.answer)) { | ||||||
| 				err = new Error('failed to get DNS response'); | 				err = new Error('failed to get DNS response'); | ||||||
| @ -35,20 +35,20 @@ native._dns01 = function(me, ch) { | |||||||
| 				throw err; | 				throw err; | ||||||
| 			} | 			} | ||||||
| 			return { | 			return { | ||||||
| 				answer: resp.body.answer.map(function(ans) { | 				answer: resp.body.answer.map(function (ans) { | ||||||
| 					return { data: ans.data, ttl: ans.ttl }; | 					return { data: ans.data, ttl: ans.ttl }; | ||||||
| 				}) | 				}) | ||||||
| 			}; | 			}; | ||||||
| 		}); | 		}); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| native._http01 = function(me, ch) { | native._http01 = function (me, ch) { | ||||||
| 	var url = encodeURIComponent(ch.challengeUrl); | 	var url = encodeURIComponent(ch.challengeUrl); | ||||||
| 	return me | 	return me | ||||||
| 		.request({ | 		.request({ | ||||||
| 			url: me._baseUrl + '/api/http?url=' + url | 			url: me._baseUrl + '/api/http?url=' + url | ||||||
| 		}) | 		}) | ||||||
| 		.then(function(resp) { | 		.then(function (resp) { | ||||||
| 			return resp.body; | 			return resp.body; | ||||||
| 		}); | 		}); | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| 'use strict'; | 'use strict'; | ||||||
| 
 | 
 | ||||||
| var UserAgent = module.exports; | var UserAgent = module.exports; | ||||||
| UserAgent.get = function() { | UserAgent.get = function () { | ||||||
| 	return false; | 	return false; | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -2,30 +2,30 @@ | |||||||
| 
 | 
 | ||||||
| var http = module.exports; | var http = module.exports; | ||||||
| 
 | 
 | ||||||
| http.request = function(opts) { | http.request = function (opts) { | ||||||
| 	opts.cors = true; | 	opts.cors = true; | ||||||
| 	return window.fetch(opts.url, opts).then(function(resp) { | 	return window.fetch(opts.url, opts).then(function (resp) { | ||||||
| 		var headers = {}; | 		var headers = {}; | ||||||
| 		var result = { | 		var result = { | ||||||
| 			statusCode: resp.status, | 			statusCode: resp.status, | ||||||
| 			headers: headers, | 			headers: headers, | ||||||
| 			toJSON: function() { | 			toJSON: function () { | ||||||
| 				return this; | 				return this; | ||||||
| 			} | 			} | ||||||
| 		}; | 		}; | ||||||
| 		Array.from(resp.headers.entries()).forEach(function(h) { | 		Array.from(resp.headers.entries()).forEach(function (h) { | ||||||
| 			headers[h[0]] = h[1]; | 			headers[h[0]] = h[1]; | ||||||
| 		}); | 		}); | ||||||
| 		if (!headers['content-type']) { | 		if (!headers['content-type']) { | ||||||
| 			return result; | 			return result; | ||||||
| 		} | 		} | ||||||
| 		if (/json/.test(headers['content-type'])) { | 		if (/json/.test(headers['content-type'])) { | ||||||
| 			return resp.json().then(function(json) { | 			return resp.json().then(function (json) { | ||||||
| 				result.body = json; | 				result.body = json; | ||||||
| 				return result; | 				return result; | ||||||
| 			}); | 			}); | ||||||
| 		} | 		} | ||||||
| 		return resp.text().then(function(txt) { | 		return resp.text().then(function (txt) { | ||||||
| 			result.body = txt; | 			result.body = txt; | ||||||
| 			return result; | 			return result; | ||||||
| 		}); | 		}); | ||||||
|  | |||||||
| @ -3,7 +3,7 @@ | |||||||
| var sha2 = module.exports; | var sha2 = module.exports; | ||||||
| 
 | 
 | ||||||
| var encoder = new TextEncoder(); | var encoder = new TextEncoder(); | ||||||
| sha2.sum = function(alg, str) { | sha2.sum = function (alg, str) { | ||||||
| 	var data = str; | 	var data = str; | ||||||
| 	if ('string' === typeof data) { | 	if ('string' === typeof data) { | ||||||
| 		data = encoder.encode(str); | 		data = encoder.encode(str); | ||||||
|  | |||||||
| @ -5,18 +5,18 @@ var promisify = require('util').promisify; | |||||||
| var resolveTxt = promisify(require('dns').resolveTxt); | var resolveTxt = promisify(require('dns').resolveTxt); | ||||||
| var crypto = require('crypto'); | var crypto = require('crypto'); | ||||||
| 
 | 
 | ||||||
| native._canCheck = function(me) { | native._canCheck = function (me) { | ||||||
| 	me._canCheck = {}; | 	me._canCheck = {}; | ||||||
| 	me._canCheck['http-01'] = true; | 	me._canCheck['http-01'] = true; | ||||||
| 	me._canCheck['dns-01'] = true; | 	me._canCheck['dns-01'] = true; | ||||||
| 	return Promise.resolve(); | 	return Promise.resolve(); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| native._dns01 = function(me, ch) { | native._dns01 = function (me, ch) { | ||||||
| 	// TODO use digd.js
 | 	// TODO use digd.js
 | ||||||
| 	return resolveTxt(ch.dnsHost).then(function(records) { | 	return resolveTxt(ch.dnsHost).then(function (records) { | ||||||
| 		return { | 		return { | ||||||
| 			answer: records.map(function(rr) { | 			answer: records.map(function (rr) { | ||||||
| 				return { | 				return { | ||||||
| 					data: rr | 					data: rr | ||||||
| 				}; | 				}; | ||||||
| @ -25,10 +25,10 @@ native._dns01 = function(me, ch) { | |||||||
| 	}); | 	}); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| native._http01 = function(me, ch) { | native._http01 = function (me, ch) { | ||||||
| 	return new me.request({ | 	return new me.request({ | ||||||
| 		url: ch.challengeUrl | 		url: ch.challengeUrl | ||||||
| 	}).then(function(resp) { | 	}).then(function (resp) { | ||||||
| 		return resp.body; | 		return resp.body; | ||||||
| 	}); | 	}); | ||||||
| }; | }; | ||||||
| @ -36,12 +36,12 @@ native._http01 = function(me, ch) { | |||||||
| // the hashcash here is for browser parity only
 | // the hashcash here is for browser parity only
 | ||||||
| // basically we ask the client to find a needle in a haystack
 | // basically we ask the client to find a needle in a haystack
 | ||||||
| // (very similar to CloudFlare's api protection)
 | // (very similar to CloudFlare's api protection)
 | ||||||
| native._hashcash = function(ch) { | native._hashcash = function (ch) { | ||||||
| 	if (!ch || !ch.nonce) { | 	if (!ch || !ch.nonce) { | ||||||
| 		ch = { nonce: 'xxx' }; | 		ch = { nonce: 'xxx' }; | ||||||
| 	} | 	} | ||||||
| 	return Promise.resolve() | 	return Promise.resolve() | ||||||
| 		.then(function() { | 		.then(function () { | ||||||
| 			// only get easy answers
 | 			// only get easy answers
 | ||||||
| 			var len = ch.needle.length; | 			var len = ch.needle.length; | ||||||
| 			var start = ch.start || 0; | 			var start = ch.start || 0; | ||||||
| @ -80,7 +80,7 @@ native._hashcash = function(ch) { | |||||||
| 			} | 			} | ||||||
| 			return ch.nonce + ':xxx'; | 			return ch.nonce + ':xxx'; | ||||||
| 		}) | 		}) | ||||||
| 		.catch(function() { | 		.catch(function () { | ||||||
| 			//console.log('[debug]', err);
 | 			//console.log('[debug]', err);
 | ||||||
| 			// ignore any error
 | 			// ignore any error
 | ||||||
| 			return ch.nonce + ':xxx'; | 			return ch.nonce + ':xxx'; | ||||||
|  | |||||||
| @ -4,7 +4,7 @@ var os = require('os'); | |||||||
| var ver = require('../../package.json').version; | var ver = require('../../package.json').version; | ||||||
| 
 | 
 | ||||||
| var UserAgent = module.exports; | var UserAgent = module.exports; | ||||||
| UserAgent.get = function(me) { | UserAgent.get = function (me) { | ||||||
| 	// ACME clients MUST have an RFC7231-compliant User-Agent
 | 	// ACME clients MUST have an RFC7231-compliant User-Agent
 | ||||||
| 	// ex: Greenlock/v3 ACME.js/v3 node/v12.0.0 darwin/17.7.0 Darwin/x64
 | 	// ex: Greenlock/v3 ACME.js/v3 node/v12.0.0 darwin/17.7.0 Darwin/x64
 | ||||||
| 	//
 | 	//
 | ||||||
|  | |||||||
| @ -4,6 +4,6 @@ var http = module.exports; | |||||||
| var promisify = require('util').promisify; | var promisify = require('util').promisify; | ||||||
| var request = promisify(require('@root/request')); | var request = promisify(require('@root/request')); | ||||||
| 
 | 
 | ||||||
| http.request = function(opts) { | http.request = function (opts) { | ||||||
| 	return request(opts); | 	return request(opts); | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -4,14 +4,11 @@ | |||||||
| var sha2 = module.exports; | var sha2 = module.exports; | ||||||
| var crypto = require('crypto'); | var crypto = require('crypto'); | ||||||
| 
 | 
 | ||||||
| sha2.sum = function(alg, str) { | sha2.sum = function (alg, str) { | ||||||
| 	return Promise.resolve().then(function() { | 	return Promise.resolve().then(function () { | ||||||
| 		var sha = 'sha' + String(alg).replace(/^sha-?/i, ''); | 		var sha = 'sha' + String(alg).replace(/^sha-?/i, ''); | ||||||
| 		// utf8 is the default for strings
 | 		// utf8 is the default for strings
 | ||||||
| 		var buf = Buffer.from(str); | 		var buf = Buffer.from(str); | ||||||
| 		return crypto | 		return crypto.createHash(sha).update(buf).digest(); | ||||||
| 			.createHash(sha) |  | ||||||
| 			.update(buf) |  | ||||||
| 			.digest(); |  | ||||||
| 	}); | 	}); | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -7,7 +7,7 @@ var native = require('./lib/native.js'); | |||||||
| // something breaks or has a serious bug or flaw.
 | // something breaks or has a serious bug or flaw.
 | ||||||
| 
 | 
 | ||||||
| var oldCollegeTries = {}; | var oldCollegeTries = {}; | ||||||
| M.init = function(me) { | M.init = function (me) { | ||||||
| 	if (oldCollegeTries[me.maintainerEmail]) { | 	if (oldCollegeTries[me.maintainerEmail]) { | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| @ -32,8 +32,8 @@ M.init = function(me) { | |||||||
| 	} | 	} | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| M._init = function(me, tz, locale) { | M._init = function (me, tz, locale) { | ||||||
| 	setTimeout(function() { | 	setTimeout(function () { | ||||||
| 		// prevent a stampede from misconfigured clients in an eternal loop
 | 		// prevent a stampede from misconfigured clients in an eternal loop
 | ||||||
| 		me.request({ | 		me.request({ | ||||||
| 			timeout: 3000, | 			timeout: 3000, | ||||||
| @ -41,12 +41,12 @@ M._init = function(me, tz, locale) { | |||||||
| 			url: 'https://api.rootprojects.org/api/nonce', | 			url: 'https://api.rootprojects.org/api/nonce', | ||||||
| 			json: true | 			json: true | ||||||
| 		}) | 		}) | ||||||
| 			.then(function(resp) { | 			.then(function (resp) { | ||||||
| 				// in the browser this will work until solved, but in
 | 				// in the browser this will work until solved, but in
 | ||||||
| 				// node this will bail unless the challenge is trivial
 | 				// node this will bail unless the challenge is trivial
 | ||||||
| 				return native._hashcash(resp.body || {}); | 				return native._hashcash(resp.body || {}); | ||||||
| 			}) | 			}) | ||||||
| 			.then(function(hashcash) { | 			.then(function (hashcash) { | ||||||
| 				var req = { | 				var req = { | ||||||
| 					timeout: 3000, | 					timeout: 3000, | ||||||
| 					headers: { | 					headers: { | ||||||
| @ -64,7 +64,7 @@ M._init = function(me, tz, locale) { | |||||||
| 				}; | 				}; | ||||||
| 				return me.request(req); | 				return me.request(req); | ||||||
| 			}) | 			}) | ||||||
| 			.catch(function(err) { | 			.catch(function (err) { | ||||||
| 				if (me.debug) { | 				if (me.debug) { | ||||||
| 					console.error( | 					console.error( | ||||||
| 						'error adding maintainer to support notices:' | 						'error adding maintainer to support notices:' | ||||||
| @ -72,7 +72,7 @@ M._init = function(me, tz, locale) { | |||||||
| 					console.error(err); | 					console.error(err); | ||||||
| 				} | 				} | ||||||
| 			}) | 			}) | ||||||
| 			.then(function(/*resp*/) { | 			.then(function (/*resp*/) { | ||||||
| 				oldCollegeTries[me.maintainerEmail] = true; | 				oldCollegeTries[me.maintainerEmail] = true; | ||||||
| 				//console.log(resp);
 | 				//console.log(resp);
 | ||||||
| 			}); | 			}); | ||||||
|  | |||||||
							
								
								
									
										20
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										20
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @ -1,6 +1,6 @@ | |||||||
| { | { | ||||||
| 	"name": "@root/acme", | 	"name": "@root/acme", | ||||||
| 	"version": "3.0.10", | 	"version": "3.1.0", | ||||||
| 	"lockfileVersion": 1, | 	"lockfileVersion": 1, | ||||||
| 	"requires": true, | 	"requires": true, | ||||||
| 	"dependencies": { | 	"dependencies": { | ||||||
| @ -28,9 +28,9 @@ | |||||||
| 			"integrity": "sha512-OaEub02ufoU038gy6bsNHQOjIn8nUjGiLcaRmJ40IUykneJkIW5fxDqKxQx48cszuNflYldsJLPPXCrGfHs8yQ==" | 			"integrity": "sha512-OaEub02ufoU038gy6bsNHQOjIn8nUjGiLcaRmJ40IUykneJkIW5fxDqKxQx48cszuNflYldsJLPPXCrGfHs8yQ==" | ||||||
| 		}, | 		}, | ||||||
| 		"@root/keypairs": { | 		"@root/keypairs": { | ||||||
| 			"version": "0.9.0", | 			"version": "0.10.0", | ||||||
| 			"resolved": "https://registry.npmjs.org/@root/keypairs/-/keypairs-0.9.0.tgz", | 			"resolved": "https://registry.npmjs.org/@root/keypairs/-/keypairs-0.10.0.tgz", | ||||||
| 			"integrity": "sha512-NXE2L9Gv7r3iC4kB/gTPZE1vO9Ox/p14zDzAJ5cGpTpytbWOlWF7QoHSJbtVX4H7mRG/Hp7HR3jWdWdb2xaaXg==", | 			"integrity": "sha512-t8VocY46Mtb0NTsxzyLLf5tsgfw0BXLYVADAyiRdEdqHcvPFGJdjkXNtHVQuSV/FMaC65iTOHVP4E6X8iT3Ikg==", | ||||||
| 			"requires": { | 			"requires": { | ||||||
| 				"@root/encoding": "^1.0.1", | 				"@root/encoding": "^1.0.1", | ||||||
| 				"@root/pem": "^1.0.4", | 				"@root/pem": "^1.0.4", | ||||||
| @ -43,9 +43,9 @@ | |||||||
| 			"integrity": "sha512-rEUDiUsHtild8GfIjFE9wXtcVxeS+ehCJQBwbQQ3IVfORKHK93CFnRtkr69R75lZFjcmKYVc+AXDB+AeRFOULA==" | 			"integrity": "sha512-rEUDiUsHtild8GfIjFE9wXtcVxeS+ehCJQBwbQQ3IVfORKHK93CFnRtkr69R75lZFjcmKYVc+AXDB+AeRFOULA==" | ||||||
| 		}, | 		}, | ||||||
| 		"@root/request": { | 		"@root/request": { | ||||||
| 			"version": "1.3.11", | 			"version": "1.6.1", | ||||||
| 			"resolved": "https://registry.npmjs.org/@root/request/-/request-1.3.11.tgz", | 			"resolved": "https://registry.npmjs.org/@root/request/-/request-1.6.1.tgz", | ||||||
| 			"integrity": "sha512-3a4Eeghcjsfe6zh7EJ+ni1l8OK9Fz2wL1OjP4UCa0YdvtH39kdXB9RGWuzyNv7dZi0+Ffkc83KfH0WbPMiuJFw==" | 			"integrity": "sha512-8wrWyeBLRp7T8J36GkT3RODJ6zYmL0/maWlAUD5LOXT28D3TDquUepyYDKYANNA3Gc8R5ZCgf+AXvSTYpJEWwQ==" | ||||||
| 		}, | 		}, | ||||||
| 		"@root/x509": { | 		"@root/x509": { | ||||||
| 			"version": "0.7.2", | 			"version": "0.7.2", | ||||||
| @ -152,9 +152,9 @@ | |||||||
| 			"dev": true | 			"dev": true | ||||||
| 		}, | 		}, | ||||||
| 		"glob": { | 		"glob": { | ||||||
| 			"version": "7.1.5", | 			"version": "7.1.6", | ||||||
| 			"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.5.tgz", | 			"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", | ||||||
| 			"integrity": "sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ==", | 			"integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", | ||||||
| 			"dev": true, | 			"dev": true, | ||||||
| 			"requires": { | 			"requires": { | ||||||
| 				"fs.realpath": "^1.0.0", | 				"fs.realpath": "^1.0.0", | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| { | { | ||||||
| 	"name": "@root/acme", | 	"name": "@root/acme", | ||||||
| 	"version": "3.0.10", | 	"version": "3.1.0", | ||||||
| 	"description": "Free SSL certificates for Node.js and Browsers. Issued via Let's Encrypt", | 	"description": "Free SSL certificates for Node.js and Browsers. Issued via Let's Encrypt", | ||||||
| 	"homepage": "https://rootprojects.org/acme/", | 	"homepage": "https://rootprojects.org/acme/", | ||||||
| 	"main": "acme.js", | 	"main": "acme.js", | ||||||
| @ -44,9 +44,9 @@ | |||||||
| 	"dependencies": { | 	"dependencies": { | ||||||
| 		"@root/csr": "^0.8.1", | 		"@root/csr": "^0.8.1", | ||||||
| 		"@root/encoding": "^1.0.1", | 		"@root/encoding": "^1.0.1", | ||||||
| 		"@root/keypairs": "^0.9.0", | 		"@root/keypairs": "^0.10.0", | ||||||
| 		"@root/pem": "^1.0.4", | 		"@root/pem": "^1.0.4", | ||||||
| 		"@root/request": "^1.3.11", | 		"@root/request": "^1.6.1", | ||||||
| 		"@root/x509": "^0.7.2" | 		"@root/x509": "^0.7.2" | ||||||
| 	}, | 	}, | ||||||
| 	"devDependencies": { | 	"devDependencies": { | ||||||
|  | |||||||
| @ -51,7 +51,7 @@ async function main() { | |||||||
| 			challenge: ch, | 			challenge: ch, | ||||||
| 			dnsPrefix: '_test-challenge' | 			dnsPrefix: '_test-challenge' | ||||||
| 		}) | 		}) | ||||||
| 			.then(function(auth) { | 			.then(function (auth) { | ||||||
| 				if ('dns-01' === ch.type) { | 				if ('dns-01' === ch.type) { | ||||||
| 					if (auth.keyAuthorizationDigest !== expectedKeyAuthDigest) { | 					if (auth.keyAuthorizationDigest !== expectedKeyAuthDigest) { | ||||||
| 						console.error('[keyAuthorizationDigest]'); | 						console.error('[keyAuthorizationDigest]'); | ||||||
| @ -84,7 +84,7 @@ async function main() { | |||||||
| 				console.info('PASS', hostname, ch.type); | 				console.info('PASS', hostname, ch.type); | ||||||
| 				return next(); | 				return next(); | ||||||
| 			}) | 			}) | ||||||
| 			.catch(function(err) { | 			.catch(function (err) { | ||||||
| 				err.message = | 				err.message = | ||||||
| 					'Error computing ' + | 					'Error computing ' + | ||||||
| 					ch.type + | 					ch.type + | ||||||
| @ -99,12 +99,12 @@ async function main() { | |||||||
| 	return next(); | 	return next(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| module.exports = function() { | module.exports = function () { | ||||||
| 	return main(authorization) | 	return main(authorization) | ||||||
| 		.then(function() { | 		.then(function () { | ||||||
| 			console.info('PASS'); | 			console.info('PASS'); | ||||||
| 		}) | 		}) | ||||||
| 		.catch(function(err) { | 		.catch(function (err) { | ||||||
| 			console.error(err.stack); | 			console.error(err.stack); | ||||||
| 			process.exit(1); | 			process.exit(1); | ||||||
| 		}); | 		}); | ||||||
|  | |||||||
| @ -37,10 +37,10 @@ var tests = [ | |||||||
| 
 | 
 | ||||||
| var ACME = require('../'); | var ACME = require('../'); | ||||||
| 
 | 
 | ||||||
| module.exports = function() { | module.exports = function () { | ||||||
| 	console.info('\n[Test] can split and format PEM chain properly'); | 	console.info('\n[Test] can split and format PEM chain properly'); | ||||||
| 
 | 
 | ||||||
| 	tests.forEach(function(str) { | 	tests.forEach(function (str) { | ||||||
| 		var actual = ACME.formatPemChain(str); | 		var actual = ACME.formatPemChain(str); | ||||||
| 		if (expected !== actual) { | 		if (expected !== actual) { | ||||||
| 			console.error('input:   ', JSON.stringify(str)); | 			console.error('input:   ', JSON.stringify(str)); | ||||||
| @ -68,7 +68,7 @@ module.exports = function() { | |||||||
| 
 | 
 | ||||||
| 	ACME.splitPemChain( | 	ACME.splitPemChain( | ||||||
| 		'--B--\nxxxx\nyyyy\n--E--\n\n--B--\nxxxx\nyyyy\n--E--\n\n--B--\nxxxx\nyyyy\n--E--\n' | 		'--B--\nxxxx\nyyyy\n--E--\n\n--B--\nxxxx\nyyyy\n--E--\n\n--B--\nxxxx\nyyyy\n--E--\n' | ||||||
| 	).forEach(function(str) { | 	).forEach(function (str) { | ||||||
| 		if ('--B--\nxxxx\nyyyy\n--E--\n' !== str) { | 		if ('--B--\nxxxx\nyyyy\n--E--\n' !== str) { | ||||||
| 			throw new Error('bad thingy'); | 			throw new Error('bad thingy'); | ||||||
| 		} | 		} | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| 'use strict'; | 'use strict'; | ||||||
| 
 | 
 | ||||||
| module.exports = async function() { | module.exports = async function () { | ||||||
| 	console.log('[Test] can generate, export, and import key'); | 	console.log('[Test] can generate, export, and import key'); | ||||||
| 	var Keypairs = require('@root/keypairs'); | 	var Keypairs = require('@root/keypairs'); | ||||||
| 
 | 
 | ||||||
| @ -13,7 +13,7 @@ module.exports = async function() { | |||||||
| 	var jwk = await Keypairs.import({ | 	var jwk = await Keypairs.import({ | ||||||
| 		pem: pem | 		pem: pem | ||||||
| 	}); | 	}); | ||||||
| 	['kty', 'd', 'n', 'e'].forEach(function(k) { | 	['kty', 'd', 'n', 'e'].forEach(function (k) { | ||||||
| 		if (!jwk[k] || jwk[k] !== certKeypair.private[k]) { | 		if (!jwk[k] || jwk[k] !== certKeypair.private[k]) { | ||||||
| 			throw new Error('bad export/import'); | 			throw new Error('bad export/import'); | ||||||
| 		} | 		} | ||||||
|  | |||||||
| @ -32,14 +32,14 @@ var pluginPrefix = 'acme-' + config.challengeType + '-'; | |||||||
| var pluginName = config.challengeModule; | var pluginName = config.challengeModule; | ||||||
| var plugin; | var plugin; | ||||||
| 
 | 
 | ||||||
| module.exports = function() { | module.exports = function () { | ||||||
| 	console.info('\n[Test] end-to-end issue certificates'); | 	console.info('\n[Test] end-to-end issue certificates'); | ||||||
| 
 | 
 | ||||||
| 	var acme = ACME.create({ | 	var acme = ACME.create({ | ||||||
| 		// debug: true
 | 		// debug: true
 | ||||||
| 		maintainerEmail: config.email, | 		maintainerEmail: config.email, | ||||||
| 		packageAgent: 'test-' + pkg.name + '/' + pkg.version, | 		packageAgent: 'test-' + pkg.name + '/' + pkg.version, | ||||||
| 		notify: function(ev, params) { | 		notify: function (ev, params) { | ||||||
| 			console.info( | 			console.info( | ||||||
| 				'\t' + ev, | 				'\t' + ev, | ||||||
| 				params.subject || params.altname || params.domain || '', | 				params.subject || params.altname || params.domain || '', | ||||||
| @ -169,7 +169,7 @@ module.exports = function() { | |||||||
| 			console.info('Get certificates for random domains:'); | 			console.info('Get certificates for random domains:'); | ||||||
| 			console.info( | 			console.info( | ||||||
| 				domains | 				domains | ||||||
| 					.map(function(puny) { | 					.map(function (puny) { | ||||||
| 						var uni = punycode.toUnicode(puny); | 						var uni = punycode.toUnicode(puny); | ||||||
| 						if (puny !== uni) { | 						if (puny !== uni) { | ||||||
| 							return puny + ' (' + uni + ')'; | 							return puny + ' (' + uni + ')'; | ||||||
| @ -221,25 +221,25 @@ module.exports = function() { | |||||||
| 	// Try EC + RSA
 | 	// Try EC + RSA
 | ||||||
| 	var rnd = random(); | 	var rnd = random(); | ||||||
| 	happyPath('EC', 'RSA', rnd) | 	happyPath('EC', 'RSA', rnd) | ||||||
| 		.then(function() { | 		.then(function () { | ||||||
| 			console.info('PASS: ECDSA account key with RSA server key'); | 			console.info('PASS: ECDSA account key with RSA server key'); | ||||||
| 			// Now try RSA + EC
 | 			// Now try RSA + EC
 | ||||||
| 			rnd = random(); | 			rnd = random(); | ||||||
| 			return happyPath('RSA', 'EC', rnd).then(function() { | 			return happyPath('RSA', 'EC', rnd).then(function () { | ||||||
| 				console.info('PASS: RSA account key with ECDSA server key'); | 				console.info('PASS: RSA account key with ECDSA server key'); | ||||||
| 			}); | 			}); | ||||||
| 		}) | 		}) | ||||||
| 		.then(function() { | 		.then(function () { | ||||||
| 			console.info('PASS'); | 			console.info('PASS'); | ||||||
| 		}) | 		}) | ||||||
| 		.catch(function(err) { | 		.catch(function (err) { | ||||||
| 			console.error('Error:'); | 			console.error('Error:'); | ||||||
| 			console.error(err.stack); | 			console.error(err.stack); | ||||||
| 		}); | 		}); | ||||||
| 
 | 
 | ||||||
| 	function randomDomains(rnd) { | 	function randomDomains(rnd) { | ||||||
| 		return ['foo-acmejs', 'bar-acmejs', '*.baz-acmejs', 'baz-acmejs'].map( | 		return ['foo-acmejs', 'bar-acmejs', '*.baz-acmejs', 'baz-acmejs'].map( | ||||||
| 			function(pre) { | 			function (pre) { | ||||||
| 				return punycode.toASCII(pre + '-' + rnd + '.' + config.domain); | 				return punycode.toASCII(pre + '-' + rnd + '.' + config.domain); | ||||||
| 			} | 			} | ||||||
| 		); | 		); | ||||||
| @ -247,12 +247,7 @@ module.exports = function() { | |||||||
| 
 | 
 | ||||||
| 	function random() { | 	function random() { | ||||||
| 		return ( | 		return ( | ||||||
| 			parseInt( | 			parseInt(Math.random().toString().slice(2, 99), 10) | ||||||
| 				Math.random() |  | ||||||
| 					.toString() |  | ||||||
| 					.slice(2, 99), |  | ||||||
| 				10 |  | ||||||
| 			) |  | ||||||
| 				.toString(16) | 				.toString(16) | ||||||
| 				.slice(0, 4) + '例' | 				.slice(0, 4) + '例' | ||||||
| 		); | 		); | ||||||
|  | |||||||
| @ -11,7 +11,7 @@ native | |||||||
| 		start: 0, | 		start: 0, | ||||||
| 		end: 2 | 		end: 2 | ||||||
| 	}) | 	}) | ||||||
| 	.then(function(hashcash) { | 	.then(function (hashcash) { | ||||||
| 		if ('00:76de' !== hashcash) { | 		if ('00:76de' !== hashcash) { | ||||||
| 			throw new Error('hashcash algorthim changed'); | 			throw new Error('hashcash algorthim changed'); | ||||||
| 		} | 		} | ||||||
| @ -25,7 +25,7 @@ native | |||||||
| 				start: 0, | 				start: 0, | ||||||
| 				end: 2 | 				end: 2 | ||||||
| 			}) | 			}) | ||||||
| 			.then(function(hashcash) { | 			.then(function (hashcash) { | ||||||
| 				if ('10:00' !== hashcash) { | 				if ('10:00' !== hashcash) { | ||||||
| 					throw new Error('hashcash algorthim changed'); | 					throw new Error('hashcash algorthim changed'); | ||||||
| 				} | 				} | ||||||
| @ -33,10 +33,7 @@ native | |||||||
| 
 | 
 | ||||||
| 				var now = Date.now(); | 				var now = Date.now(); | ||||||
| 				var nonce = '20'; | 				var nonce = '20'; | ||||||
| 				var needle = crypto | 				var needle = crypto.randomBytes(3).toString('hex').slice(0, 5); | ||||||
| 					.randomBytes(3) |  | ||||||
| 					.toString('hex') |  | ||||||
| 					.slice(0, 5); |  | ||||||
| 				native | 				native | ||||||
| 					._hashcash({ | 					._hashcash({ | ||||||
| 						alg: 'SHA-256', | 						alg: 'SHA-256', | ||||||
| @ -45,7 +42,7 @@ native | |||||||
| 						start: 0, | 						start: 0, | ||||||
| 						end: Math.ceil(needle.length / 2) | 						end: Math.ceil(needle.length / 2) | ||||||
| 					}) | 					}) | ||||||
| 					.then(function(hashcash) { | 					.then(function (hashcash) { | ||||||
| 						var later = Date.now(); | 						var later = Date.now(); | ||||||
| 						var parts = hashcash.split(':'); | 						var parts = hashcash.split(':'); | ||||||
| 						var answer = parts[1]; | 						var answer = parts[1]; | ||||||
|  | |||||||
							
								
								
									
										31
									
								
								utils.js
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								utils.js
									
									
									
									
									
								
							| @ -6,17 +6,18 @@ var Keypairs = require('@root/keypairs'); | |||||||
| var UserAgent = require('./lib/node/client-user-agent.js'); | var UserAgent = require('./lib/node/client-user-agent.js'); | ||||||
| 
 | 
 | ||||||
| // Handle nonce, signing, and request altogether
 | // Handle nonce, signing, and request altogether
 | ||||||
| U._jwsRequest = function(me, bigopts) { | U._jwsRequest = function (me, bigopts) { | ||||||
| 	return U._getNonce(me).then(function(nonce) { | 	return U._getNonce(me).then(function (nonce) { | ||||||
| 		bigopts.protected.nonce = nonce; | 		bigopts.protected.nonce = nonce; | ||||||
| 		bigopts.protected.url = bigopts.url; | 		bigopts.protected.url = bigopts.url; | ||||||
| 		// protected.alg: added by Keypairs.signJws
 | 		// protected.alg: added by Keypairs.signJws
 | ||||||
| 		if (!bigopts.protected.jwk) { | 		if (bigopts.protected.jwk) { | ||||||
| 			// protected.kid must be overwritten due to ACME's interpretation of the spec
 | 			bigopts.protected.kid = false; | ||||||
| 			if (!('kid' in bigopts.protected)) { | 		} else if (!('kid' in bigopts.protected)) { | ||||||
|  | 			// protected.kid must be provided according to ACME's interpretation of the spec
 | ||||||
|  | 			// (using the provided URL rather than the Key's Thumbprint as Key ID)
 | ||||||
| 			bigopts.protected.kid = bigopts.kid; | 			bigopts.protected.kid = bigopts.kid; | ||||||
| 		} | 		} | ||||||
| 		} |  | ||||||
| 
 | 
 | ||||||
| 		// this will shasum the thumbprint the 2nd time
 | 		// this will shasum the thumbprint the 2nd time
 | ||||||
| 		return Keypairs.signJws({ | 		return Keypairs.signJws({ | ||||||
| @ -24,12 +25,12 @@ U._jwsRequest = function(me, bigopts) { | |||||||
| 			protected: bigopts.protected, | 			protected: bigopts.protected, | ||||||
| 			payload: bigopts.payload | 			payload: bigopts.payload | ||||||
| 		}) | 		}) | ||||||
| 			.then(function(jws) { | 			.then(function (jws) { | ||||||
| 				//#console.debug('[ACME.js] url: ' + bigopts.url + ':');
 | 				//#console.debug('[ACME.js] url: ' + bigopts.url + ':');
 | ||||||
| 				//#console.debug(jws);
 | 				//#console.debug(jws);
 | ||||||
| 				return U._request(me, { url: bigopts.url, json: jws }); | 				return U._request(me, { url: bigopts.url, json: jws }); | ||||||
| 			}) | 			}) | ||||||
| 			.catch(function(e) { | 			.catch(function (e) { | ||||||
| 				if (/badNonce$/.test(e.urn)) { | 				if (/badNonce$/.test(e.urn)) { | ||||||
| 					// retry badNonces
 | 					// retry badNonces
 | ||||||
| 					var retryable = bigopts._retries >= 2; | 					var retryable = bigopts._retries >= 2; | ||||||
| @ -43,7 +44,7 @@ U._jwsRequest = function(me, bigopts) { | |||||||
| 	}); | 	}); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| U._getNonce = function(me) { | U._getNonce = function (me) { | ||||||
| 	var nonce; | 	var nonce; | ||||||
| 	while (true) { | 	while (true) { | ||||||
| 		nonce = me._nonces.shift(); | 		nonce = me._nonces.shift(); | ||||||
| @ -64,13 +65,13 @@ U._getNonce = function(me) { | |||||||
| 	return U._request(me, { | 	return U._request(me, { | ||||||
| 		method: 'HEAD', | 		method: 'HEAD', | ||||||
| 		url: me._directoryUrls.newNonce | 		url: me._directoryUrls.newNonce | ||||||
| 	}).then(function(resp) { | 	}).then(function (resp) { | ||||||
| 		return resp.headers['replay-nonce']; | 		return resp.headers['replay-nonce']; | ||||||
| 	}); | 	}); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| // Handle some ACME-specific defaults
 | // Handle some ACME-specific defaults
 | ||||||
| U._request = function(me, opts) { | U._request = function (me, opts) { | ||||||
| 	// no-op on browser
 | 	// no-op on browser
 | ||||||
| 	var ua = UserAgent.get(me, opts); | 	var ua = UserAgent.get(me, opts); | ||||||
| 
 | 
 | ||||||
| @ -100,7 +101,7 @@ U._request = function(me, opts) { | |||||||
| 
 | 
 | ||||||
| 	//console.log('\n[debug] REQUEST');
 | 	//console.log('\n[debug] REQUEST');
 | ||||||
| 	//console.log(opts);
 | 	//console.log(opts);
 | ||||||
| 	return me.__request(opts).then(function(resp) { | 	return me.__request(opts).then(function (resp) { | ||||||
| 		if (resp.toJSON) { | 		if (resp.toJSON) { | ||||||
| 			resp = resp.toJSON(); | 			resp = resp.toJSON(); | ||||||
| 		} | 		} | ||||||
| @ -139,11 +140,11 @@ U._request = function(me, opts) { | |||||||
| 	}); | 	}); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| U._setNonce = function(me, nonce) { | U._setNonce = function (me, nonce) { | ||||||
| 	me._nonces.unshift({ nonce: nonce, createdAt: Date.now() }); | 	me._nonces.unshift({ nonce: nonce, createdAt: Date.now() }); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| U._importKeypair = function(key) { | U._importKeypair = function (key) { | ||||||
| 	var p; | 	var p; | ||||||
| 	var pub; | 	var pub; | ||||||
| 
 | 
 | ||||||
| @ -162,7 +163,7 @@ U._importKeypair = function(key) { | |||||||
| 		throw new Error('no private key given'); | 		throw new Error('no private key given'); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return p.then(function(pair) { | 	return p.then(function (pair) { | ||||||
| 		if (pair.public.kid) { | 		if (pair.public.kid) { | ||||||
| 			pair = JSON.parse(JSON.stringify(pair)); | 			pair = JSON.parse(JSON.stringify(pair)); | ||||||
| 			delete pair.public.kid; | 			delete pair.public.kid; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user