diff --git a/README.md b/README.md index 3cffabd..f5b6ae2 100644 --- a/README.md +++ b/README.md @@ -19,13 +19,18 @@ You will follow these steps to obtain certificates: * register a user account with `registerNewAccount` * implement a method to agree to the terms of service as `agreeToTos` * get certificates with `getCertificate` +* implement a method to store the challenge token as `setChallenge` +* implement a method to get the challenge token as `getChallenge` +* implement a method to remove the challenge token as `removeChallenge` ```javascript 'use strict'; var LeCore = require('letiny-core'); + var accountPrivateKeyPem = '...'; // leCrypto.generateRsaKeypair(bitLen, exp, cb) var domainPrivateKeyPem = '...'; // (same) +var challengeStore = { /*get, set, remove*/ }; // see below for example LeCore.getAcmeUrls( LeCore.stagingServerUrl // or choose LeCore.productionServerUrl @@ -46,7 +51,10 @@ LeCore.getAcmeUrls( // record to disk (or db) LeCore.getCertificate( - { + { domainPrivateKeyPem: domainPrivateKeyPem + , accountPrivateKeyPem: accountPrivateKeyPem + , setChallenge: challengeStore.set + , removeChallenge: challengeStore.remove } , function (err, certs) { @@ -62,6 +70,45 @@ LeCore.getAcmeUrls( ); ``` +That will fail unless you have a webserver running on 80 and 443 (or 5001) +to respond to `/.well-known/acme-challenge/xxxxxxxx` with the proper token + +```javascript +var localCerts = require('localhost.daplie.com-certificates'); // needs default certificates +var http = require('http'); +var httsp = require('https'); + +function acmeResponder(req, res) { + if (0 !== req.url.indexOf(LeCore.acmeChallengePrefixUrl)) { + res.end('Hello World!'); + return; + } + + LeCore. +} + +http.createServer() +``` + +Finally, you need an implementation of `challengeStore`: + +```javascript +var challengeCache = {}; +var challengeStore = { + set: function (hostname, key, value, cb) { + challengeCache[key] = value; + cb(null); + } +, get: function (hostname, key, cb) { + cb(null, challengeCache[key]); + } +, remove: function (hostname, key, cb) { + delete challengeCache[key]; + cb(null); + } +}; +``` + ## API The Goodies @@ -90,6 +137,7 @@ Helpers & Stuff // Constants LeCore.productionServerUrl // https://acme-v01.api.letsencrypt.org/directory LeCore.stagingServerUrl // https://acme-staging.api.letsencrypt.org/directory +LeCore.acmeChallengePrefix // /.well-known/acme-challenge/ LeCore.configDir // /etc/letsencrypt/ LeCore.logsDir // /var/log/letsencrypt/ LeCore.workDir // /var/lib/letsencrypt/ @@ -130,6 +178,12 @@ LeCore.getAcmeUrls(discoveryUrl, function (err, urls) { }); ``` +## Authors + + * ISRG + * Anatol Sommer (https://github.com/anatolsommer) + * AJ ONeal (https://daplie.com) + ## Licence MPL 2.0 diff --git a/lib/get-certificate.js b/lib/get-certificate.js index 5073df4..f63cd81 100644 --- a/lib/get-certificate.js +++ b/lib/get-certificate.js @@ -9,7 +9,7 @@ module.exports.create = function (deps) { var NOOP=function () {}, log=NOOP; var request=require('request'); - var util=require('./acme-util'); + var toStandardB64 = deps.leUtils.toStandardB64; var importPemPrivateKey = deps.leCrypto.importPemPrivateKey; var thumbprinter = deps.leCrypto.thumbprint; var generateCsr = deps.leCrypto.generateCsr || deps.leCrypto.generateCSR; @@ -239,7 +239,7 @@ module.exports.create = function (deps) { } function certBufferToPem(cert) { - cert=util.toStandardB64(cert.toString('base64')); + cert=toStandardB64(cert.toString('base64')); cert=cert.match(/.{1,64}/g).join('\n'); return '-----BEGIN CERTIFICATE-----\n'+cert+'\n-----END CERTIFICATE-----'; } diff --git a/lib/node.js b/lib/node.js index 2d34c2b..d393f34 100644 --- a/lib/node.js +++ b/lib/node.js @@ -6,6 +6,7 @@ 'use strict'; var request = require('request'); +var leUtils = require('./acme-utils'); var leCrypto = require('./letsencrypt-node-crypto'); var leForge = require('./letsencrypt-forge'); var leUrsa; @@ -36,3 +37,4 @@ Object.keys(leForge).forEach(function (key) { module.exports.request = request; module.exports.leCrypto = leCrypto; +module.exports.leUtils = leUtils;