
Research
Two Malicious Rust Crates Impersonate Popular Logger to Steal Wallet Keys
Socket uncovers malicious Rust crates impersonating fast_log to steal Solana and Ethereum wallet keys from source code.
base-acme-client
Advanced tools
Implementation of the Automatic Certificate Management Environment in Javascript (RFC8555)
A module for interacting with ACME
servers for automated SSL/TLS certificate issuance and management.
import * as bac from 'base-acme-client'; // ES6
Fetches the directory information from an ACME
server.
/**
* 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) { /*...*/ }
Retrieves a new nonce from the ACME
server.
/**
* 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) { /*...*/ }
Creates a JSON Web Key (JWK) from a public key.
/**
* 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) { /*...*/ }
Creates a new account on the ACME
server.
/**
* 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) { /*...*/ }
Creates a new order for certificate issuance on the ACME
server.
/**
* 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) { /*...*/ }
Finalizes a certificate order by submitting a Certificate Signing Request (CSR).
/**
* 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) { /*...*/ }
Performs a POST-as-GET request to retrieve order or authorization status.
/**
* 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) { /*...*/ }
Performs a POST-as-GET request for challenges
/**
* 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) { /*...*/ }
Signs a JSON payload for ACME
server requests.
/**
* 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) { /*...*/ }
Signs a payload for ACME
server requests.
/**
* 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) { /*...*/ }
Formats a PEM-encoded public key to a key object.
/**
* 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) { /*...*/ }
Formats a PEM-encoded private key to a key object.
/**
* 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) { /*...*/ }
Encodes input to a base64url-encoded string.
/**
* 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) { /*...*/ }
Converts a hexadecimal string to a Uint8Array of bytes.
/**
* 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) { /*...*/ }
Retrieves the next nonce for ACME protocol requests.
/**
* 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) { /*...*/ }
Sends a signed request to the ACME
server.
/**
* 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) { /*...*/ }
Fetches the suggested renewal window information for a certificate from the specified URL.
/**
* 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) { /*...*/ }
Fetch a resource with multiple retry attempts and progressive backoff.
/**
* 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) { /*...*/ }
Fetch a protected resource with multiple retry attempts and progressive backoff.
/**
* 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 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
}
}
This module is used by Lets Encrypt ACME Client
and Server SSL
FAQs
Implementation of the Automatic Certificate Management Environment in Javascript (RFC8555)
We found that base-acme-client demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Socket uncovers malicious Rust crates impersonating fast_log to steal Solana and Ethereum wallet keys from source code.
Research
A malicious package uses a QR code as steganography in an innovative technique.
Research
/Security News
Socket identified 80 fake candidates targeting engineering roles, including suspected North Korean operators, exposing the new reality of hiring as a security function.