Simple and unopinionated ACME client
Clone or download
Latest commit 5909b38 Nov 7, 2018

README.md

acme-client Build Status

A simple and unopinionated ACME client.

This module is written to handle communication with a Boulder/Let's Encrypt-style ACME API.

ACME specification: https://github.com/ietf-wg-acme/acme/blob/master/draft-ietf-acme-acme.md

Information on how the Boulder/Let's Encrypt API diverges from the ACME spec: https://github.com/letsencrypt/boulder/blob/master/docs/acme-divergences.md

ACME compatibility

acme-client API Style
v2.x ACMEv2 Promise
v1.x ACMEv1 callback

Installation

$ npm install acme-client

Usage

const acme = require('acme-client');

const accountPrivateKey = '<PEM encoded private key>';

const client = new acme.Client({
    directoryUrl: acme.directory.letsencrypt.staging,
    accountKey: accountPrivateKey
});

Directory URLs

acme.directory.letsencrypt.staging;
acme.directory.letsencrypt.production;

Cryptography

For key pair generation and Certificate Signing Requests, acme-client supports multiple interchangeable cryptographic engines.

acme.forge -- docs/forge.md

Recommended when node >= v10.12.0 or OpenSSL CLI dependency can not be met.

Uses node-forge, a pure JavaScript implementation of the TLS protocol.

This engine has no external dependencies since it is completely implemented in JavaScript, however CPU-intensive tasks (like generating a large size key pair) has a performance penalty and will be slower than doing it natively.

This caveat is removed in Node v10.12.0 with the introduction of crypto.generateKeyPair(), a native Node API for key pair generation. The forge engine will automatically use this API when available.

Example

const privateKey = await acme.forge.createPrivateKey();

const [certificateKey, certificateCsr] = await acme.forge.createCsr({
    commonName: '*.example.com',
    altNames: ['example.com']
})

acme.openssl -- docs/openssl.md

Recommended when node < v10.12.0 and OpenSSL CLI dependency can be met.

Uses openssl-wrapper to execute commands using the OpenSSL CLI.

This backend requires OpenSSL to be installed and available in $PATH.

Example

const privateKey = await acme.openssl.createPrivateKey();

const [certificateKey, certificateCsr] = await acme.openssl.createCsr({
    commonName: '*.example.com',
    altNames: ['example.com']
})

Auto mode

For convenience an auto() method is included in the client that takes a single config object. This method will handle the entire process of getting a certificate for one or multiple domains.

A full example can be found at examples/auto.js.

Documentation: docs/client.md#AcmeClient+auto

Example

const autoOpts = {
    csr: '<PEM encoded CSR>',
    email: 'test@example.com',
    termsOfServiceAgreed: true,
    challengeCreateFn: async (authz, challenge, keyAuthorization) => {},
    challengeRemoveFn: async (authz, challenge, keyAuthorization) => {}
}

const certificate = await client.auto(autoOpts);

API

For more fine-grained control you can interact with the ACME API using the methods documented below.

A full example can be found at examples/api.js.

Documentation: docs/client.md

Example

const account = await client.createAccount({
    termsOfServiceAgreed: true,
    contact: ['mailto:test@example.com']
});

const order = await client.createOrder({
    identifiers: [
        { type: 'dns', value: 'example.com' },
        { type: 'dns', value: '*.example.com' }
    ]
});

Debugging

acme-client uses debug for debugging which can be enabled by running

DEBUG=acme-client node index.js

License

MIT