From 499ac7f8eacdd2301980e55838f61e6c704fa826 Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Sun, 6 Oct 2019 01:22:18 -0600 Subject: [PATCH] cleanup and bugfixes --- lib/acme.js | 37 ++++++++++++++++------------ lib/ecdsa.js | 2 -- lib/keypairs.js | 4 --- tests/index.js | 65 +++++++++++++++++++++++++++++++++++++------------ 4 files changed, 71 insertions(+), 37 deletions(-) diff --git a/lib/acme.js b/lib/acme.js index 6c20a34..56f6d2b 100644 --- a/lib/acme.js +++ b/lib/acme.js @@ -354,7 +354,6 @@ ACME._testChallengeOptions = function() { ]; }; ACME._testChallenges = function(me, options) { - console.log('[debug] testChallenges'); var CHECK_DELAY = 0; // memoized so that it doesn't run until it's first called @@ -461,13 +460,16 @@ ACME._testChallenges = function(me, options) { return ACME._wait(CHECK_DELAY).then(function() { return Promise.all( auths.map(function(auth) { - return ACME.challengeTests[auth.type](me, auth).then( - function(result) { + return ACME.challengeTests[auth.type](me, auth) + .then(function(result) { // not a blocker ACME._removeChallenge(me, options, auth); return result; - } - ); + }) + .catch(function(err) { + ACME._removeChallenge(me, options, auth); + throw err; + }); }) ); }); @@ -671,14 +673,16 @@ ACME._postChallenge = function(me, options, auth) { return ACME._wait(RETRY_INTERVAL).then(respondToChallenge); } + // REMOVE DNS records as soon as the state is non-processing + try { + ACME._removeChallenge(me, options, auth); + } catch (e) {} + if ('valid' === resp.body.status) { if (me.debug) { - console.debug('VALID !!!!!!!!!!!!!!!! poll: valid'); + console.debug('poll: valid'); } - try { - ACME._removeChallenge(me, options, auth); - } catch (e) {} return resp.body; } @@ -1126,7 +1130,6 @@ ACME._getCertificate = function(me, options) { challenge, false ).then(function(auth) { - console.log('ADD DUBIOUS AUTH'); auths.push(auth); return ACME._setChallenge( me, @@ -1151,7 +1154,6 @@ ACME._getCertificate = function(me, options) { } function checkNext() { - console.log('CONSUME DUBIOUS AUTH', auths.length); var auth = auths.shift(); if (!auth) { return; @@ -1161,20 +1163,17 @@ ACME._getCertificate = function(me, options) { // not so much "valid" as "not invalid" // but in this case we can't confirm either way validAuths.push(auth); - console.log('ADD VALID AUTH (skip)', validAuths.length); return checkNext(); } return ACME.challengeTests[auth.type](me, auth) .then(function() { - console.log('ADD VALID AUTH'); validAuths.push(auth); }) .then(checkNext); } function presentNext() { - console.log('CONSUME VALID AUTH', validAuths.length); var auth = validAuths.shift(); if (!auth) { return; @@ -1535,14 +1534,20 @@ ACME._removeChallenge = function(me, options, auth) { var challengers = options.challenges || {}; var removeChallenge = challengers[auth.type] && challengers[auth.type].remove; + if (!removeChallenge) { + throw new Error('challenge plugin is missing remove()'); + } if (1 === removeChallenge.length) { return Promise.resolve(removeChallenge(auth)).then( function() {}, function() {} ); } else if (2 === removeChallenge.length) { - removeChallenge(auth, function(err) { - return err; + return new Promise(function(resolve) { + removeChallenge(auth, function(err) { + resolve(); + return err; + }); }); } else { throw new Error( diff --git a/lib/ecdsa.js b/lib/ecdsa.js index 9052bd0..4879937 100644 --- a/lib/ecdsa.js +++ b/lib/ecdsa.js @@ -216,9 +216,7 @@ EC.__thumbprint = function(jwk) { '","y":"' + jwk.y + '"}'; - console.log('[debug] EC', alg, payload); return sha2.sum(alg, payload).then(function(hash) { - console.log('[debug] EC hash', hash); return Enc.bufToUrlBase64(Uint8Array.from(hash)); }); }; diff --git a/lib/keypairs.js b/lib/keypairs.js index 6bd5c8a..601e662 100644 --- a/lib/keypairs.js +++ b/lib/keypairs.js @@ -76,13 +76,10 @@ Keypairs.neuter = function(opts) { }; Keypairs.thumbprint = function(opts) { - //console.log('[debug]', new Error('NOT_ERROR').stack); return Promise.resolve().then(function() { if (/EC/i.test(opts.jwk.kty)) { - console.log('[debug] EC thumbprint'); return Eckles.thumbprint(opts); } else { - console.log('[debug] RSA thumbprint'); return Rasha.thumbprint(opts); } }); @@ -122,7 +119,6 @@ Keypairs.publish = function(opts) { // JWT a.k.a. JWS with Claims using Compact Serialization Keypairs.signJwt = function(opts) { - console.log('[debug] signJwt'); return Keypairs.thumbprint({ jwk: opts.jwk }).then(function(thumb) { var header = opts.header || {}; var claims = JSON.parse(JSON.stringify(opts.claims || {})); diff --git a/tests/index.js b/tests/index.js index 315f5bf..36610e8 100644 --- a/tests/index.js +++ b/tests/index.js @@ -4,7 +4,9 @@ require('dotenv').config(); var ACME = require('../'); var Keypairs = require('../lib/keypairs.js'); -var acme = ACME.create({ debug: true }); +var acme = ACME.create({ + // debug: true +}); // TODO exec npm install --save-dev CHALLENGE_MODULE @@ -13,14 +15,42 @@ var config = { email: process.env.SUBSCRIBER_EMAIL, domain: process.env.BASE_DOMAIN, challengeType: process.env.CHALLENGE_TYPE, - challengeModule: process.env.CHALLENGE_MODULE, + challengeModule: process.env.CHALLENGE_PLUGIN, challengeOptions: JSON.parse(process.env.CHALLENGE_OPTIONS) }; config.debug = !/^PROD/i.test(config.env); -config.challenger = require('acme-' + - config.challengeType + - '-' + - config.challengeModule).create(config.challengeOptions); +var pluginPrefix = 'acme-' + config.challengeType + '-'; +var pluginName = config.challengeModule; +var plugin; + +function badPlugin(err) { + if ('MODULE_NOT_FOUND' !== err.code) { + console.error(err); + return; + } + console.error("Couldn't find '" + pluginName + "'. Is it installed?"); + console.error("\tnpm install --save-dev '" + pluginName + "'"); +} +try { + plugin = require(pluginName); +} catch (err) { + if ( + 'MODULE_NOT_FOUND' !== err.code || + 0 === pluginName.indexOf(pluginPrefix) + ) { + badPlugin(err); + process.exit(1); + } + try { + pluginName = pluginPrefix + pluginName; + plugin = require(pluginName); + } catch (e) { + badPlugin(e); + process.exit(1); + } +} + +config.challenger = plugin.create(config.challengeOptions); if (!config.challengeType || !config.domain) { console.error( new Error('Missing config variables. Check you .env and the docs') @@ -33,7 +63,7 @@ if (!config.challengeType || !config.domain) { var challenges = {}; challenges[config.challengeType] = config.challenger; -async function happyPath() { +async function happyPath(accKty, srvKty, rnd) { var agreed = false; var metadata = await acme.init( 'https://acme-staging-v02.api.letsencrypt.org/directory' @@ -47,8 +77,7 @@ async function happyPath() { console.info(); } - // EC for account (but RSA for cert, for testing both) - var accountKeypair = await Keypairs.generate({ kty: 'EC' }); + var accountKeypair = await Keypairs.generate({ kty: accKty }); if (config.debug) { console.info('Account Key Created'); console.info(JSON.stringify(accountKeypair, null, 2)); @@ -83,7 +112,7 @@ async function happyPath() { throw new Error('Failed to ask the user to agree to terms'); } - var serverKeypair = await Keypairs.generate({ kty: 'RSA' }); + var serverKeypair = await Keypairs.generate({ kty: srvKty }); if (config.debug) { console.info('Server Key Created'); console.info(JSON.stringify(serverKeypair, null, 2)); @@ -91,7 +120,7 @@ async function happyPath() { console.info(); } - var domains = randomDomains(); + var domains = randomDomains(rnd); if (config.debug) { console.info('Get certificates for random domains:'); console.info(domains); @@ -107,6 +136,7 @@ async function happyPath() { if (config.debug) { console.info('Got SSL Certificate:'); + console.info(Object.keys(results)); console.info(results.expires); console.info(results.cert); console.info(results.chain); @@ -115,17 +145,22 @@ async function happyPath() { } } -happyPath() +// Try EC + RSA +var rnd = random(); +happyPath('EC', 'RSA', rnd) .then(function() { - console.info('success'); + // Now try RSA + EC + rnd = random(); + return happyPath('RSA', 'EC', rnd).then(function() { + console.info('success'); + }); }) .catch(function(err) { console.error('Error:'); console.error(err.stack); }); -function randomDomains() { - var rnd = random(); +function randomDomains(rnd) { return ['foo-acmejs', 'bar-acmejs', '*.baz-acmejs', 'baz-acmejs'].map( function(pre) { return pre + '-' + rnd + '.' + config.domain;