diff --git a/lib/acme-client.js b/lib/acme-client.js index 1bb3794..528f975 100644 --- a/lib/acme-client.js +++ b/lib/acme-client.js @@ -8,13 +8,17 @@ module.exports.create = function (deps) { - var NOOP=function () {}; + var NOOP=function () { + }; var log=NOOP; var request=require('request'); var RSA = deps.RSA; var generateSignature = RSA.signJws; function Acme(keypair) { + if (!keypair) { + throw new Error("no keypair given. that's bad"); + } if ('string' === typeof keypair) { // backwards compat keypair = RSA.import({ privateKeyPem: keypair }); @@ -59,14 +63,16 @@ module.exports.create = function (deps) { log('Using nonce: '+this.nonces[0]); payload=JSON.stringify(body, null, 2); jws=generateSignature( - this.keypair, new Buffer(payload), this.nonces.shift() + self.keypair, new Buffer(payload), this.nonces.shift() ); signed=JSON.stringify(jws, null, 2); log('Posting to '+url); - log(signed.green); - log('Payload:'+payload.blue); + log(signed); + log('Payload:'+payload); +//process.exit(1); +//return; return request.post({ url:url, body:signed, @@ -80,22 +86,22 @@ module.exports.create = function (deps) { return cb(err); } if (res) { - log(('HTTP/1.1 '+res.statusCode).yellow); + log(('HTTP/1.1 '+res.statusCode)); } Object.keys(res.headers).forEach(function(key) { var value, upcased; value=res.headers[key]; upcased=key.charAt(0).toUpperCase()+key.slice(1); - log((upcased+': '+value).yellow); + log((upcased+': '+value)); }); if (body && !body.toString().match(/[^\x00-\x7F]/)) { try { parsed=JSON.parse(body); - log(JSON.stringify(parsed, null, 2).cyan); + log(JSON.stringify(parsed, null, 2)); } catch(err) { - log(body.toString().cyan); + log(body.toString()); } } diff --git a/lib/get-certificate.js b/lib/get-certificate.js index eaf9e6f..7885a90 100644 --- a/lib/get-certificate.js +++ b/lib/get-certificate.js @@ -79,13 +79,13 @@ module.exports.create = function (deps) { } function getChallenges(domain) { - state.domain=domain; + state.domain = domain; state.acme.post(state.newAuthzUrl, { - resource:'new-authz', - identifier:{ - type:'dns', - value:state.domain, + resource: 'new-authz', + identifier: { + type: 'dns', + value: state.domain, } }, function (err, res, body) { if (!err && res.body) { @@ -101,6 +101,12 @@ module.exports.create = function (deps) { } function getReadyToValidate(err, res, body) { + var links; + var authz; + var httpChallenges; + var challenge; + var thumbprint; + var keyAuthorization; function challengeDone(err) { if (err) { @@ -115,8 +121,8 @@ module.exports.create = function (deps) { } state.acme.post(state.responseUrl, { - resource:'challenge', - keyAuthorization:keyAuthorization + resource: 'challenge', + keyAuthorization: keyAuthorization }, function(err, res, body) { if (!err && res.body) { try { @@ -134,8 +140,6 @@ module.exports.create = function (deps) { }); } - var links, authz, httpChallenges, challenge, thumbprint, keyAuthorization; - if (err) { return handleErr(err); } @@ -144,30 +148,30 @@ module.exports.create = function (deps) { return handleErr(null, 'Authorization request failed ('+res.statusCode+')'); } - links=Acme.parseLink(res.headers.link); + links = Acme.parseLink(res.headers.link); if (!links || !('next' in links)) { return handleErr(err, 'Server didn\'t provide information to proceed (2)'); } - state.authorizationUrl=res.headers.location; - state.newCertUrl=links.next; + state.authorizationUrl = res.headers.location; + state.newCertUrl = links.next; - authz=body; + authz = body; - httpChallenges=authz.challenges.filter(function(x) { - return x.type==='http-01'; + httpChallenges = authz.challenges.filter(function(x) { + return x.type === options.challengeType; }); - if (httpChallenges.length===0) { + if (httpChallenges.length === 0) { return handleErr(null, 'Server didn\'t offer any challenge we can handle.'); } - challenge=httpChallenges[0]; + challenge = httpChallenges[0]; - thumbprint=RSA.thumbprint(state.accountKeypair); - keyAuthorization=challenge.token+'.'+thumbprint; - state.responseUrl=challenge.uri; + thumbprint = RSA.thumbprint(state.accountKeypair); + keyAuthorization = challenge.token + '.' + thumbprint; + + state.responseUrl = challenge.uri; options.setChallenge(state.domain, challenge.token, keyAuthorization, challengeDone); - } function ensureValidation(err, res, body, unlink) { @@ -224,7 +228,7 @@ module.exports.create = function (deps) { } function getCertificate() { - var csr=RSA.generateCsrWeb64(RSA.exportPrivateKeyPem(state.certKeypair), state.validatedDomains); + var csr=RSA.generateCsrWeb64(state.certKeypair, state.validatedDomains); log('Requesting certificate...'); state.acme.post(state.newCertUrl, { resource:'new-cert', @@ -332,7 +336,7 @@ module.exports.create = function (deps) { return; } - privkeyPem = RSA.exportPrivateKeyPem(state.certKeypair); + privkeyPem = RSA.exportPrivatePem(state.certKeypair); cb(null, { cert: certPem // TODO privkey isn't necessary @@ -358,6 +362,12 @@ module.exports.create = function (deps) { , newCertUrl: options.newCertUrl }; + if (!options.challengeType) { + options.challengeType = 'http-01'; + } + if (-1 === [ 'http-01', 'tls-sni-01', 'dns-01' ].indexOf(options.challengeType)) { + return handleErr(new Error("options.challengeType '" + options.challengeType + "' is not yet supported")); + } if (!options.newAuthzUrl) { return handleErr(new Error("options.newAuthzUrl must be the authorization url")); } @@ -390,9 +400,9 @@ module.exports.create = function (deps) { state.domains = options.domains.slice(0); // copy array try { - state.acme = new Acme(state.accountKeypair); state.accountKeypair = options.accountKeypair; state.certKeypair = options.domainKeypair; + state.acme = new Acme(state.accountKeypair); } catch(err) { return handleErr(err, 'Failed to parse privateKey'); }