Improve test.js.
Use request instead of http so it works with either HTTP or HTTPS URLs. Write DER certificate rather than PEM certificate. I was getting some bytewise mismatches when checking the output PEM against a downloaded DER.
This commit is contained in:
parent
3814c95594
commit
2edb869086
|
|
@ -6,6 +6,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cli": "^0.6.5",
|
"cli": "^0.6.5",
|
||||||
"inquirer": "^0.8.2",
|
"inquirer": "^0.8.2",
|
||||||
"node-forge": "^0.6.21"
|
"node-forge": "^0.6.21",
|
||||||
|
"request": "^2.55.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ var inquirer = require("inquirer");
|
||||||
var cli = require("cli");
|
var cli = require("cli");
|
||||||
var http = require('http');
|
var http = require('http');
|
||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
|
var request = require('request');
|
||||||
var url = require('url');
|
var url = require('url');
|
||||||
var util = require("./acme-util");
|
var util = require("./acme-util");
|
||||||
var crypto = require("./crypto-util");
|
var crypto = require("./crypto-util");
|
||||||
|
|
@ -32,7 +33,7 @@ var questions = {
|
||||||
type: "confirm",
|
type: "confirm",
|
||||||
name: "terms",
|
name: "terms",
|
||||||
message: "Do you agree to these terms?",
|
message: "Do you agree to these terms?",
|
||||||
default: false,
|
default: true,
|
||||||
}],
|
}],
|
||||||
|
|
||||||
domain: [{
|
domain: [{
|
||||||
|
|
@ -64,7 +65,7 @@ var questions = {
|
||||||
type: "input",
|
type: "input",
|
||||||
name: "certFile",
|
name: "certFile",
|
||||||
message: "Name for certificate file",
|
message: "Name for certificate file",
|
||||||
default: "cert.pem"
|
default: "cert.der"
|
||||||
}],
|
}],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -72,7 +73,7 @@ var state = {
|
||||||
keyPairBits: 512,
|
keyPairBits: 512,
|
||||||
keyPair: null,
|
keyPair: null,
|
||||||
|
|
||||||
newRegistrationURL: "http://localhost:4000/acme/new-reg",
|
newRegistrationURL: "https://www.letsencrypt-demo.org/acme/new-reg",
|
||||||
registrationURL: "",
|
registrationURL: "",
|
||||||
|
|
||||||
termsRequired: false,
|
termsRequired: false,
|
||||||
|
|
@ -169,14 +170,12 @@ function register(answers) {
|
||||||
var jws = crypto.generateSignature(state.keyPair, new Buffer(registerMessage));
|
var jws = crypto.generateSignature(state.keyPair, new Buffer(registerMessage));
|
||||||
var payload = JSON.stringify(jws);
|
var payload = JSON.stringify(jws);
|
||||||
|
|
||||||
var options = url.parse(state.newRegistrationURL);
|
var req = request.post(state.newRegistrationURL, {}, getTerms);
|
||||||
options.method = "POST";
|
|
||||||
var req = http.request(options, getTerms);
|
|
||||||
req.write(payload)
|
req.write(payload)
|
||||||
req.end();
|
req.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTerms(resp) {
|
function getTerms(err, resp) {
|
||||||
if (Math.floor(resp.statusCode / 100) != 2) {
|
if (Math.floor(resp.statusCode / 100) != 2) {
|
||||||
// Non-2XX response
|
// Non-2XX response
|
||||||
console.log("Registration request failed with code " + resp.statusCode);
|
console.log("Registration request failed with code " + resp.statusCode);
|
||||||
|
|
@ -196,20 +195,13 @@ function getTerms(resp) {
|
||||||
if (state.termsRequired) {
|
if (state.termsRequired) {
|
||||||
state.termsURL = links["terms-of-service"];
|
state.termsURL = links["terms-of-service"];
|
||||||
console.log(state.termsURL);
|
console.log(state.termsURL);
|
||||||
http.get(state.termsURL, getAgreement)
|
request.get(state.termsURL, getAgreement)
|
||||||
} else {
|
} else {
|
||||||
inquirer.prompt(questions.domain, getChallenges);
|
inquirer.prompt(questions.domain, getChallenges);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAgreement(resp) {
|
function getAgreement(err, resp, body) {
|
||||||
var body = "";
|
|
||||||
resp.on("data", function(chunk) {
|
|
||||||
body += chunk;
|
|
||||||
});
|
|
||||||
resp.on("end", function(chunk) {
|
|
||||||
if (chunk) { body += chunk; }
|
|
||||||
|
|
||||||
// TODO: Check content-type
|
// TODO: Check content-type
|
||||||
console.log("The CA requires your agreement to terms (not supported).");
|
console.log("The CA requires your agreement to terms (not supported).");
|
||||||
console.log();
|
console.log();
|
||||||
|
|
@ -217,7 +209,6 @@ function getAgreement(resp) {
|
||||||
console.log();
|
console.log();
|
||||||
|
|
||||||
inquirer.prompt(questions.terms, sendAgreement);
|
inquirer.prompt(questions.terms, sendAgreement);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendAgreement(answers) {
|
function sendAgreement(answers) {
|
||||||
|
|
@ -234,12 +225,7 @@ function sendAgreement(answers) {
|
||||||
var payload = JSON.stringify(jws);
|
var payload = JSON.stringify(jws);
|
||||||
|
|
||||||
console.log("Posting agreement to: " + state.registrationURL)
|
console.log("Posting agreement to: " + state.registrationURL)
|
||||||
var options = url.parse(state.registrationURL);
|
var req = request(state.registrationURL, {}, function(err, resp, body) {
|
||||||
options.method = "POST";
|
|
||||||
var req = http.request(options, function(resp) {
|
|
||||||
var body = "";
|
|
||||||
resp.on("data", function(chunk) { body += chunk; });
|
|
||||||
resp.on("end", function() {
|
|
||||||
if (Math.floor(resp.statusCode / 100) != 2) {
|
if (Math.floor(resp.statusCode / 100) != 2) {
|
||||||
// Non-2XX response
|
// Non-2XX response
|
||||||
console.log("Couldn't POST agreement back to server, aborting.");
|
console.log("Couldn't POST agreement back to server, aborting.");
|
||||||
|
|
@ -247,7 +233,6 @@ function sendAgreement(answers) {
|
||||||
console.log(body);
|
console.log(body);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
inquirer.prompt(questions.domain, getChallenges);
|
inquirer.prompt(questions.domain, getChallenges);
|
||||||
});
|
});
|
||||||
|
|
@ -268,14 +253,12 @@ function getChallenges(answers) {
|
||||||
var jws = crypto.generateSignature(state.keyPair, new Buffer(authzMessage));
|
var jws = crypto.generateSignature(state.keyPair, new Buffer(authzMessage));
|
||||||
var payload = JSON.stringify(jws);
|
var payload = JSON.stringify(jws);
|
||||||
|
|
||||||
var options = url.parse(state.newAuthorizationURL);
|
var req = request.post(state.newAuthorizationURL, {}, getReadyToValidate);
|
||||||
options.method = "POST";
|
|
||||||
var req = http.request(options, getReadyToValidate);
|
|
||||||
req.write(payload)
|
req.write(payload)
|
||||||
req.end();
|
req.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getReadyToValidate(resp) {
|
function getReadyToValidate(err, resp, body) {
|
||||||
if (Math.floor(resp.statusCode / 100) != 2) {
|
if (Math.floor(resp.statusCode / 100) != 2) {
|
||||||
// Non-2XX response
|
// Non-2XX response
|
||||||
console.log("Authorization request failed with code " + resp.statusCode)
|
console.log("Authorization request failed with code " + resp.statusCode)
|
||||||
|
|
@ -291,13 +274,6 @@ function getReadyToValidate(resp) {
|
||||||
state.authorizationURL = resp.headers["location"];
|
state.authorizationURL = resp.headers["location"];
|
||||||
state.newCertificateURL = links["next"];
|
state.newCertificateURL = links["next"];
|
||||||
|
|
||||||
var body = ""
|
|
||||||
resp.on('data', function(chunk) {
|
|
||||||
body += chunk;
|
|
||||||
});
|
|
||||||
resp.on('end', function(chunk) {
|
|
||||||
if (chunk) { body += chunk; }
|
|
||||||
|
|
||||||
var authz = JSON.parse(body);
|
var authz = JSON.parse(body);
|
||||||
|
|
||||||
var simpleHttps = authz.challenges.filter(function(x) { return x.type == "simpleHttps"; });
|
var simpleHttps = authz.challenges.filter(function(x) { return x.type == "simpleHttps"; });
|
||||||
|
|
@ -326,7 +302,6 @@ function getReadyToValidate(resp) {
|
||||||
// > python -m SimpleHTTPServer 5001
|
// > python -m SimpleHTTPServer 5001
|
||||||
|
|
||||||
inquirer.prompt(questions.readyToValidate, sendResponse);
|
inquirer.prompt(questions.readyToValidate, sendResponse);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendResponse() {
|
function sendResponse() {
|
||||||
|
|
@ -340,30 +315,23 @@ function sendResponse() {
|
||||||
|
|
||||||
var options = url.parse(state.responseURL);
|
var options = url.parse(state.responseURL);
|
||||||
options.method = "POST";
|
options.method = "POST";
|
||||||
var req = http.request(options, ensureValidation);
|
var req = request.post(state.responseURL, {}, ensureValidation);
|
||||||
req.write(payload)
|
req.write(payload)
|
||||||
req.end();
|
req.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
function ensureValidation(resp) {
|
function ensureValidation(err, resp, body) {
|
||||||
if (Math.floor(resp.statusCode / 100) != 2) {
|
if (Math.floor(resp.statusCode / 100) != 2) {
|
||||||
// Non-2XX response
|
// Non-2XX response
|
||||||
console.log("Authorization status request failed with code " + resp.statusCode)
|
console.log("Authorization status request failed with code " + resp.statusCode)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var body = "";
|
|
||||||
resp.on('data', function(chunk) {
|
|
||||||
body += chunk;
|
|
||||||
});
|
|
||||||
resp.on('end', function(chunk) {
|
|
||||||
if (chunk) { body += chunk; }
|
|
||||||
|
|
||||||
var authz = JSON.parse(body);
|
var authz = JSON.parse(body);
|
||||||
|
|
||||||
if (authz.status == "pending") {
|
if (authz.status == "pending") {
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
http.get(state.authorizationURL, ensureValidation);
|
request.get(state.authorizationURL, {}, ensureValidation);
|
||||||
}, state.retryDelay);
|
}, state.retryDelay);
|
||||||
} else if (authz.status == "valid") {
|
} else if (authz.status == "valid") {
|
||||||
cli.spinner("Validating domain ... done", true);
|
cli.spinner("Validating domain ... done", true);
|
||||||
|
|
@ -377,7 +345,6 @@ function ensureValidation(resp) {
|
||||||
console.log(JSON.stringify(authz, null, " "));
|
console.log(JSON.stringify(authz, null, " "));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCertificate() {
|
function getCertificate() {
|
||||||
|
|
@ -392,22 +359,12 @@ function getCertificate() {
|
||||||
|
|
||||||
cli.spinner("Requesting certificate");
|
cli.spinner("Requesting certificate");
|
||||||
|
|
||||||
var options = url.parse(state.newCertificateURL);
|
var req = request.post(state.newCertificateURL, {}, downloadCertificate);
|
||||||
options.method = "POST";
|
|
||||||
var req = http.request(options, downloadCertificate);
|
|
||||||
req.write(payload)
|
req.write(payload)
|
||||||
req.end();
|
req.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
function downloadCertificate(resp) {
|
function downloadCertificate(err, resp, body) {
|
||||||
var chunks = [];
|
|
||||||
resp.on('data', function(chunk) {
|
|
||||||
chunks.push(chunk);
|
|
||||||
});
|
|
||||||
resp.on('end', function(chunk) {
|
|
||||||
if (chunk) { chunks.push(chunk); }
|
|
||||||
var body = Buffer.concat(chunks);
|
|
||||||
|
|
||||||
if (Math.floor(resp.statusCode / 100) != 2) {
|
if (Math.floor(resp.statusCode / 100) != 2) {
|
||||||
// Non-2XX response
|
// Non-2XX response
|
||||||
console.log("Certificate request failed with code " + resp.statusCode);
|
console.log("Certificate request failed with code " + resp.statusCode);
|
||||||
|
|
@ -417,19 +374,23 @@ function downloadCertificate(resp) {
|
||||||
|
|
||||||
cli.spinner("Requesting certificate ... done", true);
|
cli.spinner("Requesting certificate ... done", true);
|
||||||
console.log();
|
console.log();
|
||||||
var certB64 = util.b64enc(body);
|
|
||||||
|
|
||||||
state.certificate = certB64;
|
state.certificate = body;
|
||||||
inquirer.prompt(questions.files, saveFiles);
|
console.log()
|
||||||
|
var certURL = resp.headers['location'];
|
||||||
|
request.get(certURL, function(err, res, body) {
|
||||||
|
if (body !== state.certificate) {
|
||||||
|
console.log("ERROR! Cert at", certURL, "did not match returned cert.");
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
inquirer.prompt(questions.files, saveFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveFiles(answers) {
|
function saveFiles(answers) {
|
||||||
var keyPEM = crypto.privateKeyToPem(state.keyPair.privateKey);
|
var keyPEM = crypto.privateKeyToPem(state.keyPair.privateKey);
|
||||||
fs.writeFileSync(answers.keyFile, keyPEM);
|
fs.writeFileSync(answers.keyFile, keyPEM);
|
||||||
|
|
||||||
var certPEM = crypto.certificateToPem(state.certificate);
|
fs.writeFileSync(answers.certFile, state.certificate);
|
||||||
fs.writeFileSync(answers.certFile, certPEM);
|
|
||||||
|
|
||||||
console.log("Done!")
|
console.log("Done!")
|
||||||
console.log("To try it out:");
|
console.log("To try it out:");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue