Package detail

base-acme-client

FirstTimeEZ167Apache-2.030.0.3

Implementation of the Automatic Certificate Management Environment in Javascript (RFC8555)

rfc8555, acme-ari-07, automatic, certificate

readme

Automatic Certificate Management Environment (ACME)

A module for interacting with ACME servers for automated SSL/TLS certificate issuance and management.

Exports

import * as bac from 'base-acme-client'; // ES6

newDirectory

Fetches the directory information from an ACME server.

<summary>Show jsdoc</summary> javascript /** * Fetches the directory information from an ACME server. * @async * * @param {string} mainDirectoryUrl - The URL of the ACME server's directory endpoint * * @returns {Promise<Object>} An object containing the directory information or an error * @property {Object|null} get - The parsed directory JSON or null * * @property {null|Object} error - The error response if the request was unsuccessful */ export async function newDirectory(mainDirectoryUrl) { /*...*/ }

newNonce

Retrieves a new nonce from the ACME server.

<summary>Show jsdoc</summary> javascript /** * Retrieves a new nonce from the ACME server. * @async * * @param {string} [newNonceUrl] - ACME Directory URL to fetch a new nonce. * * @returns {Promise<Object>} An object containing the nonce or error details * @property {string|null} nonce - A new replay nonce for subsequent requests * * @property {null|Object} error - The error response if the request was unsuccessful */ export async function newNonce(newNonceUrl) { /*...*/ }

createJsonWebKey

Creates a JSON Web Key (JWK) from a public key.

<summary>Show jsdoc</summary> javascript /** * Creates a JSON Web Key (JWK) from a public key. * @async * * @param {Object} publicKey - The public key to convert to JWK format * * @returns {Promise<Object>} An object containing the JWK and its thumbprint * @property {Object} key - The JSON Web Key representation * @property {string} print - Base64URL encoded thumbprint of the key */ export async function createJsonWebKey(publicKey) { /*...*/ }

createAccount

Creates a new account on the ACME server.

<summary>Show jsdoc</summary> javascript /** * Creates a new account on the ACME server. * @async * * @param {string} nonce - The replay nonce from the server * @param {string} newAccountUrl - The URL for creating a new account * @param {Object} privateKey - The private key for signing the request * @param {Object} jsonWebKey - The JSON Web Key representing the account's public key * @param {Object} acmeDirectory - The ACME directory containing URLs for ACME operations * * @returns {Promise<Object>} An object containing the account creation result * @property {Object|null} get - The created account details * @property {string|null} location - The location URL of the created account * @property {string|null} nonce - A new replay nonce for subsequent requests * * @property {null|Object} error - Error details if account creation fails */ export async function createAccount(nonce, newAccountUrl, privateKey, jsonWebKey) { /*...*/ }

createOrder

Creates a new order for certificate issuance on the ACME server.

<summary>Show jsdoc</summary> javascript /** * Creates a new order for certificate issuance on the ACME server. * @async * * @param {string} kid - Key Identifier for the account * @param {string} nonce - The replay nonce from the server * @param {Object} privateKey - The private key for signing the request * @param {string[]} identifiers - Domain names to be included in the certificate * @param {Object} acmeDirectory - The ACME directory containing URLs for ACME operations * * @returns {Promise<Object>} An object containing the order creation result * @property {Object|null} get - The created order details * @property {string|null} location - The location URL of the created order * @property {string|null} nonce - A new replay nonce for subsequent requests * * @property {null|Object} error - Error details if order creation fails */ export async function createOrder(kid, nonce, privateKey, newOrderUrl, identifiers) { /*...*/ }

finalizeOrder

Finalizes a certificate order by submitting a Certificate Signing Request (CSR).

<summary>Show jsdoc</summary> javascript /** * Finalizes a certificate order by submitting a Certificate Signing Request (CSR). * @async * * @param {string} commonName - The primary domain name for the certificate * @param {string} kid - Key Identifier for the account * @param {string} nonce - The replay nonce from the server * @param {Object} privateKey - The private key for signing the request * @param {Object} publicKeySign - Public key used for signing the CSR * @param {Object} privateKeySign - Private key used for signing the CSR * @param {string} finalizeUrl - The URL for finalizing the order * @param {Object} acmeDirectory - The ACME directory containing URLs for ACME operations * @param {string[]} dnsNames - Additional DNS names to be included in the certificate * * @returns {Promise<Object>} An object containing the order finalization result * @property {Object|null} get - The finalized order details * @property {string|null} location - The location URL of the finalized order * @property {string|null} nonce - A new replay nonce for subsequent requests * * @property {null|Object} error - Error details if finalization fails */ export async function finalizeOrder(commonName, kid, nonce, privateKey, publicKeySign, privateKeySign, finalizeUrl, dnsNames) { /*...*/ }

