cleanup and bugfixes

This commit is contained in:
AJ ONeal 2019-10-06 01:22:18 -06:00
parent 24c3633d75
commit 499ac7f8ea
4 changed files with 71 additions and 37 deletions

View File

@ -354,7 +354,6 @@ ACME._testChallengeOptions = function() {
]; ];
}; };
ACME._testChallenges = function(me, options) { ACME._testChallenges = function(me, options) {
console.log('[debug] testChallenges');
var CHECK_DELAY = 0; var CHECK_DELAY = 0;
// memoized so that it doesn't run until it's first called // 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 ACME._wait(CHECK_DELAY).then(function() {
return Promise.all( return Promise.all(
auths.map(function(auth) { auths.map(function(auth) {
return ACME.challengeTests[auth.type](me, auth).then( return ACME.challengeTests[auth.type](me, auth)
function(result) { .then(function(result) {
// not a blocker // not a blocker
ACME._removeChallenge(me, options, auth); ACME._removeChallenge(me, options, auth);
return result; 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); return ACME._wait(RETRY_INTERVAL).then(respondToChallenge);
} }
if ('valid' === resp.body.status) { // REMOVE DNS records as soon as the state is non-processing
if (me.debug) {
console.debug('VALID !!!!!!!!!!!!!!!! poll: valid');
}
try { try {
ACME._removeChallenge(me, options, auth); ACME._removeChallenge(me, options, auth);
} catch (e) {} } catch (e) {}
if ('valid' === resp.body.status) {
if (me.debug) {
console.debug('poll: valid');
}
return resp.body; return resp.body;
} }
@ -1126,7 +1130,6 @@ ACME._getCertificate = function(me, options) {
challenge, challenge,
false false
).then(function(auth) { ).then(function(auth) {
console.log('ADD DUBIOUS AUTH');
auths.push(auth); auths.push(auth);
return ACME._setChallenge( return ACME._setChallenge(
me, me,
@ -1151,7 +1154,6 @@ ACME._getCertificate = function(me, options) {
} }
function checkNext() { function checkNext() {
console.log('CONSUME DUBIOUS AUTH', auths.length);
var auth = auths.shift(); var auth = auths.shift();
if (!auth) { if (!auth) {
return; return;
@ -1161,20 +1163,17 @@ ACME._getCertificate = function(me, options) {
// not so much "valid" as "not invalid" // not so much "valid" as "not invalid"
// but in this case we can't confirm either way // but in this case we can't confirm either way
validAuths.push(auth); validAuths.push(auth);
console.log('ADD VALID AUTH (skip)', validAuths.length);
return checkNext(); return checkNext();
} }
return ACME.challengeTests[auth.type](me, auth) return ACME.challengeTests[auth.type](me, auth)
.then(function() { .then(function() {
console.log('ADD VALID AUTH');
validAuths.push(auth); validAuths.push(auth);
}) })
.then(checkNext); .then(checkNext);
} }
function presentNext() { function presentNext() {
console.log('CONSUME VALID AUTH', validAuths.length);
var auth = validAuths.shift(); var auth = validAuths.shift();
if (!auth) { if (!auth) {
return; return;
@ -1535,15 +1534,21 @@ ACME._removeChallenge = function(me, options, auth) {
var challengers = options.challenges || {}; var challengers = options.challenges || {};
var removeChallenge = var removeChallenge =
challengers[auth.type] && challengers[auth.type].remove; challengers[auth.type] && challengers[auth.type].remove;
if (!removeChallenge) {
throw new Error('challenge plugin is missing remove()');
}
if (1 === removeChallenge.length) { if (1 === removeChallenge.length) {
return Promise.resolve(removeChallenge(auth)).then( return Promise.resolve(removeChallenge(auth)).then(
function() {}, function() {},
function() {} function() {}
); );
} else if (2 === removeChallenge.length) { } else if (2 === removeChallenge.length) {
return new Promise(function(resolve) {
removeChallenge(auth, function(err) { removeChallenge(auth, function(err) {
resolve();
return err; return err;
}); });
});
} else { } else {
throw new Error( throw new Error(
"Bad function signature for '" + auth.type + "' challenge.remove()" "Bad function signature for '" + auth.type + "' challenge.remove()"

View File

@ -216,9 +216,7 @@ EC.__thumbprint = function(jwk) {
'","y":"' + '","y":"' +
jwk.y + jwk.y +
'"}'; '"}';
console.log('[debug] EC', alg, payload);
return sha2.sum(alg, payload).then(function(hash) { return sha2.sum(alg, payload).then(function(hash) {
console.log('[debug] EC hash', hash);
return Enc.bufToUrlBase64(Uint8Array.from(hash)); return Enc.bufToUrlBase64(Uint8Array.from(hash));
}); });
}; };

View File

@ -76,13 +76,10 @@ Keypairs.neuter = function(opts) {
}; };
Keypairs.thumbprint = function(opts) { Keypairs.thumbprint = function(opts) {
//console.log('[debug]', new Error('NOT_ERROR').stack);
return Promise.resolve().then(function() { return Promise.resolve().then(function() {
if (/EC/i.test(opts.jwk.kty)) { if (/EC/i.test(opts.jwk.kty)) {
console.log('[debug] EC thumbprint');
return Eckles.thumbprint(opts); return Eckles.thumbprint(opts);
} else { } else {
console.log('[debug] RSA thumbprint');
return Rasha.thumbprint(opts); return Rasha.thumbprint(opts);
} }
}); });
@ -122,7 +119,6 @@ Keypairs.publish = function(opts) {
// JWT a.k.a. JWS with Claims using Compact Serialization // JWT a.k.a. JWS with Claims using Compact Serialization
Keypairs.signJwt = function(opts) { Keypairs.signJwt = function(opts) {
console.log('[debug] signJwt');
return Keypairs.thumbprint({ jwk: opts.jwk }).then(function(thumb) { return Keypairs.thumbprint({ jwk: opts.jwk }).then(function(thumb) {
var header = opts.header || {}; var header = opts.header || {};
var claims = JSON.parse(JSON.stringify(opts.claims || {})); var claims = JSON.parse(JSON.stringify(opts.claims || {}));

View File

@ -4,7 +4,9 @@ require('dotenv').config();
var ACME = require('../'); var ACME = require('../');
var Keypairs = require('../lib/keypairs.js'); 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 // TODO exec npm install --save-dev CHALLENGE_MODULE
@ -13,14 +15,42 @@ var config = {
email: process.env.SUBSCRIBER_EMAIL, email: process.env.SUBSCRIBER_EMAIL,
domain: process.env.BASE_DOMAIN, domain: process.env.BASE_DOMAIN,
challengeType: process.env.CHALLENGE_TYPE, challengeType: process.env.CHALLENGE_TYPE,
challengeModule: process.env.CHALLENGE_MODULE, challengeModule: process.env.CHALLENGE_PLUGIN,
challengeOptions: JSON.parse(process.env.CHALLENGE_OPTIONS) challengeOptions: JSON.parse(process.env.CHALLENGE_OPTIONS)
}; };
config.debug = !/^PROD/i.test(config.env); config.debug = !/^PROD/i.test(config.env);
config.challenger = require('acme-' + var pluginPrefix = 'acme-' + config.challengeType + '-';
config.challengeType + var pluginName = config.challengeModule;
'-' + var plugin;
config.challengeModule).create(config.challengeOptions);
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) { if (!config.challengeType || !config.domain) {
console.error( console.error(
new Error('Missing config variables. Check you .env and the docs') new Error('Missing config variables. Check you .env and the docs')
@ -33,7 +63,7 @@ if (!config.challengeType || !config.domain) {
var challenges = {}; var challenges = {};
challenges[config.challengeType] = config.challenger; challenges[config.challengeType] = config.challenger;
async function happyPath() { async function happyPath(accKty, srvKty, rnd) {
var agreed = false; var agreed = false;
var metadata = await acme.init( var metadata = await acme.init(
'https://acme-staging-v02.api.letsencrypt.org/directory' 'https://acme-staging-v02.api.letsencrypt.org/directory'
@ -47,8 +77,7 @@ async function happyPath() {
console.info(); console.info();
} }
// EC for account (but RSA for cert, for testing both) var accountKeypair = await Keypairs.generate({ kty: accKty });
var accountKeypair = await Keypairs.generate({ kty: 'EC' });
if (config.debug) { if (config.debug) {
console.info('Account Key Created'); console.info('Account Key Created');
console.info(JSON.stringify(accountKeypair, null, 2)); 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'); 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) { if (config.debug) {
console.info('Server Key Created'); console.info('Server Key Created');
console.info(JSON.stringify(serverKeypair, null, 2)); console.info(JSON.stringify(serverKeypair, null, 2));
@ -91,7 +120,7 @@ async function happyPath() {
console.info(); console.info();
} }
var domains = randomDomains(); var domains = randomDomains(rnd);
if (config.debug) { if (config.debug) {
console.info('Get certificates for random domains:'); console.info('Get certificates for random domains:');
console.info(domains); console.info(domains);
@ -107,6 +136,7 @@ async function happyPath() {
if (config.debug) { if (config.debug) {
console.info('Got SSL Certificate:'); console.info('Got SSL Certificate:');
console.info(Object.keys(results));
console.info(results.expires); console.info(results.expires);
console.info(results.cert); console.info(results.cert);
console.info(results.chain); console.info(results.chain);
@ -115,17 +145,22 @@ async function happyPath() {
} }
} }
happyPath() // Try EC + RSA
var rnd = random();
happyPath('EC', 'RSA', rnd)
.then(function() { .then(function() {
// Now try RSA + EC
rnd = random();
return happyPath('RSA', 'EC', rnd).then(function() {
console.info('success'); console.info('success');
});
}) })
.catch(function(err) { .catch(function(err) {
console.error('Error:'); console.error('Error:');
console.error(err.stack); console.error(err.stack);
}); });
function randomDomains() { function randomDomains(rnd) {
var rnd = random();
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 pre + '-' + rnd + '.' + config.domain; return pre + '-' + rnd + '.' + config.domain;