show challenges
This commit is contained in:
		
							parent
							
								
									ec9a2606f6
								
							
						
					
					
						commit
						d646edf045
					
				
							
								
								
									
										11
									
								
								index.html
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								index.html
									
									
									
									
									
								
							| @ -25,10 +25,12 @@ | |||||||
| 
 | 
 | ||||||
|     <!-- Step 3 Set Challanges --> |     <!-- Step 3 Set Challanges --> | ||||||
|     <form class="js-acme-form js-acme-form-challenges"> |     <form class="js-acme-form js-acme-form-challenges"> | ||||||
|  |       <div class="js-acme-challenges"> | ||||||
|  | 
 | ||||||
|       <label>How will you validate your domain?</label> |       <label>How will you validate your domain?</label> | ||||||
|       <label><input class="js-acme-challenge-type" type="radio" value="http-01" checked required> |       <label><input class="js-acme-challenge-type" name="acme-challenge-type" type="radio" value="http-01" checked required> | ||||||
|         File Upload to HTTP Web Server</label> |         File Upload to HTTP Web Server</label> | ||||||
|       <label><input class="js-acme-challenge-type" type="radio" value="dns-01" required> |       <label><input class="js-acme-challenge-type" name="acme-challenge-type" type="radio" value="dns-01" required> | ||||||
|         TXT Records on DNS Name Server</label> |         TXT Records on DNS Name Server</label> | ||||||
| 
 | 
 | ||||||
|       Verify Domains & Sub-Domains: |       Verify Domains & Sub-Domains: | ||||||
| @ -66,11 +68,12 @@ | |||||||
|           </tr> |           </tr> | ||||||
|         </tbody> |         </tbody> | ||||||
|       </table> |       </table> | ||||||
|  |       </div> | ||||||
| 
 | 
 | ||||||
|       <div class="js-acme-wildcards"> |       <div class="js-acme-wildcard"> | ||||||
|         Verify Wildcard Domains: |         Verify Wildcard Domains: | ||||||
| 
 | 
 | ||||||