postAsGet

Performs a POST-as-GET request to retrieve order or authorization status.

<summary>Show jsdoc</summary> javascript /** * Performs a POST-as-GET request to retrieve order or authorization status. * @async * * @param {string} kid - Key Identifier for the account * @param {string} nonce - The replay nonce from the server * @param {Object} privateKey - The private key for signing the request * @param {string} url - The URL to retrieve status from * @param {Object} acmeDirectory - The ACME directory containing URLs for ACME operations * * @returns {Promise<Object>} An object containing the retrieved information * @property {Object|null} get - The retrieved resource details * @property {string|null} location - The location URL of the resource * @property {string|null} nonce - A new replay nonce for subsequent requests * * @property {null|Object} error - Error details if retrieval fails */ export async function postAsGet(kid, nonce, privateKey, url) { /*...*/ }

postAsGetChal

Performs a POST-as-GET request for challenges

<summary>Show jsdoc</summary> javascript /** * Performs a POST-as-GET request for challenges * @async * * @param {string} kid - Key Identifier for the account * @param {string} nonce - The replay nonce from the server * @param {Object} privateKey - The private key for signing the request * @param {string} url - The URL to retrieve challenge details from * @param {Object} acmeDirectory - The ACME directory containing URLs for ACME operations * * @returns {Promise<Object>} An object containing the challenge details * @property {Object|null} get - The retrieved challenge details * @property {string|null} location - The location URL of the challenge * @property {string|null} nonce - A new replay nonce for subsequent requests * * @property {null|Object} error - Error details if retrieval fails */ export async function postAsGetChal(kid, nonce, privateKey, url) { /*...*/ }

signPayloadJson

Signs a JSON payload for ACME server requests.

<summary>Show jsdoc</summary> javascript /** * Signs a JSON payload for ACME server requests. * @async * * @param {Object} payload - The payload to be signed * @param {Object} protectedHeader - The protected header containing metadata * @param {Object} privateKey - The private key used for signing * * @returns {Promise<string>} A JSON Web Signature (JWS) string */ export async function signPayloadJson(payload, protectedHeader, privateKey) { /*...*/ }

signPayload

Signs a payload for ACME server requests.

<summary>Show jsdoc</summary> javascript /** * Signs a payload for ACME server requests. * @async * * @param {string|Object} payload - The payload to be signed * @param {Object} protectedHeader - The protected header containing metadata * @param {Object} privateKey - The private key used for signing * * @returns {Promise<string>} A JSON Web Signature (JWS) string */ export async function signPayload(payload, protectedHeader, privateKey) { /*...*/ }

formatPublicKey

Formats a PEM-encoded public key to a key object.

<summary>Show jsdoc</summary> javascript /** * Formats a PEM-encoded public key to a key object. * * @param {string} pem - The PEM-encoded public key * * @returns {Object} A formatted public key object */ export function formatPublicKey(pem) { /*...*/ }

formatPrivateKey

Formats a PEM-encoded private key to a key object.

<summary>Show jsdoc</summary> javascript /** * Formats a PEM-encoded private key to a key object. * * @param {string} pem - The PEM-encoded private key * * @returns {Object} A formatted private key object */ export function formatPrivateKey(pem) { /*...*/ }

base64urlEncode

Encodes input to a base64url-encoded string.

<summary>Show jsdoc</summary> javascript /** * Encodes input to a base64url-encoded string. * * @param {string|Uint8Array} input - The input to encode * * @returns {string} A base64url-encoded string */ export function base64urlEncode(input) { /*...*/ }

hexToBytes

Converts a hexadecimal string to a Uint8Array of bytes.

<summary>Show jsdoc</summary> javascript /** * Converts a hexadecimal string to a Uint8Array of bytes. * * @param {string} hex - The hexadecimal string to convert. It should contain an even number of characters. * * @returns {Uint8Array} A Uint8Array containing the byte values represented by the hexadecimal string. * @throws {Error} Throws an error if the input string has an odd length or contains invalid hexadecimal characters. */ export function hexToBytes(hex) { /*...*/ }

getNextNonce

Retrieves the next nonce for ACME protocol requests.

<summary>Show jsdoc</summary> javascript /** * Retrieves the next nonce for ACME protocol requests. * * If a replay nonce is provided in the headers, it will return that nonce. * Otherwise, it will request a new nonce from the ACME directory. * * @async * * @param {Headers} headers - The headers object containing the replay nonce. * @param {Object} acmeDirectory - The ACME directory containing URLs for ACME operations * * @returns {Promise<string|null>} A promise that resolves to the next nonce as a string, * or null if no nonce is available. */ export async function getNextNonce(headers, acmeDirectory) { /*...*/ }

fetchRequest

Sends a signed request to the ACME server.

<summary>Show jsdoc</summary> javascript /** * Sends a signed request to the ACME server. * @async * * @param {string} method - The HTTP method to use (e.g., 'GET', 'POST') * @param {string} url - The URL to send the request to * @param {string} signedData - The signed payload to send * * @returns {Promise<Response>} The response from the server */ export async function fetchRequest(method, url, signedData) { /*...*/ }

fetchSuggestedWindow

Fetches the suggested renewal window information for a certificate from the specified URL.

<summary>Show jsdoc</summary> javascript /** * Fetches the suggested renewal window information for a certificate from the specified URL. * @async * * @param {string} renewalInfoUrl - The base URL for fetching renewal information. * @param {string} aki- The Authority Key Identifier in hexadecimal format. * @param {string} serial - The serial number in hexadecimal format. * * @returns {Promise<Object>} A promise that resolves to the parsed JSON of the suggested window * @property {Object|null} get - The retrieved suggested window * * @property {null|Object} error - Error details if retrieval fails * * @throws {Error} Throws an error if the fetch operation fails. */ export async function fetchSuggestedWindow(renewalInfoUrl, aki, serial) { /*...*/ }

fetchAndRetryUntilOk

Fetch a resource with multiple retry attempts and progressive backoff.

<summary>Show jsdoc</summary> javascript /** * Fetch a resource with multiple retry attempts and progressive backoff. * @async * * @param {string|Request} fetchInput - The URL or Request object to fetch * @param {Object} init - optional fetch init object * @param {number} [attempts=6] - Maximum number of fetch attempts * @param {boolean} silent - true to suppress console output on failure attempt * * @returns {Promise<Response|undefined>} The response or undefined if all attempts fail * * @description * This function attempts to fetch a resource with the following characteristics: * - Starts with one fetch attempt * - Increments attempts progressively * - Implements an increasing delay between failed attempts (650ms * attempt number) * - Logs any caught exceptions * - Returns immediately on a successful (ok) response * - Returns the last response or undefined if all attempts are exhausted * * @example * const response = await fetchAndRetyUntilOk('https://api.example.com/data'); * if (response && response.ok) { * const data = await response.json(); * // Process successful response * } */ export async function fetchAndRetryUntilOk(fetchInput, init, attempts = 6, silent = false) { /*...*/ }

fetchAndRetryProtectedUntilOk

Fetch a protected resource with multiple retry attempts and progressive backoff.

<summary>Show jsdoc</summary> javascript /** * Fetch a protected resource with multiple retry attempts and progressive backoff. * @async * * @param {Object} payload - The payload to be sent with the request * @param {Object} protectedHeader - The protected header containing metadata for the request * @param {Object} privateKey - The private key for signing the request * @param {Object} acmeDirectory - The ACME directory containing URLs for ACME operations * @param {number} [attempts=6] - Maximum number of fetch attempts (default: 6) * @param {boolean} silent - true to suppress console output on failure attempt * * @returns {Promise<Response|undefined>} The response or undefined if all attempts fail * * @description * This function attempts to fetch a protected resource with the following characteristics: * - Starts with one fetch attempt * - Increments attempts progressively * - Implements an increasing delay between failed attempts (650ms * attempt number) * - Logs any caught exceptions * - Returns immediately on a successful (ok) response * - Returns the last response or undefined if all attempts are exhausted * * @example * const response = await fetchAndRetryProtectedUntilOk( * payload, * protectedHeader, * privateKey, * acmeDirectory * ); * if (response && response.ok) { * const data = await response.json(); * // Process successful response * } */ export async function fetchAndRetryProtectedUntilOk(payload, protectedHeader, privateKey, acmeDirectory, attempts = 3, silent = false) { /*...*/ }

Errors/Exceptions

Errors and Exceptions will be returned in an object

// Exceptions
{
  error: {
    type: 'bac:exception:methodName',
    detail: Error: SyntaxError: Unexpected end of input
        at file:///base-acme-client.js:666:11
        at ModuleJob.run (node:internal/modules/esm/module_job:271:25)
        at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader:547:26)
        at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:116:5),
    status: 777777
  }
}

// Error from the Base ACME Client
{
  error: {
    type: 'bac:failed:methodName',
    detail: 'Could not complete methodName after multiple attempts',
    status: 777777
  }
}

// Error from the ACME Server
{
  error: {
    type: 'urn:ietf:params:acme:error:orderNotReady',
    detail: `Order's status ("valid") is not acceptable for finalization`,
    status: 403
  }
}

Full Working Examples

This module is used by Lets Encrypt ACME Client and Server SSL