Socket
Socket
Sign inDemoInstall

acme-client

Package Overview
Dependencies
Maintainers
1
Versions
40
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

acme-client - npm Package Compare versions

Comparing version 4.2.5 to 5.0.0

src/crypto/index.js

37

package.json

@@ -5,3 +5,3 @@ {

"author": "nmorsman",
"version": "4.2.5",
"version": "5.0.0",
"main": "src/index.js",

@@ -12,3 +12,3 @@ "types": "types",

"engines": {
"node": ">= 10"
"node": ">= 16"
},

@@ -20,24 +20,23 @@ "files": [

"dependencies": {
"axios": "0.26.1",
"backo2": "^1.0.0",
"bluebird": "^3.5.0",
"axios": "0.27.2",
"debug": "^4.1.1",
"node-forge": "^1.3.0"
"jsrsasign": "^10.5.26",
"node-forge": "^1.3.1"
},
"devDependencies": {
"@types/node": "^14.0.5",
"chai": "^4.1.0",
"chai-as-promised": "^7.0.0",
"dtslint": "^4.0.0",
"eslint": "^7.1.0",
"eslint-config-airbnb-base": "^14.0.0",
"eslint-plugin-import": "^2.10.0",
"jsdoc-to-markdown": "^6.0.1",
"mocha": "^8.1.3",
"nock": "^13.0.4",
"typescript": "^4.0.2",
"uuid": "^8.1.0"
"@types/node": "^18.6.1",
"chai": "^4.3.6",
"chai-as-promised": "^7.1.1",
"dtslint": "^4.2.1",
"eslint": "^8.11.0",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-plugin-import": "^2.25.4",
"jsdoc-to-markdown": "^7.1.1",
"mocha": "^10.0.0",
"nock": "^13.2.4",
"typescript": "^4.6.2",
"uuid": "^8.3.2"
},
"scripts": {
"build-docs": "jsdoc2md src/client.js > docs/client.md && jsdoc2md src/crypto/forge.js > docs/forge.md",
"build-docs": "jsdoc2md src/client.js > docs/client.md && jsdoc2md src/crypto/index.js > docs/crypto.md && jsdoc2md src/crypto/forge.js > docs/forge.md",
"lint": "eslint .",

@@ -44,0 +43,0 @@ "lint-types": "dtslint types",

@@ -11,10 +11,18 @@ # acme-client [![CircleCI](https://circleci.com/gh/publishlab/node-acme-client.svg?style=svg)](https://circleci.com/gh/publishlab/node-acme-client)

## Important upgrade notice
On September 15, 2022, Let's Encrypt will stop accepting Certificate Signing Requests signed using the obsolete SHA-1 hash. This change affects all `acme-client` versions lower than `3.3.2` and `4.2.4`. Please upgrade ASAP to ensure that your certificates can still be issued following this date.
A more detailed explanation can be found [at the Let's Encrypt forums](https://community.letsencrypt.org/t/rejecting-sha-1-csrs-and-validation-using-tls-1-0-1-1-urls/175144).
### Compatibility
| acme-client | API | Style | Node.js |
| ------------- | --------- | --------- | ------- |
| v4.x | ACMEv2 | Promise | >= v10 |
| v3.x | ACMEv2 | Promise | >= v8 |
| v2.x | ACMEv2 | Promise | >= v4 |
| v1.x | ACMEv1 | callback | >= v4 |
| acme-client | Node.js | |
| ------------- | --------- | ----------------------------------------- |
| v5.x | >= v16 | [Upgrade guide](docs/upgrade-v5.md) |
| v4.x | >= v10 | [Changelog](CHANGELOG.md#v400-2020-05-29) |
| v3.x | >= v8 | [Changelog](CHANGELOG.md#v300-2019-07-13) |
| v2.x | >= v4 | [Changelog](CHANGELOG.md#v200-2018-04-02) |
| v1.x | >= v4 | [Changelog](CHANGELOG.md#v100-2017-10-20) |

@@ -30,2 +38,3 @@

* [Cryptography](#cryptography)
* [Legacy .forge interface](#legacy-forge-interface)
* [Auto mode](#auto-mode)

@@ -113,15 +122,13 @@ * [Challenge priority](#challenge-priority)

For key pair generation and Certificate Signing Requests, `acme-client` uses [node-forge](https://www.npmjs.com/package/node-forge), a pure JavaScript implementation of the TLS protocol.
For key pairs `acme-client` utilizes native Node.js cryptography APIs, supporting signing and generation of both RSA and ECDSA keys. The module [jsrsasign](https://www.npmjs.com/package/jsrsasign) is used to generate and parse Certificate Signing Requests.
These utility methods are exposed through `.forge`.
These utility methods are exposed through `.crypto`.
__API documentation: [docs/forge.md](docs/forge.md)__
* __Documentation: [docs/crypto.md](docs/crypto.md)__
#### Example
```js
const privateKey = await acme.forge.createPrivateKey();
const privateRsaKey = await acme.crypto.createPrivateRsaKey();
const privateEcdsaKey = await acme.crypto.createPrivateEcdsaKey();
const [certificateKey, certificateCsr] = await acme.forge.createCsr({
const [certificateKey, certificateCsr] = await acme.crypto.createCsr({
commonName: '*.example.com',

@@ -133,13 +140,18 @@ altNames: ['example.com']

## Auto mode
### Legacy `.forge` interface
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.
The legacy `node-forge` crypto interface is still available for backward compatibility, however this interface is now considered deprecated and will be removed in a future major version of `acme-client`.
A full example can be found at [examples/auto.js](examples/auto.js).
You should consider migrating to the new `.crypto` API at your earliest convenience. More details can be found in the [acme-client v5 upgrade guide](docs/upgrade-v5.md).
__Documentation: [docs/client.md#AcmeClient+auto](docs/client.md#AcmeClient+auto)__
* __Documentation: [docs/forge.md](docs/forge.md)__
#### Example
## 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.
* __Documentation: [docs/client.md#AcmeClient+auto](docs/client.md#AcmeClient+auto)__
* __Full example: [examples/auto.js](examples/auto.js)__
```js

@@ -194,9 +206,5 @@ const autoOpts = {

A full example can be found at [examples/api.js](examples/api.js).
* __Documentation: [docs/client.md](docs/client.md)__
* __Full example: [examples/api.js](examples/api.js)__
__API documentation: [docs/client.md](docs/client.md)__
#### Example
```js

@@ -203,0 +211,0 @@ const account = await client.createAccount({

@@ -5,5 +5,4 @@ /**

const Promise = require('bluebird');
const { readCsrDomains } = require('./crypto');
const { log } = require('./logger');
const forge = require('./crypto/forge');

@@ -64,3 +63,3 @@ const defaultOpts = {

log('[auto] Parsing domains from Certificate Signing Request');
const csrDomains = await forge.readCsrDomains(opts.csr);
const csrDomains = readCsrDomains(opts.csr);
const domains = [csrDomains.commonName].concat(csrDomains.altNames);

@@ -67,0 +66,0 @@ const uniqueDomains = Array.from(new Set(domains));

@@ -7,4 +7,4 @@ /**

const crypto = require('crypto');
const Promise = require('bluebird');
const { createHash } = require('crypto');
const { getPemBodyAsB64u } = require('./crypto');
const { log } = require('./logger');

@@ -16,3 +16,2 @@ const HttpClient = require('./http');

const auto = require('./auto');
const forge = require('./crypto/forge');

@@ -270,12 +269,9 @@

/* Get new JWK */
/* Get old JWK */
data.account = accountUrl;
data.oldKey = await this.http.getJwk();
data.oldKey = this.http.getJwk();
/* TODO: Backward-compatibility with draft-ietf-acme-12, remove this in a later release */
data.newKey = await newHttpClient.getJwk();
/* Get signed request body from new client */
const url = await newHttpClient.getResourceUrl('keyChange');
const body = await newHttpClient.createSignedRsaBody(url, data);
const body = newHttpClient.createSignedBody(url, data);

@@ -378,5 +374,3 @@ /* Change key using old client */

const body = forge.getPemBody(csr);
const data = { csr: util.b64escape(body) };
const data = { csr: getPemBodyAsB64u(csr) };
const resp = await this.api.finalizeOrder(order.finalize, data);

@@ -410,3 +404,3 @@

async getAuthorizations(order) {
return Promise.map((order.authorizations || []), async (url) => {
return Promise.all((order.authorizations || []).map(async (url) => {
const resp = await this.api.getAuthorization(url);

@@ -417,3 +411,3 @@

return resp.data;
});
}));
}

@@ -472,5 +466,5 @@

async getChallengeKeyAuthorization(challenge) {
const jwk = await this.http.getJwk();
const keysum = crypto.createHash('sha256').update(JSON.stringify(jwk));
const thumbprint = util.b64escape(keysum.digest('base64'));
const jwk = this.http.getJwk();
const keysum = createHash('sha256').update(JSON.stringify(jwk));
const thumbprint = keysum.digest('base64url');
const result = `${challenge.token}.${thumbprint}`;

@@ -492,4 +486,4 @@

if ((challenge.type === 'dns-01') || (challenge.type === 'tls-alpn-01')) {
const shasum = crypto.createHash('sha256').update(result);
return util.b64escape(shasum.digest('base64'));
const shasum = createHash('sha256').update(result);
return shasum.digest('base64url');
}

@@ -650,3 +644,3 @@

const alternateLinks = util.parseLinkHeader(resp.headers.link);
const alternates = await Promise.map(alternateLinks, async (link) => this.api.apiRequest(link, null, [200]));
const alternates = await Promise.all(alternateLinks.map(async (link) => this.api.apiRequest(link, null, [200])));
const certificates = [resp].concat(alternates).map((c) => c.data);

@@ -687,5 +681,3 @@

async revokeCertificate(cert, data = {}) {
const body = forge.getPemBody(cert);
data.certificate = util.b64escape(body);
data.certificate = getPemBodyAsB64u(cert);
const resp = await this.api.revokeCert(data);

@@ -712,3 +704,3 @@ return resp.data;

* ```js
* const [certificateKey, certificateRequest] = await acme.forge.createCsr({
* const [certificateKey, certificateRequest] = await acme.crypto.createCsr({
* commonName: 'test.example.com'

@@ -732,3 +724,3 @@ * });

* ```js
* const [certificateKey, certificateRequest] = await acme.forge.createCsr({
* const [certificateKey, certificateRequest] = await acme.crypto.createCsr({
* commonName: 'test.example.com'

@@ -735,0 +727,0 @@ * });

/**
* node-forge crypto engine
* Legacy node-forge crypto interface
*
* DEPRECATION WARNING: This crypto interface is deprecated and will be removed from acme-client in a future
* major release. Please migrate to the new `acme.crypto` interface at your earliest convenience.
*
* @namespace forge

@@ -8,6 +11,6 @@ */

const net = require('net');
const Promise = require('bluebird');
const { promisify } = require('util');
const forge = require('node-forge');
const generateKeyPair = Promise.promisify(forge.pki.rsa.generateKeyPair);
const generateKeyPair = promisify(forge.pki.rsa.generateKeyPair);

@@ -146,3 +149,3 @@

/**
* Parse body of PEM encoded object form buffer or string
* Parse body of PEM encoded object from buffer or string
* If multiple objects are chained, the first body will be returned

@@ -149,0 +152,0 @@ *

@@ -5,7 +5,6 @@ /**

const crypto = require('crypto');
const { createHmac, createSign, constants: { RSA_PKCS1_PADDING } } = require('crypto');
const { getJwk } = require('./crypto');
const { log } = require('./logger');
const axios = require('./axios');
const util = require('./util');
const forge = require('./crypto/forge');

@@ -94,19 +93,10 @@

*
* @returns {Promise<object>} {e, kty, n}
* @returns {object} JSON Web Key
*/
async getJwk() {
if (this.jwk) {
return this.jwk;
getJwk() {
if (!this.jwk) {
this.jwk = getJwk(this.accountKey);
}
const exponent = await forge.getPublicExponent(this.accountKey);
const modulus = await forge.getModulus(this.accountKey);
this.jwk = {
e: util.b64encode(exponent),
kty: 'RSA',
n: util.b64encode(modulus)
};
return this.jwk;

@@ -181,6 +171,6 @@ }

* @param {string} [opts.kid] JWS KID
* @returns {Promise<object>} Signed HTTP request body
* @returns {object} Signed HTTP request body
*/
async prepareSignedBody(alg, url, payload = null, { nonce = null, kid = null } = {}) {
prepareSignedBody(alg, url, payload = null, { nonce = null, kid = null } = {}) {
const header = { alg, url };

@@ -199,3 +189,3 @@

else {
header.jwk = await this.getJwk();
header.jwk = this.getJwk();
}

@@ -205,4 +195,4 @@

return {
payload: payload ? util.b64encode(JSON.stringify(payload)) : '',
protected: util.b64encode(JSON.stringify(header))
payload: payload ? Buffer.from(JSON.stringify(payload)).toString('base64url') : '',
protected: Buffer.from(JSON.stringify(header)).toString('base64url')
};

@@ -213,3 +203,3 @@ }

/**
* Create signed HMAC HTTP request body
* Create JWS HTTP request body using HMAC
*

@@ -222,11 +212,11 @@ * @param {string} hmacKey HMAC key

* @param {string} [opts.kid] JWS KID
* @returns {Promise<object>} Signed HMAC request body
* @returns {object} Signed HMAC request body
*/
async createSignedHmacBody(hmacKey, url, payload = null, { nonce = null, kid = null } = {}) {
const result = await this.prepareSignedBody('HS256', url, payload, { nonce, kid });
createSignedHmacBody(hmacKey, url, payload = null, { nonce = null, kid = null } = {}) {
const result = this.prepareSignedBody('HS256', url, payload, { nonce, kid });
/* Signature */
const signer = crypto.createHmac('SHA256', Buffer.from(hmacKey, 'base64')).update(`${result.protected}.${result.payload}`, 'utf8');
result.signature = util.b64encode(signer.digest());
const signer = createHmac('SHA256', Buffer.from(hmacKey, 'base64')).update(`${result.protected}.${result.payload}`, 'utf8');
result.signature = signer.digest().toString('base64url');

@@ -238,4 +228,6 @@ return result;

/**
* Create signed RSA HTTP request body
* Create JWS HTTP request body using RSA or ECC
*
* https://datatracker.ietf.org/doc/html/rfc7515
*
* @param {string} url Request URL

@@ -246,12 +238,35 @@ * @param {object} [payload] Request payload

* @param {string} [opts.kid] JWS KID
* @returns {Promise<object>} Signed RSA request body
* @returns {object} JWS request body
*/
async createSignedRsaBody(url, payload = null, { nonce = null, kid = null } = {}) {
const result = await this.prepareSignedBody('RS256', url, payload, { nonce, kid });
createSignedBody(url, payload = null, { nonce = null, kid = null } = {}) {
const jwk = this.getJwk();
let headerAlg = 'RS256';
let signerAlg = 'SHA256';
/* Signature */
const signer = crypto.createSign('RSA-SHA256').update(`${result.protected}.${result.payload}`, 'utf8');
result.signature = util.b64escape(signer.sign(this.accountKey, 'base64'));
/* https://datatracker.ietf.org/doc/html/rfc7518#section-3.1 */
if (jwk.crv && (jwk.kty === 'EC')) {
headerAlg = 'ES256';
if (jwk.crv === 'P-384') {
headerAlg = 'ES384';
signerAlg = 'SHA384';
}
else if (jwk.crv === 'P-521') {
headerAlg = 'ES512';
signerAlg = 'SHA512';
}
}
/* Prepare body and signer */
const result = this.prepareSignedBody(headerAlg, url, payload, { nonce, kid });
const signer = createSign(signerAlg).update(`${result.protected}.${result.payload}`, 'utf8');
/* Signature - https://stackoverflow.com/questions/39554165 */
result.signature = signer.sign({
key: this.accountKey,
padding: RSA_PKCS1_PADDING,
dsaEncoding: 'ieee-p1363'
}, 'base64url');
return result;

@@ -284,7 +299,7 @@ }

if (this.externalAccountBinding.kid && this.externalAccountBinding.hmacKey) {
const jwk = await this.getJwk();
const jwk = this.getJwk();
const eabKid = this.externalAccountBinding.kid;
const eabHmacKey = this.externalAccountBinding.hmacKey;
payload.externalAccountBinding = await this.createSignedHmacBody(eabHmacKey, url, jwk, { kid: eabKid });
payload.externalAccountBinding = this.createSignedHmacBody(eabHmacKey, url, jwk, { kid: eabKid });
}

@@ -294,3 +309,3 @@ }

/* Sign body and send request */
const data = await this.createSignedRsaBody(url, payload, { nonce, kid });
const data = this.createSignedBody(url, payload, { nonce, kid });
const resp = await this.request(url, 'post', { data });

@@ -297,0 +312,0 @@

@@ -31,2 +31,3 @@ /**

exports.crypto = require('./crypto');
exports.forge = require('./crypto/forge');

@@ -33,0 +34,0 @@

@@ -5,10 +5,41 @@ /**

const Promise = require('bluebird');
const dns = Promise.promisifyAll(require('dns'));
const Backoff = require('backo2');
const dns = require('dns').promises;
const { readCertificateInfo, splitPemChain } = require('./crypto');
const { log } = require('./logger');
const forge = require('./crypto/forge');
/**
* Exponential backoff
*
* https://github.com/mokesmokes/backo
*
* @class
* @param {object} [opts]
* @param {number} [opts.min] Minimum backoff duration in ms
* @param {number} [opts.max] Maximum backoff duration in ms
*/
class Backoff {
constructor({ min = 100, max = 10000 } = {}) {
this.min = min;
this.max = max;
this.attempts = 0;
}
/**
* Get backoff duration
*
* @returns {number} Backoff duration in ms
*/
duration() {
const ms = this.min * (2 ** this.attempts);
this.attempts += 1;
return Math.min(ms, this.max);
}
}
/**
* Retry promise

@@ -37,3 +68,3 @@ *

await Promise.delay(duration);
await new Promise((resolve) => { setTimeout(resolve, duration); });
return retryPromise(fn, attempts, backoff);

@@ -62,29 +93,2 @@ }

/**
* Escape base64 encoded string
*
* @param {string} str Base64 encoded string
* @returns {string} Escaped string
*/
function b64escape(str) {
return str.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=/g, '');
}
/**
* Base64 encode and escape buffer or string
*
* @param {buffer|string} str Buffer or string to be encoded
* @returns {string} Escaped base64 encoded string
*/
function b64encode(str) {
const buf = Buffer.isBuffer(str) ? str : Buffer.from(str);
return b64escape(buf.toString('base64'));
}
/**
* Parse URLs from link header

@@ -110,34 +114,48 @@ *

/**
* Find certificate chain with preferred issuer
* If issuer can not be located, the first certificate will be returned
* Find certificate chain with preferred issuer common name
* - If issuer is found in multiple chains, the closest to root wins
* - If issuer can not be located, the first chain will be returned
*
* @param {array} certificates Array of PEM encoded certificate chains
* @param {string} issuer Preferred certificate issuer
* @returns {Promise<string>} PEM encoded certificate chain
* @returns {string} PEM encoded certificate chain
*/
async function findCertificateChainForIssuer(chains, issuer) {
try {
return await Promise.any(chains.map(async (chain) => {
/* Look up all issuers */
const certs = forge.splitPemChain(chain);
const infoCollection = await Promise.map(certs, forge.readCertificateInfo);
const issuerCollection = infoCollection.map((i) => i.issuer.commonName);
function findCertificateChainForIssuer(chains, issuer) {
log(`Attempting to find match for issuer="${issuer}" in ${chains.length} certificate chains`);
let bestMatch = null;
let bestDistance = null;
/* Found match, return it */
if (issuerCollection.includes(issuer)) {
log(`Found matching certificate for preferred issuer="${issuer}", issuers=${JSON.stringify(issuerCollection)}`);
return chain;
chains.forEach((chain) => {
/* Look up all issuers */
const certs = splitPemChain(chain);
const infoCollection = certs.map((c) => readCertificateInfo(c));
const issuerCollection = infoCollection.map((i) => i.issuer.commonName);
/* Found issuer match, get distance from root - lower is better */
if (issuerCollection.includes(issuer)) {
const distance = (issuerCollection.length - issuerCollection.indexOf(issuer));
log(`Found matching chain for preferred issuer="${issuer}" distance=${distance} issuers=${JSON.stringify(issuerCollection)}`);
/* Chain wins, use it */
if (!bestDistance || (distance < bestDistance)) {
log(`Issuer is closer to root than previous match, using it (${distance} < ${bestDistance || 'undefined'})`);
bestMatch = chain;
bestDistance = distance;
}
}
else {
/* No match */
log(`Unable to match certificate for preferred issuer="${issuer}", issuers=${JSON.stringify(issuerCollection)}`);
}
});
/* No match, throw error */
log(`Unable to match certificate for preferred issuer="${issuer}", issuers=${JSON.stringify(issuerCollection)}`);
throw new Error('Certificate issuer mismatch');
}));
/* Return found match */
if (bestMatch) {
return bestMatch;
}
catch (e) {
/* No certificates matched, return default */
log(`Found no match in ${chains.length} certificate chains for preferred issuer="${issuer}", returning default certificate chain`);
return chains[0];
}
/* No chains matched, return default */
log(`Found no match in ${chains.length} certificate chains for preferred issuer="${issuer}", returning default certificate chain`);
return chains[0];
}

@@ -176,3 +194,3 @@

try {
await dns.resolveSoaAsync(recordName);
await dns.resolveSoa(recordName);
log(`Found SOA record, considering domain to be: ${recordName}`);

@@ -211,4 +229,4 @@ return recordName;

log(`Looking up authoritative NS records for domain: ${domain}`);
const nsRecords = await dns.resolveNsAsync(domain);
const nsAddrArray = await Promise.map(nsRecords, async (r) => dns.resolve4Async(r));
const nsRecords = await dns.resolveNs(domain);
const nsAddrArray = await Promise.all(nsRecords.map(async (r) => dns.resolve4(r)));
const nsAddresses = [].concat(...nsAddrArray).filter((a) => a);

@@ -242,4 +260,2 @@

retry,
b64escape,
b64encode,
parseLinkHeader,

@@ -246,0 +262,0 @@ findCertificateChainForIssuer,

@@ -5,4 +5,3 @@ /**

const Promise = require('bluebird');
const dns = Promise.promisifyAll(require('dns'));
const dns = require('dns').promises;
const { log } = require('./logger');

@@ -52,3 +51,3 @@ const axios = require('./axios');

log(`Checking name for CNAME records: ${recordName}`);
const cnameRecords = await resolver.resolveCnameAsync(recordName);
const cnameRecords = await resolver.resolveCname(recordName);

@@ -67,3 +66,3 @@ if (cnameRecords.length) {

log(`Checking name for TXT records: ${recordName}`);
const txtRecords = await resolver.resolveTxtAsync(recordName);
const txtRecords = await resolver.resolveTxt(recordName);

@@ -70,0 +69,0 @@ if (txtRecords.length) {

@@ -78,3 +78,3 @@ /**

waitForValidStatus<T = Order | Authorization | rfc8555.Challenge>(item: T): Promise<T>;
getCertificate(order: Order, preferredChain?: string | null): Promise<string>;
getCertificate(order: Order, preferredChain?: string): Promise<string>;
revokeCertificate(cert: CertificateBuffer | CertificateString, data?: rfc8555.CertificateRevocationRequest): Promise<void>;

@@ -136,3 +136,32 @@ auto(opts: ClientAutoOptions): Promise<string>;

export interface RsaPublicJwk {
e: string;
kty: string;
n: string;
}
export interface EcdsaPublicJwk {
crv: string;
kty: string;
x: string;
y: string;
}
export interface CryptoInterface {
createPrivateKey(keySize?: number): Promise<PrivateKeyBuffer>;
createPrivateRsaKey(keySize?: number): Promise<PrivateKeyBuffer>;
createPrivateEcdsaKey(namedCurve?: 'P-256' | 'P-384' | 'P-521'): Promise<PrivateKeyBuffer>;
getPublicKey(keyPem: PrivateKeyBuffer | PrivateKeyString | PublicKeyBuffer | PublicKeyString): PublicKeyBuffer;
getJwk(keyPem: PrivateKeyBuffer | PrivateKeyString | PublicKeyBuffer | PublicKeyString): RsaPublicJwk | EcdsaPublicJwk;
splitPemChain(chainPem: CertificateBuffer | CertificateString): string[];
getPemBodyAsB64u(pem: CertificateBuffer | CertificateString): string;
readCsrDomains(csrPem: CsrBuffer | CsrString): CertificateDomains;
readCertificateInfo(certPem: CertificateBuffer | CertificateString): CertificateInfo;
createCsr(data: CsrOptions, keyPem?: PrivateKeyBuffer | PrivateKeyString): Promise<[PrivateKeyBuffer, CsrBuffer]>;
}
export const crypto: CryptoInterface;
/* TODO: LEGACY */
export interface CryptoLegacyInterface {
createPrivateKey(size?: number): Promise<PrivateKeyBuffer>;

@@ -149,3 +178,3 @@ createPublicKey(key: PrivateKeyBuffer | PrivateKeyString): Promise<PublicKeyBuffer>;

export const forge: CryptoInterface;
export const forge: CryptoLegacyInterface;

@@ -152,0 +181,0 @@

@@ -10,3 +10,3 @@ /**

/* Client */
const accountKey = await acme.forge.createPrivateKey();
const accountKey = await acme.crypto.createPrivateKey();

@@ -45,3 +45,3 @@ const client = new acme.Client({

/* Finalize */
const [certKey, certCsr] = await acme.forge.createCsr({
const [certKey, certCsr] = await acme.crypto.createCsr({
commonName: 'example.com',

@@ -48,0 +48,0 @@ altNames: ['example.com', '*.example.com']

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc