forked from root/acme.js
		
	Bug fix: Polling status using POST-as-GET wherever possible
Avoid repeating finalize POST request and challenge POST requests by using POST-as-GET requests instead. Allows for testing with Pebble, and more correctly follows the spec.
This commit is contained in:
		
							parent
							
								
									bef931f28f
								
							
						
					
					
						commit
						0aa939a227
					
				
							
								
								
									
										144
									
								
								acme.js
									
									
									
									
									
								
							
							
						
						
									
										144
									
								
								acme.js
									
									
									
									
									
								
							@ -756,12 +756,8 @@ ACME._postChallenge = function (me, options, kid, auth) {
 | 
				
			|||||||
			altname: altname
 | 
								altname: altname
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if ('processing' === resp.body.status) {
 | 
							// State can be pending while waiting ACME server to transition to
 | 
				
			||||||
			//#console.debug('poll: again', auth.url);
 | 
							// processing
 | 
				
			||||||
			return ACME._wait(RETRY_INTERVAL).then(pollStatus);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// This state should never occur
 | 
					 | 
				
			||||||
		if ('pending' === resp.body.status) {
 | 
							if ('pending' === resp.body.status) {
 | 
				
			||||||
			if (count >= MAX_PEND) {
 | 
								if (count >= MAX_PEND) {
 | 
				
			||||||
				return ACME._wait(RETRY_INTERVAL)
 | 
									return ACME._wait(RETRY_INTERVAL)
 | 
				
			||||||
@ -769,7 +765,12 @@ ACME._postChallenge = function (me, options, kid, auth) {
 | 
				
			|||||||
					.then(respondToChallenge);
 | 
										.then(respondToChallenge);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			//#console.debug('poll: again', auth.url);
 | 
								//#console.debug('poll: again', auth.url);
 | 
				
			||||||
			return ACME._wait(RETRY_INTERVAL).then(respondToChallenge);
 | 
								return ACME._wait(RETRY_INTERVAL).then(pollStatus);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if ('processing' === resp.body.status) {
 | 
				
			||||||
 | 
								//#console.debug('poll: again', auth.url);
 | 
				
			||||||
 | 
								return ACME._wait(RETRY_INTERVAL).then(pollStatus);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// REMOVE DNS records as soon as the state is non-processing
 | 
							// REMOVE DNS records as soon as the state is non-processing
 | 
				
			||||||
@ -1012,73 +1013,84 @@ ACME._pollOrderStatus = function (me, options, kid, order, verifieds) {
 | 
				
			|||||||
	var body = { csr: csr64 };
 | 
						var body = { csr: csr64 };
 | 
				
			||||||
	var payload = JSON.stringify(body);
 | 
						var payload = JSON.stringify(body);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	function pollCert() {
 | 
						function processResponse(resp) {
 | 
				
			||||||
 | 
							ACME._notify(me, options, 'certificate_status', {
 | 
				
			||||||
 | 
								subject: options.domains[0],
 | 
				
			||||||
 | 
								status: resp.body.status
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// https://tools.ietf.org/html/draft-ietf-acme-acme-12#section-7.1.3
 | 
				
			||||||
 | 
							// Possible values are: "pending" => ("invalid" || "ready") => "processing" => "valid"
 | 
				
			||||||
 | 
							if ('valid' === resp.body.status) {
 | 
				
			||||||
 | 
								var voucher = resp.body;
 | 
				
			||||||
 | 
								voucher._certificateUrl = resp.body.certificate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								return voucher;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if ('processing' === resp.body.status) {
 | 
				
			||||||
 | 
								return ACME._wait().then(pollStatus);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (me.debug) {
 | 
				
			||||||
 | 
								console.debug(
 | 
				
			||||||
 | 
									'Error: bad status:\n' + JSON.stringify(resp.body, null, 2)
 | 
				
			||||||
 | 
								);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if ('pending' === resp.body.status) {
 | 
				
			||||||
 | 
								return Promise.reject(
 | 
				
			||||||
 | 
									new Error(
 | 
				
			||||||
 | 
										"Did not finalize order: status 'pending'." +
 | 
				
			||||||
 | 
											' Best guess: You have not accepted at least one challenge for each domain:\n' +
 | 
				
			||||||
 | 
											"Requested: '" +
 | 
				
			||||||
 | 
											options.domains.join(', ') +
 | 
				
			||||||
 | 
											"'\n" +
 | 
				
			||||||
 | 
											"Validated: '" +
 | 
				
			||||||
 | 
											verifieds.join(', ') +
 | 
				
			||||||
 | 
											"'\n" +
 | 
				
			||||||
 | 
											JSON.stringify(resp.body, null, 2)
 | 
				
			||||||
 | 
									)
 | 
				
			||||||
 | 
								);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if ('invalid' === resp.body.status) {
 | 
				
			||||||
 | 
								return Promise.reject(
 | 
				
			||||||
 | 
									E.ORDER_INVALID(options, verifieds, resp)
 | 
				
			||||||
 | 
								);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if ('ready' === resp.body.status) {
 | 
				
			||||||
 | 
								return Promise.reject(
 | 
				
			||||||
 | 
									E.DOUBLE_READY_ORDER(options, verifieds, resp)
 | 
				
			||||||
 | 
								);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return Promise.reject(
 | 
				
			||||||
 | 
								E.UNHANDLED_ORDER_STATUS(options, verifieds, resp)
 | 
				
			||||||
 | 
							);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						function pollStatus() {
 | 
				
			||||||
 | 
							return U._jwsRequest(me, {
 | 
				
			||||||
 | 
								accountKey: options.accountKey,
 | 
				
			||||||
 | 
								url: order._orderUrl,
 | 
				
			||||||
 | 
								protected: { kid: kid },
 | 
				
			||||||
 | 
								payload: Enc.binToBuf('')
 | 
				
			||||||
 | 
							}).then(processResponse);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						function finalizeOrder() {
 | 
				
			||||||
		//#console.debug('[ACME.js] pollCert:', order._finalizeUrl);
 | 
							//#console.debug('[ACME.js] pollCert:', order._finalizeUrl);
 | 
				
			||||||
		return U._jwsRequest(me, {
 | 
							return U._jwsRequest(me, {
 | 
				
			||||||
			accountKey: options.accountKey,
 | 
								accountKey: options.accountKey,
 | 
				
			||||||
			url: order._finalizeUrl,
 | 
								url: order._finalizeUrl,
 | 
				
			||||||
			protected: { kid: kid },
 | 
								protected: { kid: kid },
 | 
				
			||||||
			payload: Enc.strToBuf(payload)
 | 
								payload: Enc.strToBuf(payload)
 | 
				
			||||||
		}).then(function (resp) {
 | 
							}).then(processResponse);
 | 
				
			||||||
			ACME._notify(me, options, 'certificate_status', {
 | 
					 | 
				
			||||||
				subject: options.domains[0],
 | 
					 | 
				
			||||||
				status: resp.body.status
 | 
					 | 
				
			||||||
			});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			// https://tools.ietf.org/html/draft-ietf-acme-acme-12#section-7.1.3
 | 
					 | 
				
			||||||
			// Possible values are: "pending" => ("invalid" || "ready") => "processing" => "valid"
 | 
					 | 
				
			||||||
			if ('valid' === resp.body.status) {
 | 
					 | 
				
			||||||
				var voucher = resp.body;
 | 
					 | 
				
			||||||
				voucher._certificateUrl = resp.body.certificate;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				return voucher;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if ('processing' === resp.body.status) {
 | 
					 | 
				
			||||||
				return ACME._wait().then(pollCert);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if (me.debug) {
 | 
					 | 
				
			||||||
				console.debug(
 | 
					 | 
				
			||||||
					'Error: bad status:\n' + JSON.stringify(resp.body, null, 2)
 | 
					 | 
				
			||||||
				);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if ('pending' === resp.body.status) {
 | 
					 | 
				
			||||||
				return Promise.reject(
 | 
					 | 
				
			||||||
					new Error(
 | 
					 | 
				
			||||||
						"Did not finalize order: status 'pending'." +
 | 
					 | 
				
			||||||
							' Best guess: You have not accepted at least one challenge for each domain:\n' +
 | 
					 | 
				
			||||||
							"Requested: '" +
 | 
					 | 
				
			||||||
							options.domains.join(', ') +
 | 
					 | 
				
			||||||
							"'\n" +
 | 
					 | 
				
			||||||
							"Validated: '" +
 | 
					 | 
				
			||||||
							verifieds.join(', ') +
 | 
					 | 
				
			||||||
							"'\n" +
 | 
					 | 
				
			||||||
							JSON.stringify(resp.body, null, 2)
 | 
					 | 
				
			||||||
					)
 | 
					 | 
				
			||||||
				);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if ('invalid' === resp.body.status) {
 | 
					 | 
				
			||||||
				return Promise.reject(
 | 
					 | 
				
			||||||
					E.ORDER_INVALID(options, verifieds, resp)
 | 
					 | 
				
			||||||
				);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if ('ready' === resp.body.status) {
 | 
					 | 
				
			||||||
				return Promise.reject(
 | 
					 | 
				
			||||||
					E.DOUBLE_READY_ORDER(options, verifieds, resp)
 | 
					 | 
				
			||||||
				);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			return Promise.reject(
 | 
					 | 
				
			||||||
				E.UNHANDLED_ORDER_STATUS(options, verifieds, resp)
 | 
					 | 
				
			||||||
			);
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return pollCert();
 | 
						return finalizeOrder();
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ACME._redeemCert = function (me, options, kid, voucher) {
 | 
					ACME._redeemCert = function (me, options, kid, voucher) {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user