|         <table class="js-acme-table-wildcards"> |         <table class="js-acme-table-wildcard"> | ||||||
|           <thead> |           <thead> | ||||||
|             <tr> |             <tr> | ||||||
|               <th>Hostname</th> |               <th>Hostname</th> | ||||||
|  | |||||||
							
								
								
									
										179
									
								
								js/app.js
									
									
									
									
									
								
							
							
						
						
									
										179
									
								
								js/app.js
									
									
									
									
									
								
							| @ -18,13 +18,32 @@ | |||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   function submitForm(ev) { | ||||||
|  |     steps[i].submit(ev); | ||||||
|  |     i += 1; | ||||||
|  |   } | ||||||
|   $qsa('.js-acme-form').forEach(function ($el) { |   $qsa('.js-acme-form').forEach(function ($el) { | ||||||
|     $el.addEventListener('submit', function (ev) { |     $el.addEventListener('submit', function (ev) { | ||||||
|       ev.preventDefault(); |       ev.preventDefault(); | ||||||
|       steps[i].submit(ev); |       submitForm(ev); | ||||||
|       i += 1; |  | ||||||
|     }); |     }); | ||||||
|   }); |   }); | ||||||
|  |   function updateChallengeType() { | ||||||
|  |     var input = this || $qs('.js-acme-challenge-type'); | ||||||
|  |     console.log('ch type radio:', input.value); | ||||||
|  |     $qs('.js-acme-table-wildcard').hidden = true; | ||||||
|  |     $qs('.js-acme-table-http-01').hidden = true; | ||||||
|  |     $qs('.js-acme-table-dns-01').hidden = true; | ||||||
|  |     if (info.challenges.wildcard) { | ||||||
|  |       $qs('.js-acme-table-wildcard').hidden = false; | ||||||
|  |     } | ||||||
|  |     if (info.challenges[input.value]) { | ||||||
|  |       $qs('.js-acme-table-' + input.value).hidden = false; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   $qsa('.js-acme-challenge-type').forEach(function ($el) { | ||||||
|  |     $el.addEventListener('change', updateChallengeType); | ||||||
|  |   }); | ||||||
| 
 | 
 | ||||||
|   steps[1] = function () { |   steps[1] = function () { | ||||||
|     hideForms(); |     hideForms(); | ||||||
| @ -85,6 +104,7 @@ | |||||||
|       console.log('account jwk:'); |       console.log('account jwk:'); | ||||||
|       console.log(jwk); |       console.log(jwk); | ||||||
|       delete jwk.key_ops; |       delete jwk.key_ops; | ||||||
|  |       info.jwk = jwk; | ||||||
|       return BACME.accounts.sign({ |       return BACME.accounts.sign({ | ||||||
|         jwk: jwk |         jwk: jwk | ||||||
|       , contacts: [ 'mailto:' + email ] |       , contacts: [ 'mailto:' + email ] | ||||||
| @ -117,6 +137,7 @@ | |||||||
| 
 | 
 | ||||||
|       return p2.then(function (_kid) { |       return p2.then(function (_kid) { | ||||||
|         kid = _kid; |         kid = _kid; | ||||||
|  |         info.kid = kid; | ||||||
|         return BACME.orders.sign({ |         return BACME.orders.sign({ | ||||||
|           jwk: jwk |           jwk: jwk | ||||||
|         , identifiers: info.identifiers |         , identifiers: info.identifiers | ||||||
| @ -124,13 +145,96 @@ | |||||||
|         }).then(function (signedOrder) { |         }).then(function (signedOrder) { | ||||||
|           return BACME.orders.create({ |           return BACME.orders.create({ | ||||||
|             signedOrder: signedOrder |             signedOrder: signedOrder | ||||||
|           }).then(function (/*challengeIndexes*/) { |           }).then(function (order) { | ||||||
|             return BACME.challenges.all().then(function (challenges) { |             info.finalizeUrl = order.finalize; | ||||||
|               console.log('challenges:'); |             return BACME.thumbprint({ jwk: jwk }).then(function (thumbprint) { | ||||||
|               console.log(challenges); |               return BACME.challenges.all().then(function (claims) { | ||||||
|               // TODO populate challenges in table
 |                 console.log('claims:'); | ||||||
|  |                 console.log(claims); | ||||||
|  |                 var obj = { 'dns-01': [], 'http-01': [], 'wildcard': [] }; | ||||||
|  |                 var map = { | ||||||
|  |                   'http-01': '.js-acme-table-http-01' | ||||||
|  |                 , 'dns-01': '.js-acme-table-dns-01' | ||||||
|  |                 , 'wildcard': '.js-acme-table-wildcard' | ||||||
|  |                 } | ||||||
|  |                 var tpls = {}; | ||||||
|  |                 info.challenges = obj; | ||||||
|  |                 Object.keys(map).forEach(function (k) { | ||||||
|  |                   var sel = map[k] + ' tbody'; | ||||||
|  |                   console.log(sel); | ||||||
|  |                   tpls[k] = $qs(sel).innerHTML; | ||||||
|  |                   $qs(map[k] + ' tbody').innerHTML = ''; | ||||||
|  |                 }); | ||||||
|  | 
 | ||||||
|  |                 // TODO make Promise-friendly
 | ||||||
|  |                 return Promise.all(claims.map(function (claim) { | ||||||
|  |                   var hostname = claim.identifier.value; | ||||||
|  |                   return Promise.all(claim.challenges.map(function (c) { | ||||||
|  |                     var keyAuth = BACME.challenges['http-01']({ | ||||||
|  |                       token: c.token | ||||||
|  |                     , thumbprint: thumbprint | ||||||
|  |                     , challengeDomain: hostname | ||||||
|  |                     }); | ||||||
|  |                     return BACME.challenges['dns-01']({ | ||||||
|  |                       keyAuth: keyAuth | ||||||
|  |                     , challengeDomain: hostname | ||||||
|  |                     }).then(function (dnsAuth) { | ||||||
|  |                       var data = { | ||||||
|  |                         type: c.type | ||||||
|  |                       , hostname: hostname | ||||||
|  |                       , url: c.url | ||||||
|  |                       , token: c.token | ||||||
|  |                       , keyAuthorization: keyAuth | ||||||
|  |                       , httpPath: keyAuth.path | ||||||
|  |                       , httpAuth: keyAuth.value | ||||||
|  |                       , dnsType: dnsAuth.type | ||||||
|  |                       , dnsHost: dnsAuth.host | ||||||
|  |                       , dnsAnswer: dnsAuth.answer | ||||||
|  |                       }; | ||||||
|  | 
 | ||||||
|  |                       obj[c.type].push(data); | ||||||
|  |                       console.log(''); | ||||||
|  |                       console.log('CHALLENGE'); | ||||||
|  |                       console.log(claim); | ||||||
|  |                       console.log(c); | ||||||
|  |                       console.log(data); | ||||||
|  |                       console.log(''); | ||||||
|  | 
 | ||||||
|  |                       if (claim.wildcard) { | ||||||
|  |                         obj.wildcard.push(data); | ||||||
|  |                         $qs(map.wildcard).innerHTML += '<tr><td>' + data.hostname + '</td><td>' + data.dnsHost + '</td><td>' + data.dnsAnswer + '</td></tr>'; | ||||||
|  |                       } else { | ||||||
|  |                         obj[data.type].push(data); | ||||||
|  |                         if ('dns-01' === data.type) { | ||||||
|  |                           $qs(map[data.type]).innerHTML += '<tr><td>' + data.hostname + '</td><td>' + data.dnsHost + '</td><td>' + data.dnsAnswer + '</td></tr>'; | ||||||
|  |                         } else if ('http-01' === data.type) { | ||||||
|  |                           $qs(map[data.type]).innerHTML += '<tr><td>' + data.hostname + '</td><td>' + data.httpPath + '</td><td>' + data.httpAuth + '</td></tr>'; | ||||||
|  |                         } else { | ||||||
|  |                           throw new Error('Unexpected type: ' + data.type); | ||||||
|  |                         } | ||||||
|  |                       } | ||||||
|  | 
 | ||||||
|  |                     }); | ||||||
|  | 
 | ||||||
|  |                   })); | ||||||
|  |                 })).then(function () { | ||||||
|  | 
 | ||||||
|  |                   // hide wildcard if no wildcard
 | ||||||
|  |                   // hide http-01 and dns-01 if only wildcard
 | ||||||
|  |                   if (!obj.wildcard.length) { | ||||||
|  |                     $qs('.js-acme-wildcard').hidden = true; | ||||||
|  |                   } | ||||||
|  |                   if (!obj['http-01'].length) { | ||||||
|  |                     $qs('.js-acme-challenges').hidden = true; | ||||||
|  |                   } | ||||||
|  | 
 | ||||||
|  |                   updateChallengeType(); | ||||||
|  | 
 | ||||||
|                   steps[i](); |                   steps[i](); | ||||||
|                 }); |                 }); | ||||||
|  | 
 | ||||||
|  |               }); | ||||||
|  |             }); | ||||||
|           }); |           }); | ||||||
|         }); |         }); | ||||||
|       }); |       }); | ||||||
| @ -144,11 +248,72 @@ | |||||||
|     hideForms(); |     hideForms(); | ||||||
|     $qs('.js-acme-form-challenges').hidden = false; |     $qs('.js-acme-form-challenges').hidden = false; | ||||||
|   }; |   }; | ||||||
|  |   steps[3].submit = function () { | ||||||
|  |     var chType = $qs('.js-acme-challenge-type').value; | ||||||
|  |     var ps = []; | ||||||
| 
 | 
 | ||||||
|  |     // do each wildcard, if any
 | ||||||
|  |     // do each challenge, by selected type only
 | ||||||
|  |     [ 'wildcard', chType].forEach(function (typ) { | ||||||
|  |       info.challenges[typ].forEach(function (ch) { | ||||||
|  |         // { jwk, challengeUrl, accountId (kid) }
 | ||||||
|  |         ps.push(BACME.challenges.accept({ | ||||||
|  |           jwk: info.jwk | ||||||
|  |         , challengeUrl: ch.url | ||||||
|  |         , accountId: info.kid | ||||||
|  |         })); | ||||||
|  |       }); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     return Promise.all(ps).then(function (results) { | ||||||
|  |       console.log('challenge status:', results); | ||||||
|  |       var polls = results.slice(0); | ||||||
|  |       var allsWell = true; | ||||||
|  | 
 | ||||||
|  |       function checkPolls() { | ||||||
|  |         return new Promise(function (resolve) { | ||||||
|  |           setTimeout(resolve, 1000); | ||||||
|  |         }).then(function () { | ||||||
|  |           return Promise.all(polls.map(function (poll) { | ||||||
|  |             return BACME.challenges.check({ challengePollUrl: poll.url }); | ||||||
|  |           })).then(function () { | ||||||
|  |             polls = polls.filter(function (poll) { | ||||||
|  |               //return 'valid' !== poll.status && 'invalid' !== poll.status;
 | ||||||
|  |               if ('pending' === poll.status) { | ||||||
|  |                 return true; | ||||||
|  |               } | ||||||
|  |               if ('valid' !== poll.status) { | ||||||
|  |                 allsWell = false; | ||||||
|  |                 console.warn('BAD POLL STATUS', poll); | ||||||
|  |               } | ||||||
|  |               // TODO show status in HTML
 | ||||||
|  |             }); | ||||||
|  | 
 | ||||||
|  |             if (polls.length) { | ||||||
|  |               return checkPolls(); | ||||||
|  |             } | ||||||
|  |             return true; | ||||||
|  |           }); | ||||||
|  |         }); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       return checkPolls().then(function () { | ||||||
|  |         if (allsWell) { | ||||||
|  |           return submitForm(); | ||||||
|  |         } | ||||||
|  |       }); | ||||||
|  |     }); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   // spinner
 | ||||||
|   steps[4] = function () { |   steps[4] = function () { | ||||||
|     hideForms(); |     hideForms(); | ||||||
|     $qs('.js-acme-form-poll').hidden = false; |     $qs('.js-acme-form-poll').hidden = false; | ||||||
|   } |   } | ||||||
|  |   steps[4].submit = function () { | ||||||
|  |     console.log('Congrats! Auto advancing...'); | ||||||
|  |     return BACME.order | ||||||
|  |   }; | ||||||
| 
 | 
 | ||||||
|   steps[5] = function () { |   steps[5] = function () { | ||||||
|     hideForms(); |     hideForms(); | ||||||
|  | |||||||
							
								
								
									
										111
									
								
								js/bacme.js
									
									
									
									
									
								
							
							
						
						
									
										111
									
								
								js/bacme.js
									
									
									
									
									
								
							| @ -289,11 +289,10 @@ BACME.orders = {}; | |||||||
| BACME.orders.sign = function (opts) { | BACME.orders.sign = function (opts) { | ||||||
| 	var payload64 = BACME._jsto64({ identifiers: opts.identifiers }); | 	var payload64 = BACME._jsto64({ identifiers: opts.identifiers }); | ||||||
| 
 | 
 | ||||||
| 	var protected64 = BACME._jsto64( |  | ||||||
| 		{ nonce: nonce, alg: 'ES256', url: orderUrl, kid: opts.kid } |  | ||||||
| 	); |  | ||||||
| 
 |  | ||||||
| 	return BACME._importKey(opts.jwk).then(function (abstractKey) { | 	return BACME._importKey(opts.jwk).then(function (abstractKey) { | ||||||
|  |     var protected64 = BACME._jsto64( | ||||||
|  |       { nonce: nonce, alg: abstractKey.meta.alg/*'ES256'*/, url: orderUrl, kid: opts.kid } | ||||||
|  |     ); | ||||||
|     console.log('abstractKey:'); |     console.log('abstractKey:'); | ||||||
|     console.log(abstractKey); |     console.log(abstractKey); | ||||||
|     return BACME._sign({ |     return BACME._sign({ | ||||||
| @ -378,7 +377,16 @@ BACME.challenges.view = function () { | |||||||
| 
 | 
 | ||||||
|       BACME._logBody(result); |       BACME._logBody(result); | ||||||
| 
 | 
 | ||||||
|       return { token: challenge.token, url: challenge.url, domain: result.identifier.value, challenges: result.challenges }; |       return { | ||||||
|  |         challenges: result.challenges | ||||||
|  |       , expires: result.expires | ||||||
|  |       , identifier: result.identifier | ||||||
|  |       , status: result.status | ||||||
|  |       , wildcard: result.wildcard | ||||||
|  |       //, token: challenge.token
 | ||||||
|  |       //, url: challenge.url
 | ||||||
|  |       //, domain: result.identifier.value,
 | ||||||
|  |       }; | ||||||
| 		}); | 		}); | ||||||
| 	}); | 	}); | ||||||
| }; | }; | ||||||
| @ -420,12 +428,13 @@ BACME.thumbprint = function (opts) { | |||||||
| 	}); | 	}); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| BACME.challenges['http-01'] = function () { | // { token, thumbprint, challengeDomain }
 | ||||||
|  | BACME.challenges['http-01'] = function (opts) { | ||||||
| 	// The contents of the key authorization file
 | 	// The contents of the key authorization file
 | ||||||
| 	keyAuth = token + '.' + thumbprint; | 	keyAuth = opts.token + '.' + opts.thumbprint; | ||||||
| 
 | 
 | ||||||
| 	// Where the key authorization file goes
 | 	// Where the key authorization file goes
 | ||||||
| 	httpPath = 'http://' + challengeDomain + '/.well-known/acme-challenge/' + token; | 	httpPath = 'http://' + opts.challengeDomain + '/.well-known/acme-challenge/' + opts.token; | ||||||
| 
 | 
 | ||||||
|   console.log("echo '" + keyAuth + "' > '" + httpPath + "'"); |   console.log("echo '" + keyAuth + "' > '" + httpPath + "'"); | ||||||
| 
 | 
 | ||||||
| @ -435,16 +444,17 @@ BACME.challenges['http-01'] = function () { | |||||||
|   }; |   }; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| BACME.challenges['dns-01'] = function () { | // { keyAuth }
 | ||||||
|  | BACME.challenges['dns-01'] = function (opts) { | ||||||
| 	return window.crypto.subtle.digest( | 	return window.crypto.subtle.digest( | ||||||
| 		{ name: "SHA-256", } | 		{ name: "SHA-256", } | ||||||
| 	, textEncoder.encode(keyAuth) | 	, textEncoder.encode(opts.keyAuth) | ||||||
| 	).then(function(hash){ | 	).then(function(hash){ | ||||||
| 		dnsAuth = btoa(Array.prototype.map.call(new Uint8Array(hash), function (ch) { | 		dnsAuth = btoa(Array.prototype.map.call(new Uint8Array(hash), function (ch) { | ||||||
| 			return String.fromCharCode(ch); | 			return String.fromCharCode(ch); | ||||||
| 		}).join('')).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/g, ''); | 		}).join('')).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/g, ''); | ||||||
| 
 | 
 | ||||||
| 		dnsRecord = '_acme-challenge.' + challengeDomain; | 		dnsRecord = '_acme-challenge.' + opts.challengeDomain; | ||||||
| 
 | 
 | ||||||
| 		console.log('DNS TXT Auth:'); | 		console.log('DNS TXT Auth:'); | ||||||
| 		// The name of the record
 | 		// The name of the record
 | ||||||
| @ -462,38 +472,30 @@ BACME.challenges['dns-01'] = function () { | |||||||
| 
 | 
 | ||||||
| var challengePollUrl; | var challengePollUrl; | ||||||
| 
 | 
 | ||||||
| BACME.challenges.accept = function () { | // { jwk, challengeUrl, accountId (kid) }
 | ||||||
|  | BACME.challenges.accept = function (opts) { | ||||||
|   var payload64 = BACME._jsto64( |   var payload64 = BACME._jsto64( | ||||||
| 		{} | 		{} | ||||||
| 	); | 	); | ||||||
| 
 | 
 | ||||||
| 	var protected64 = BACME._jsto64( |  | ||||||
| 		{ nonce: nonce, alg: 'ES256', url: challengeUrl, kid: accountId } |  | ||||||
| 	); |  | ||||||
| 
 |  | ||||||
| 	nonce = null; | 	nonce = null; | ||||||
| 	return window.crypto.subtle.sign( |   return BACME._import(opts.jwk).then(function (abstractKey) { | ||||||
| 		{ name: "ECDSA", hash: { name: "SHA-256" } } |     var protected64 = BACME._jsto64( | ||||||
| 	, accountKeypair.privateKey |       { nonce: nonce, alg: abstractKey.meta.alg/*'ES256'*/, url: opts.challengeUrl, kid: opts.accountId } | ||||||
| 	, textEncoder.encode(protected64 + '.' + payload64) |     ); | ||||||
| 	).then(function (signature) { | 		return BACME._sign({ | ||||||
| 
 |       abstractKey: abstractKey | ||||||
| 		var sig64 = btoa(Array.prototype.map.call(new Uint8Array(signature), function (ch) { |     , payload64: payload64 | ||||||
| 			return String.fromCharCode(ch); |     , protected64: protected64 | ||||||
| 		}).join('')).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/g, ''); |     }); | ||||||
| 
 |   }).then(function (signedAccept) { | ||||||
| 		var body = { |  | ||||||
| 			protected: protected64 |  | ||||||
| 		, payload: payload64 |  | ||||||
| 		, signature: sig64 |  | ||||||
| 		}; |  | ||||||
| 
 | 
 | ||||||
| 		return window.fetch( | 		return window.fetch( | ||||||
| 			challengeUrl | 			opts.challengeUrl | ||||||
| 		, { mode: 'cors' | 		, { mode: 'cors' | ||||||
| 			, method: 'POST' | 			, method: 'POST' | ||||||
| 			, headers: { 'Content-Type': 'application/jose+json' } | 			, headers: { 'Content-Type': 'application/jose+json' } | ||||||
| 			, body: JSON.stringify(body) | 			, body: JSON.stringify(signedAccept) | ||||||
| 			} | 			} | ||||||
| 		).then(function (resp) { | 		).then(function (resp) { | ||||||
|       BACME._logHeaders(resp); |       BACME._logHeaders(resp); | ||||||
| @ -504,13 +506,14 @@ BACME.challenges.accept = function () { | |||||||
| 
 | 
 | ||||||
| 				console.log('Challenge ACK:'); | 				console.log('Challenge ACK:'); | ||||||
| 				console.log(JSON.stringify(reply)); | 				console.log(JSON.stringify(reply)); | ||||||
|  |         return reply; | ||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
| 	}); | 	}); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| BACME.challenges.check = function () { | BACME.challenges.check = function (opts) { | ||||||
| 	return window.fetch(challengePollUrl, { mode: 'cors' }).then(function (resp) { | 	return window.fetch(opts.challengePollUrl, { mode: 'cors' }).then(function (resp) { | ||||||
|     BACME._logHeaders(resp); |     BACME._logHeaders(resp); | ||||||
| 		nonce = resp.headers.get('replay-nonce'); | 		nonce = resp.headers.get('replay-nonce'); | ||||||
| 
 | 
 | ||||||
| @ -558,38 +561,30 @@ BACME.orders.generateCsr = function (keypair, domains) { | |||||||
| 
 | 
 | ||||||
| var certificateUrl; | var certificateUrl; | ||||||
| 
 | 
 | ||||||
| BACME.orders.finalize = function () { | // { csr, jwk, finalizeUrl, accountId }
 | ||||||
|  | BACME.orders.finalize = function (opts) { | ||||||
| 	var payload64 = BACME._jsto64( | 	var payload64 = BACME._jsto64( | ||||||
| 		{ csr: csr } | 		{ csr: opts.csr } | ||||||
| 	); |  | ||||||
| 
 |  | ||||||
| 	var protected64 = BACME._jsto64( |  | ||||||
| 		{ nonce: nonce, alg: 'ES256', url: finalizeUrl, kid: accountId } |  | ||||||
| 	); | 	); | ||||||
| 
 | 
 | ||||||
| 	nonce = null; | 	nonce = null; | ||||||
| 	return window.crypto.subtle.sign( |   return BACME._import(opts.jwk).then(function (abstractKey) { | ||||||
| 		{ name: "ECDSA", hash: { name: "SHA-256" } } |     var protected64 = BACME._jsto64( | ||||||
| 	, accountKeypair.privateKey |       { nonce: nonce, alg: abstractKey.meta.alg/*'ES256'*/, url: opts.finalizeUrl, kid: opts.accountId } | ||||||
| 	, textEncoder.encode(protected64 + '.' + payload64) |     ); | ||||||
| 	).then(function (signature) { | 		return BACME._sign({ | ||||||
| 
 |       abstractKey: abstractKey | ||||||
| 		var sig64 = btoa(Array.prototype.map.call(new Uint8Array(signature), function (ch) { |     , payload64: payload64 | ||||||
| 			return String.fromCharCode(ch); |     , protected64: protected64 | ||||||
| 		}).join('')).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/g, ''); |     }); | ||||||
| 
 |   }).then(function (signedFinal) { | ||||||
| 		var body = { |  | ||||||
| 			protected: protected64 |  | ||||||
| 		, payload: payload64 |  | ||||||
| 		, signature: sig64 |  | ||||||
| 		}; |  | ||||||
| 
 | 
 | ||||||
| 		return window.fetch( | 		return window.fetch( | ||||||
| 			finalizeUrl | 			finalizeUrl | ||||||
| 		, { mode: 'cors' | 		, { mode: 'cors' | ||||||
| 			, method: 'POST' | 			, method: 'POST' | ||||||
| 			, headers: { 'Content-Type': 'application/jose+json' } | 			, headers: { 'Content-Type': 'application/jose+json' } | ||||||
| 			, body: JSON.stringify(body) | 			, body: JSON.stringify(signedFinal) | ||||||
| 			} | 			} | ||||||
| 		).then(function (resp) { | 		).then(function (resp) { | ||||||
|       BACME._logHeaders(resp); |       BACME._logHeaders(resp); | ||||||
| @ -598,6 +593,8 @@ BACME.orders.finalize = function () { | |||||||
| 			return resp.json().then(function (reply) { | 			return resp.json().then(function (reply) { | ||||||
| 				certificateUrl = reply.certificate; | 				certificateUrl = reply.certificate; | ||||||
|         BACME._logBody(reply); |         BACME._logBody(reply); | ||||||
|  | 
 | ||||||
|  |         return reply; | ||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
| 	}); | 	}); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user