Compare commits
2 Commits
b12a1a7ea4
...
cd48c624fa
Author | SHA1 | Date |
---|---|---|
AJ ONeal | cd48c624fa | |
AJ ONeal | 055c75cc94 |
|
@ -23,10 +23,11 @@ In progress
|
||||||
* Mar 20, 2018 - SUCCESS - got a test certificate (hard-coded)
|
* Mar 20, 2018 - SUCCESS - got a test certificate (hard-coded)
|
||||||
* Mar 21, 2018 - can now accept values (not hard coded)
|
* Mar 21, 2018 - can now accept values (not hard coded)
|
||||||
* Mar 21, 2018 - *mostly* matches le-acme-core.js API
|
* Mar 21, 2018 - *mostly* matches le-acme-core.js API
|
||||||
|
* Apr 5, 2018 - completely match api for acme v1 (le-acme-core.js)
|
||||||
|
|
||||||
Todo
|
Todo
|
||||||
|
|
||||||
* completely match api for acme v1 (le-acme-core.js)
|
* test wildcard
|
||||||
* test http and dns challenges
|
* test http and dns challenges
|
||||||
* export http and dns challenge tests
|
* export http and dns challenge tests
|
||||||
* support ECDSA keys
|
* support ECDSA keys
|
||||||
|
|
14
node.js
14
node.js
|
@ -9,6 +9,11 @@
|
||||||
var ACME = module.exports.ACME = {};
|
var ACME = module.exports.ACME = {};
|
||||||
|
|
||||||
ACME.acmeChallengePrefix = '/.well-known/acme-challenge/';
|
ACME.acmeChallengePrefix = '/.well-known/acme-challenge/';
|
||||||
|
ACME.acmeChallengeDnsPrefix = '_acme-challenge';
|
||||||
|
ACME.acmeChallengePrefixes = {
|
||||||
|
'http-01': '/.well-known/acme-challenge/'
|
||||||
|
, 'dns-01': '_acme-challenge'
|
||||||
|
};
|
||||||
|
|
||||||
ACME._getUserAgentString = function (deps) {
|
ACME._getUserAgentString = function (deps) {
|
||||||
var uaDefaults = {
|
var uaDefaults = {
|
||||||
|
@ -368,6 +373,7 @@ ACME._getCertificate = function (me, options) {
|
||||||
|
|
||||||
console.log('[acme-v2] certificates.create');
|
console.log('[acme-v2] certificates.create');
|
||||||
return ACME._getNonce(me).then(function () {
|
return ACME._getNonce(me).then(function () {
|
||||||
|
console.log("27 &#&#&#&#&#&#&&##&#&#&#&#&#&#&#&");
|
||||||
var body = {
|
var body = {
|
||||||
identifiers: options.domains.map(function (hostname) {
|
identifiers: options.domains.map(function (hostname) {
|
||||||
return { type: "dns" , value: hostname };
|
return { type: "dns" , value: hostname };
|
||||||
|
@ -401,6 +407,11 @@ ACME._getCertificate = function (me, options) {
|
||||||
me._finalize = resp.body.finalize;
|
me._finalize = resp.body.finalize;
|
||||||
//console.log('[DEBUG] finalize:', me._finalize); return;
|
//console.log('[DEBUG] finalize:', me._finalize); return;
|
||||||
|
|
||||||
|
if (!me._authorizations) {
|
||||||
|
console.log("&#&#&#&#&#&#&&##&#&#&#&#&#&#&#&");
|
||||||
|
}
|
||||||
|
console.log("47 &#&#&#&#&#&#&&##&#&#&#&#&#&#&#&");
|
||||||
|
|
||||||
//return resp.body;
|
//return resp.body;
|
||||||
return Promise.all(me._authorizations.map(function (authUrl, i) {
|
return Promise.all(me._authorizations.map(function (authUrl, i) {
|
||||||
console.log("Authorizations map #" + i);
|
console.log("Authorizations map #" + i);
|
||||||
|
@ -425,6 +436,7 @@ ACME._getCertificate = function (me, options) {
|
||||||
return ACME._postChallenge(me, options, results.identifier, challenge);
|
return ACME._postChallenge(me, options, results.identifier, challenge);
|
||||||
});
|
});
|
||||||
})).then(function () {
|
})).then(function () {
|
||||||
|
console.log("37 &#&#&#&#&#&#&&##&#&#&#&#&#&#&#&");
|
||||||
var validatedDomains = body.identifiers.map(function (ident) {
|
var validatedDomains = body.identifiers.map(function (ident) {
|
||||||
return ident.value;
|
return ident.value;
|
||||||
});
|
});
|
||||||
|
@ -444,6 +456,8 @@ ACME._getCertificate = function (me, options) {
|
||||||
ACME.create = function create(me) {
|
ACME.create = function create(me) {
|
||||||
if (!me) { me = {}; }
|
if (!me) { me = {}; }
|
||||||
me.acmeChallengePrefix = ACME.acmeChallengePrefix;
|
me.acmeChallengePrefix = ACME.acmeChallengePrefix;
|
||||||
|
me.acmeChallengeDnsPrefix = ACME.acmeChallengeDnsPrefix;
|
||||||
|
me.acmeChallengePrefixes = ACME.acmeChallengePrefixes;
|
||||||
me.RSA = me.RSA || require('rsa-compat').RSA;
|
me.RSA = me.RSA || require('rsa-compat').RSA;
|
||||||
me.request = me.request || require('request');
|
me.request = me.request || require('request');
|
||||||
me.promisify = me.promisify || require('util').promisify;
|
me.promisify = me.promisify || require('util').promisify;
|
||||||
|
|
48
test.cb.js
48
test.cb.js
|
@ -1,21 +1,17 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
module.exports.run = function run(web, chType, email) {
|
module.exports.run = function run(web, chType, email, accountKeypair, domainKeypair) {
|
||||||
var RSA = require('rsa-compat').RSA;
|
var RSA = require('rsa-compat').RSA;
|
||||||
var directoryUrl = 'https://acme-staging-v02.api.letsencrypt.org/directory';
|
var directoryUrl = 'https://acme-staging-v02.api.letsencrypt.org/directory';
|
||||||
var acme2 = require('./compat').ACME.create({ RSA: RSA });
|
var acme2 = require('./').ACME.create({ RSA: RSA });
|
||||||
// [ 'test.ppl.family' ] 'coolaj86@gmail.com''http-01'
|
// [ 'test.ppl.family' ] 'coolaj86@gmail.com''http-01'
|
||||||
console.log(web, chType, email);
|
acme2.init(directoryUrl).then(function () {
|
||||||
return;
|
|
||||||
acme2.init(directoryUrl).then(function (body) {
|
|
||||||
console.log(body);
|
|
||||||
return;
|
|
||||||
|
|
||||||
var options = {
|
var options = {
|
||||||
agreeToTerms: function (tosUrl, agree) {
|
agreeToTerms: function (tosUrl, agree) {
|
||||||
agree(null, tosUrl);
|
agree(null, tosUrl);
|
||||||
}
|
}
|
||||||
, setChallenge: function (opts, cb) {
|
, setChallenge: function (opts, cb) {
|
||||||
|
var pathname;
|
||||||
|
|
||||||
console.log("");
|
console.log("");
|
||||||
console.log('identifier:');
|
console.log('identifier:');
|
||||||
|
@ -34,40 +30,50 @@ module.exports.run = function run(web, chType, email) {
|
||||||
console.log(opts.dnsAuthorization);
|
console.log(opts.dnsAuthorization);
|
||||||
console.log("");
|
console.log("");
|
||||||
|
|
||||||
console.log("Put the string '" + opts.keyAuthorization + "' into a file at '" + opts.hostname + "/" + opts.token + "'");
|
if ('http-01' === opts.type) {
|
||||||
console.log("\nThen hit the 'any' key to continue (must be specifically the 'any' key)...");
|
pathname = opts.hostname + acme2.acmeChallengePrefix + "/" + opts.token;
|
||||||
|
console.log("Put the string '" + opts.keyAuthorization + "' into a file at '" + pathname + "'");
|
||||||
|
console.log("echo '" + opts.keyAuthorization + "' > '" + pathname + "'");
|
||||||
|
} else if ('dns-01' === opts.type) {
|
||||||
|
pathname = acme2.acmeChallengeDnsPrefix + "." + opts.hostname.replace(/^\*\./, '');
|
||||||
|
console.log("Put the string '" + opts.dnsAuthorization + "' into the TXT record '" + pathname + "'");
|
||||||
|
console.log("ddig TXT " + pathname + " '" + opts.dnsAuthorization + "'");
|
||||||
|
} else {
|
||||||
|
cb(new Error("[acme-v2] unrecognized challenge type"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.log("\nThen hit the 'any' key to continue...");
|
||||||
|
|
||||||
function onAny() {
|
function onAny() {
|
||||||
|
console.log("'any' key was hit");
|
||||||
process.stdin.pause();
|
process.stdin.pause();
|
||||||
process.stdin.removeEventListener('data', onAny);
|
process.stdin.removeListener('data', onAny);
|
||||||
process.stdin.setRawMode(false);
|
process.stdin.setRawMode(false);
|
||||||
cb();
|
cb();
|
||||||
}
|
}
|
||||||
|
|
||||||
process.stdin.setRawMode(true);
|
process.stdin.setRawMode(true);
|
||||||
process.stdin.resume();
|
process.stdin.resume();
|
||||||
process.stdin.on('data', onAny);
|
process.stdin.on('data', onAny);
|
||||||
}
|
}
|
||||||
, removeChallenge: function (opts, cb) {
|
, removeChallenge: function (opts, cb) {
|
||||||
// hostname, key
|
// hostname, key
|
||||||
console.log('[DEBUG] remove challenge', hostname, key);
|
console.log('[acme-v2] remove challenge', opts.hostname, opts.keyAuthorization);
|
||||||
setTimeout(cb, 1 * 1000);
|
setTimeout(cb, 1 * 1000);
|
||||||
}
|
}
|
||||||
, challengeType: chType
|
, challengeType: chType
|
||||||
, email: email
|
, email: email
|
||||||
, accountKeypair: RSA.import({ privateKeyPem: require('fs').readFileSync(__dirname + '/account.privkey.pem') })
|
, accountKeypair: accountKeypair
|
||||||
, domainKeypair: RSA.import({ privateKeyPem: require('fs').readFileSync(__dirname + '/privkey.pem') })
|
, domainKeypair: domainKeypair
|
||||||
, domains: web
|
, domains: web
|
||||||
};
|
};
|
||||||
|
|
||||||
acme2.registerNewAccount(options).then(function (account) {
|
acme2.accounts.create(options).then(function (account) {
|
||||||
console.log('account:');
|
console.log('[acme-v2] account:');
|
||||||
console.log(account);
|
console.log(account);
|
||||||
|
|
||||||
acme2.getCertificate(options, function (fullchainPem) {
|
acme2.certificates.create(options).then(function (fullchainPem) {
|
||||||
console.log('[acme-v2] A fullchain.pem:');
|
console.log('[acme-v2] fullchain.pem:');
|
||||||
console.log(fullchainPem);
|
|
||||||
}).then(function (fullchainPem) {
|
|
||||||
console.log('[acme-v2] B fullchain.pem:');
|
|
||||||
console.log(fullchainPem);
|
console.log(fullchainPem);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,22 +2,22 @@
|
||||||
|
|
||||||
var RSA = require('rsa-compat').RSA;
|
var RSA = require('rsa-compat').RSA;
|
||||||
|
|
||||||
module.exports.run = function (web, chType, email) {
|
module.exports.run = function (web, chType, email, accountKeypair, domainKeypair) {
|
||||||
console.log('[DEBUG] run', web, chType, email);
|
console.log('[DEBUG] run', web, chType, email);
|
||||||
|
|
||||||
var acme2 = require('./compat.js').ACME.create({ RSA: RSA });
|
var acme2 = require('./compat.js').ACME.create({ RSA: RSA });
|
||||||
acme2.getAcmeUrls(acme2.stagingServerUrl, function (err, body) {
|
acme2.getAcmeUrls(acme2.stagingServerUrl, function (err/*, directoryUrls*/) {
|
||||||
if (err) { console.log('err 1'); throw err; }
|
if (err) { console.log('err 1'); throw err; }
|
||||||
console.log(body);
|
|
||||||
|
|
||||||
var options = {
|
var options = {
|
||||||
agreeToTerms: function (tosUrl, agree) {
|
agreeToTerms: function (tosUrl, agree) {
|
||||||
agree(null, tosUrl);
|
agree(null, tosUrl);
|
||||||
}
|
}
|
||||||
, setChallenge: function (hostname, token, val, cb) {
|
, setChallenge: function (hostname, token, val, cb) {
|
||||||
console.log("Put the string '" + val + "' into a file at '" + hostname + "/" + acme2.acmeChallengePrefix + "/" + token + "'");
|
var pathname = hostname + acme2.acmeChallengePrefix + "/" + token;
|
||||||
console.log("echo '" + val + "' > '" + hostname + "/" + acme2.acmeChallengePrefix + "/" + token + "'");
|
console.log("Put the string '" + val + "' into a file at '" + pathname + "'");
|
||||||
console.log("\nThen hit the 'any' key to continue (must be specifically the 'any' key)...");
|
console.log("echo '" + val + "' > '" + pathname + "'");
|
||||||
|
console.log("\nThen hit the 'any' key to continue...");
|
||||||
|
|
||||||
function onAny() {
|
function onAny() {
|
||||||
console.log("'any' key was hit");
|
console.log("'any' key was hit");
|
||||||
|
@ -37,8 +37,8 @@ module.exports.run = function (web, chType, email) {
|
||||||
}
|
}
|
||||||
, challengeType: chType
|
, challengeType: chType
|
||||||
, email: email
|
, email: email
|
||||||
, accountKeypair: RSA.import({ privateKeyPem: require('fs').readFileSync(__dirname + '/account.privkey.pem') })
|
, accountKeypair: accountKeypair
|
||||||
, domainKeypair: RSA.import({ privateKeyPem: require('fs').readFileSync(__dirname + '/privkey.pem') })
|
, domainKeypair: domainKeypair
|
||||||
, domains: web
|
, domains: web
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
10
test.js
10
test.js
|
@ -1,5 +1,6 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
var RSA = require('rsa-compat').RSA;
|
||||||
var readline = require('readline');
|
var readline = require('readline');
|
||||||
var rl = readline.createInterface({
|
var rl = readline.createInterface({
|
||||||
input: process.stdin,
|
input: process.stdin,
|
||||||
|
@ -35,10 +36,11 @@ function getEmail(web, chType) {
|
||||||
if (!email) { email = null; }
|
if (!email) { email = null; }
|
||||||
|
|
||||||
rl.close();
|
rl.close();
|
||||||
console.log("[DEBUG] rl blah blah");
|
var accountKeypair = RSA.import({ privateKeyPem: require('fs').readFileSync(__dirname + '/account.privkey.pem') });
|
||||||
require('./test.compat.js').run(web, chType, email);
|
var domainKeypair = RSA.import({ privateKeyPem: require('fs').readFileSync(__dirname + '/privkey.pem') });
|
||||||
//require('./test.cb.js').run(web, chType, email);
|
//require('./test.compat.js').run(web, chType, email, accountKeypair, domainKeypair);
|
||||||
//require('./test.promise.js').run(web, chType, email);
|
//require('./test.cb.js').run(web, chType, email, accountKeypair, domainKeypair);
|
||||||
|
require('./test.promise.js').run(web, chType, email, accountKeypair, domainKeypair);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,23 +1,19 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
/* global Promise */
|
/* global Promise */
|
||||||
|
module.exports.run = function run(web, chType, email, accountKeypair, domainKeypair) {
|
||||||
module.exports.run = function run(web, chType, email) {
|
|
||||||
var RSA = require('rsa-compat').RSA;
|
var RSA = require('rsa-compat').RSA;
|
||||||
var directoryUrl = 'https://acme-staging-v02.api.letsencrypt.org/directory';
|
var directoryUrl = 'https://acme-staging-v02.api.letsencrypt.org/directory';
|
||||||
var acme2 = require('./compat').ACME.create({ RSA: RSA });
|
var acme2 = require('./').ACME.create({ RSA: RSA });
|
||||||
// [ 'test.ppl.family' ] 'coolaj86@gmail.com''http-01'
|
// [ 'test.ppl.family' ] 'coolaj86@gmail.com''http-01'
|
||||||
console.log(web, chType, email);
|
acme2.init(directoryUrl).then(function () {
|
||||||
return;
|
|
||||||
acme2.init(directoryUrl).then(function (body) {
|
|
||||||
console.log(body);
|
|
||||||
return;
|
|
||||||
|
|
||||||
var options = {
|
var options = {
|
||||||
agreeToTerms: function (tosUrl, agree) {
|
agreeToTerms: function (tosUrl) {
|
||||||
agree(null, tosUrl);
|
return Promise.resolve(tosUrl);
|
||||||
}
|
}
|
||||||
, setChallenge: function (opts) {
|
, setChallenge: function (opts) {
|
||||||
|
return new Promise(function (resolve, reject) {
|
||||||
|
var pathname;
|
||||||
|
|
||||||
console.log("");
|
console.log("");
|
||||||
console.log('identifier:');
|
console.log('identifier:');
|
||||||
|
@ -36,47 +32,54 @@ module.exports.run = function run(web, chType, email) {
|
||||||
console.log(opts.dnsAuthorization);
|
console.log(opts.dnsAuthorization);
|
||||||
console.log("");
|
console.log("");
|
||||||
|
|
||||||
console.log("Put the string '" + opts.keyAuthorization + "' into a file at '" + opts.hostname + "/" + opts.token + "'");
|
if ('http-01' === opts.type) {
|
||||||
console.log("\nThen hit the 'any' key to continue (must be specifically the 'any' key)...");
|
pathname = opts.hostname + acme2.acmeChallengePrefix + "/" + opts.token;
|
||||||
|
console.log("Put the string '" + opts.keyAuthorization + "' into a file at '" + pathname + "'");
|
||||||
return new Promise(function (resolve) {
|
console.log("echo '" + opts.keyAuthorization + "' > '" + pathname + "'");
|
||||||
function onAny() {
|
} else if ('dns-01' === opts.type) {
|
||||||
process.stdin.pause();
|
pathname = acme2.acmeChallengeDnsPrefix + "." + opts.hostname.replace(/^\*\./, '');;
|
||||||
process.stdin.removeEventListener('data', onAny);
|
console.log("Put the string '" + opts.dnsAuthorization + "' into the TXT record '" + pathname + "'");
|
||||||
process.stdin.setRawMode(false);
|
console.log("ddig TXT " + pathname + " '" + opts.dnsAuthorization + "'");
|
||||||
|
} else {
|
||||||
resolve();
|
reject(new Error("[acme-v2] unrecognized challenge type"));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
console.log("\nThen hit the 'any' key to continue...");
|
||||||
|
|
||||||
|
function onAny() {
|
||||||
|
console.log("'any' key was hit");
|
||||||
|
process.stdin.pause();
|
||||||
|
process.stdin.removeListener('data', onAny);
|
||||||
|
process.stdin.setRawMode(false);
|
||||||
|
resolve();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
process.stdin.setRawMode(true);
|
process.stdin.setRawMode(true);
|
||||||
process.stdin.resume();
|
process.stdin.resume();
|
||||||
process.stdin.on('data', onAny);
|
process.stdin.on('data', onAny);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
, removeChallenge: function (opts) {
|
, removeChallenge: function (opts) {
|
||||||
// hostname, key
|
console.log('[acme-v2] remove challenge', opts.hostname, opts.keyAuthorization);
|
||||||
console.log('[DEBUG] remove challenge', opts.hostname, opts.keyAuthorization);
|
|
||||||
console.log("Remove the file '" + opts.hostname + "/" + opts.token + "'");
|
|
||||||
|
|
||||||
return new Promise(function (resolve) {
|
return new Promise(function (resolve) {
|
||||||
|
// hostname, key
|
||||||
setTimeout(resolve, 1 * 1000);
|
setTimeout(resolve, 1 * 1000);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
, challengeType: chType
|
, challengeType: chType
|
||||||
, email: email
|
, email: email
|
||||||
, accountKeypair: RSA.import({ privateKeyPem: require('fs').readFileSync(__dirname + '/account.privkey.pem') })
|
, accountKeypair: accountKeypair
|
||||||
, domainKeypair: RSA.import({ privateKeyPem: require('fs').readFileSync(__dirname + '/privkey.pem') })
|
, domainKeypair: domainKeypair
|
||||||
, domains: web
|
, domains: web
|
||||||
};
|
};
|
||||||
|
|
||||||
acme2.registerNewAccount(options).then(function (account) {
|
acme2.accounts.create(options).then(function (account) {
|
||||||
console.log('account:');
|
console.log('[acme-v2] account:');
|
||||||
console.log(account);
|
console.log(account);
|
||||||
|
|
||||||
acme2.getCertificate(options, function (fullchainPem) {
|
acme2.certificates.create(options).then(function (fullchainPem) {
|
||||||
console.log('[acme-v2] A fullchain.pem:');
|
console.log('[acme-v2] fullchain.pem:');
|
||||||
console.log(fullchainPem);
|
|
||||||
}).then(function (fullchainPem) {
|
|
||||||
console.log('[acme-v2] B fullchain.pem:');
|
|
||||||
console.log(fullchainPem);
|
console.log(fullchainPem);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue