@certd/acme-client 1.27.1 → 1.27.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +10 -5
- package/src/api.js +2 -4
- package/src/auto.js +5 -5
- package/src/axios.js +11 -14
- package/src/client.js +11 -10
- package/src/crypto/forge.js +13 -15
- package/src/crypto/index.js +17 -20
- package/src/error.js +1 -4
- package/src/http.js +6 -6
- package/src/index.js +9 -12
- package/src/logger.js +4 -3
- package/src/util.js +7 -5
- package/src/verify.js +10 -9
- package/src/wait.js +1 -5
- package/src/agents.js +0 -110
package/package.json
CHANGED
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
"description": "Simple and unopinionated ACME client",
|
|
4
4
|
"private": false,
|
|
5
5
|
"author": "nmorsman",
|
|
6
|
-
"version": "1.27.
|
|
6
|
+
"version": "1.27.3",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"module": "scr/index.js",
|
|
7
9
|
"main": "src/index.js",
|
|
8
10
|
"types": "types/index.d.ts",
|
|
9
11
|
"license": "MIT",
|
|
@@ -16,12 +18,14 @@
|
|
|
16
18
|
"types"
|
|
17
19
|
],
|
|
18
20
|
"dependencies": {
|
|
21
|
+
"@certd/basic": "^1.27.3",
|
|
19
22
|
"@peculiar/x509": "^1.11.0",
|
|
20
23
|
"asn1js": "^3.0.5",
|
|
21
24
|
"axios": "^1.7.2",
|
|
22
25
|
"debug": "^4.3.5",
|
|
23
26
|
"http-proxy-agent": "^7.0.2",
|
|
24
27
|
"https-proxy-agent": "^7.0.5",
|
|
28
|
+
"lodash-es": "^4.17.21",
|
|
25
29
|
"node-forge": "^1.3.1"
|
|
26
30
|
},
|
|
27
31
|
"devDependencies": {
|
|
@@ -29,14 +33,15 @@
|
|
|
29
33
|
"chai": "^4.4.1",
|
|
30
34
|
"chai-as-promised": "^7.1.2",
|
|
31
35
|
"eslint": "^8.57.0",
|
|
32
|
-
"eslint-config-
|
|
36
|
+
"eslint-config-prettier": "^8.5.0",
|
|
33
37
|
"eslint-plugin-import": "^2.29.1",
|
|
38
|
+
"eslint-plugin-prettier": "^4.2.1",
|
|
34
39
|
"jsdoc-to-markdown": "^8.0.1",
|
|
35
40
|
"mocha": "^10.6.0",
|
|
36
41
|
"nock": "^13.5.4",
|
|
42
|
+
"prettier": "^2.8.8",
|
|
37
43
|
"tsd": "^0.31.1",
|
|
38
|
-
"typescript": "^5.4.2"
|
|
39
|
-
"uuid": "^8.3.2"
|
|
44
|
+
"typescript": "^5.4.2"
|
|
40
45
|
},
|
|
41
46
|
"scripts": {
|
|
42
47
|
"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",
|
|
@@ -60,5 +65,5 @@
|
|
|
60
65
|
"bugs": {
|
|
61
66
|
"url": "https://github.com/publishlab/node-acme-client/issues"
|
|
62
67
|
},
|
|
63
|
-
"gitHead": "
|
|
68
|
+
"gitHead": "1eb70d4cfd1ed2f746369658db2559fe01718324"
|
|
64
69
|
}
|
package/src/api.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ACME API client
|
|
3
3
|
*/
|
|
4
|
-
|
|
5
|
-
const util = require('./util');
|
|
6
|
-
const { log } = require('./logger');
|
|
4
|
+
import * as util from './util.js';
|
|
7
5
|
|
|
8
6
|
/**
|
|
9
7
|
* AcmeApi
|
|
@@ -248,4 +246,4 @@ class AcmeApi {
|
|
|
248
246
|
}
|
|
249
247
|
|
|
250
248
|
/* Export API */
|
|
251
|
-
|
|
249
|
+
export default AcmeApi;
|
package/src/auto.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ACME auto helper
|
|
3
3
|
*/
|
|
4
|
+
import { readCsrDomains } from './crypto/index.js';
|
|
5
|
+
import { log } from './logger.js';
|
|
6
|
+
import { wait } from './wait.js';
|
|
7
|
+
import { CancelError } from './error.js';
|
|
4
8
|
|
|
5
|
-
const { readCsrDomains } = require('./crypto');
|
|
6
|
-
const { log } = require('./logger');
|
|
7
|
-
const { wait } = require('./wait');
|
|
8
|
-
const { CancelError } = require('./error');
|
|
9
9
|
|
|
10
10
|
const defaultOpts = {
|
|
11
11
|
csr: null,
|
|
@@ -30,7 +30,7 @@ const defaultOpts = {
|
|
|
30
30
|
* @returns {Promise<buffer>} Certificate
|
|
31
31
|
*/
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
export default async (client, userOpts) => {
|
|
34
34
|
const opts = { ...defaultOpts, ...userOpts };
|
|
35
35
|
const accountPayload = { termsOfServiceAgreed: opts.termsOfServiceAgreed };
|
|
36
36
|
|
package/src/axios.js
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Axios instance
|
|
3
3
|
*/
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const pkg = require('./../package.json');
|
|
8
|
-
const Agents = require('./agents');
|
|
9
|
-
|
|
4
|
+
import axios from 'axios';
|
|
5
|
+
import { parseRetryAfterHeader } from './util.js';
|
|
6
|
+
import { log } from './logger.js';
|
|
10
7
|
const { AxiosError } = axios;
|
|
11
|
-
|
|
8
|
+
import {getGlobalAgents, HttpError} from '@certd/basic'
|
|
12
9
|
/**
|
|
13
10
|
* Defaults
|
|
14
11
|
*/
|
|
@@ -16,7 +13,7 @@ const { AxiosError } = axios;
|
|
|
16
13
|
const instance = axios.create();
|
|
17
14
|
|
|
18
15
|
/* Default User-Agent */
|
|
19
|
-
instance.defaults.headers.common['User-Agent'] =
|
|
16
|
+
instance.defaults.headers.common['User-Agent'] = `@certd/acme-client`;
|
|
20
17
|
|
|
21
18
|
/* Default ACME settings */
|
|
22
19
|
instance.defaults.acmeSettings = {
|
|
@@ -75,7 +72,7 @@ function validateStatus(response) {
|
|
|
75
72
|
response,
|
|
76
73
|
);
|
|
77
74
|
|
|
78
|
-
throw new
|
|
75
|
+
throw new HttpError(err);
|
|
79
76
|
}
|
|
80
77
|
|
|
81
78
|
/* Pass all responses through the error interceptor */
|
|
@@ -85,7 +82,7 @@ instance.interceptors.request.use((config) => {
|
|
|
85
82
|
}
|
|
86
83
|
config.validateStatus = () => false;
|
|
87
84
|
|
|
88
|
-
const agents =
|
|
85
|
+
const agents = getGlobalAgents();
|
|
89
86
|
// if (config.skipSslVerify) {
|
|
90
87
|
// logger.info('跳过SSL验证');
|
|
91
88
|
// agents = createAgent({ rejectUnauthorized: false } as any);
|
|
@@ -102,7 +99,7 @@ instance.interceptors.response.use(null, async (error) => {
|
|
|
102
99
|
const { config, response } = error;
|
|
103
100
|
|
|
104
101
|
if (!config) {
|
|
105
|
-
return Promise.reject(new
|
|
102
|
+
return Promise.reject(new HttpError(error));
|
|
106
103
|
}
|
|
107
104
|
|
|
108
105
|
/* Pick up errors we want to retry */
|
|
@@ -122,7 +119,7 @@ instance.interceptors.response.use(null, async (error) => {
|
|
|
122
119
|
const waitMinutes = (headerRetryAfter / 60).toFixed(1);
|
|
123
120
|
log(`Found retry-after response header with value: ${response.headers['retry-after']}, waiting ${waitMinutes} minutes`);
|
|
124
121
|
log(JSON.stringify(response.data));
|
|
125
|
-
return Promise.reject(new
|
|
122
|
+
return Promise.reject(new HttpError(error));
|
|
126
123
|
}
|
|
127
124
|
|
|
128
125
|
log(`waiting ${retryAfter} seconds`);
|
|
@@ -134,7 +131,7 @@ instance.interceptors.response.use(null, async (error) => {
|
|
|
134
131
|
}
|
|
135
132
|
|
|
136
133
|
if (!response) {
|
|
137
|
-
return Promise.reject(new
|
|
134
|
+
return Promise.reject(new HttpError(error));
|
|
138
135
|
}
|
|
139
136
|
/* Validate and return response */
|
|
140
137
|
return validateStatus(response);
|
|
@@ -144,4 +141,4 @@ instance.interceptors.response.use(null, async (error) => {
|
|
|
144
141
|
* Export instance
|
|
145
142
|
*/
|
|
146
143
|
|
|
147
|
-
|
|
144
|
+
export default instance;
|
package/src/client.js
CHANGED
|
@@ -3,16 +3,17 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @namespace Client
|
|
5
5
|
*/
|
|
6
|
+
import { createHash } from 'crypto';
|
|
7
|
+
import { getPemBodyAsB64u } from './crypto/index.js';
|
|
8
|
+
import { log } from './logger.js';
|
|
9
|
+
import HttpClient from './http.js';
|
|
10
|
+
import AcmeApi from './api.js';
|
|
11
|
+
import verify from './verify.js';
|
|
12
|
+
import * as util from './util.js';
|
|
13
|
+
import auto from './auto.js';
|
|
14
|
+
import { CancelError } from './error.js';
|
|
15
|
+
|
|
6
16
|
|
|
7
|
-
const { createHash } = require('crypto');
|
|
8
|
-
const { getPemBodyAsB64u } = require('./crypto');
|
|
9
|
-
const { log } = require('./logger');
|
|
10
|
-
const HttpClient = require('./http');
|
|
11
|
-
const AcmeApi = require('./api');
|
|
12
|
-
const verify = require('./verify');
|
|
13
|
-
const util = require('./util');
|
|
14
|
-
const auto = require('./auto');
|
|
15
|
-
const { CancelError } = require('./error');
|
|
16
17
|
|
|
17
18
|
/**
|
|
18
19
|
* ACME states
|
|
@@ -719,4 +720,4 @@ class AcmeClient {
|
|
|
719
720
|
}
|
|
720
721
|
|
|
721
722
|
/* Export client */
|
|
722
|
-
|
|
723
|
+
export default AcmeClient;
|
package/src/crypto/forge.js
CHANGED
|
@@ -6,11 +6,10 @@
|
|
|
6
6
|
*
|
|
7
7
|
* @namespace forge
|
|
8
8
|
*/
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const { createPrivateEcdsaKey, getPublicKey } = require('./index');
|
|
9
|
+
import net from 'net';
|
|
10
|
+
import { promisify } from 'util';
|
|
11
|
+
import forge from 'node-forge';
|
|
12
|
+
import { createPrivateEcdsaKey } from './index.js';
|
|
14
13
|
|
|
15
14
|
const generateKeyPair = promisify(forge.pki.rsa.generateKeyPair);
|
|
16
15
|
|
|
@@ -113,13 +112,12 @@ function parseDomains(obj) {
|
|
|
113
112
|
* ```
|
|
114
113
|
*/
|
|
115
114
|
|
|
116
|
-
async function createPrivateKey(size = 2048) {
|
|
115
|
+
export async function createPrivateKey(size = 2048) {
|
|
117
116
|
const keyPair = await generateKeyPair({ bits: size });
|
|
118
117
|
const pemKey = forge.pki.privateKeyToPem(keyPair.privateKey);
|
|
119
118
|
return Buffer.from(pemKey);
|
|
120
119
|
}
|
|
121
120
|
|
|
122
|
-
exports.createPrivateKey = createPrivateKey;
|
|
123
121
|
|
|
124
122
|
/**
|
|
125
123
|
* Create public key from a private RSA key
|
|
@@ -133,7 +131,7 @@ exports.createPrivateKey = createPrivateKey;
|
|
|
133
131
|
* ```
|
|
134
132
|
*/
|
|
135
133
|
|
|
136
|
-
|
|
134
|
+
export const createPublicKey = async (key) => {
|
|
137
135
|
const privateKey = forge.pki.privateKeyFromPem(key);
|
|
138
136
|
const publicKey = forge.pki.rsa.setPublicKey(privateKey.n, privateKey.e);
|
|
139
137
|
const pemKey = forge.pki.publicKeyToPem(publicKey);
|
|
@@ -148,7 +146,7 @@ exports.createPublicKey = async (key) => {
|
|
|
148
146
|
* @returns {string} PEM body
|
|
149
147
|
*/
|
|
150
148
|
|
|
151
|
-
|
|
149
|
+
export const getPemBody = (str) => {
|
|
152
150
|
const msg = forge.pem.decode(str)[0];
|
|
153
151
|
return forge.util.encode64(msg.body);
|
|
154
152
|
};
|
|
@@ -160,7 +158,7 @@ exports.getPemBody = (str) => {
|
|
|
160
158
|
* @returns {string[]} Array of PEM bodies
|
|
161
159
|
*/
|
|
162
160
|
|
|
163
|
-
|
|
161
|
+
export const splitPemChain = (str) => forge.pem.decode(str).map(forge.pem.encode);
|
|
164
162
|
|
|
165
163
|
/**
|
|
166
164
|
* Get modulus
|
|
@@ -176,7 +174,7 @@ exports.splitPemChain = (str) => forge.pem.decode(str).map(forge.pem.encode);
|
|
|
176
174
|
* ```
|
|
177
175
|
*/
|
|
178
176
|
|
|
179
|
-
|
|
177
|
+
export const getModulus = async (input) => {
|
|
180
178
|
if (!Buffer.isBuffer(input)) {
|
|
181
179
|
input = Buffer.from(input);
|
|
182
180
|
}
|
|
@@ -199,7 +197,7 @@ exports.getModulus = async (input) => {
|
|
|
199
197
|
* ```
|
|
200
198
|
*/
|
|
201
199
|
|
|
202
|
-
|
|
200
|
+
export const getPublicExponent = async (input) => {
|
|
203
201
|
if (!Buffer.isBuffer(input)) {
|
|
204
202
|
input = Buffer.from(input);
|
|
205
203
|
}
|
|
@@ -223,7 +221,7 @@ exports.getPublicExponent = async (input) => {
|
|
|
223
221
|
* ```
|
|
224
222
|
*/
|
|
225
223
|
|
|
226
|
-
|
|
224
|
+
export const readCsrDomains = async (csr) => {
|
|
227
225
|
if (!Buffer.isBuffer(csr)) {
|
|
228
226
|
csr = Buffer.from(csr);
|
|
229
227
|
}
|
|
@@ -251,7 +249,7 @@ exports.readCsrDomains = async (csr) => {
|
|
|
251
249
|
* ```
|
|
252
250
|
*/
|
|
253
251
|
|
|
254
|
-
|
|
252
|
+
export const readCertificateInfo = async (cert) => {
|
|
255
253
|
if (!Buffer.isBuffer(cert)) {
|
|
256
254
|
cert = Buffer.from(cert);
|
|
257
255
|
}
|
|
@@ -379,7 +377,7 @@ function formatCsrAltNames(altNames) {
|
|
|
379
377
|
* }, certificateKey);
|
|
380
378
|
*/
|
|
381
379
|
|
|
382
|
-
|
|
380
|
+
export const createCsr = async (data, keyType = null) => {
|
|
383
381
|
let key = null;
|
|
384
382
|
if (keyType === 'ec') {
|
|
385
383
|
key = await createPrivateEcdsaKey();
|
package/src/crypto/index.js
CHANGED
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @namespace crypto
|
|
5
5
|
*/
|
|
6
|
+
import net from 'net';
|
|
7
|
+
import { promisify } from 'util';
|
|
8
|
+
import crypto from 'crypto';
|
|
9
|
+
import asn1js from 'asn1js';
|
|
10
|
+
import x509 from '@peculiar/x509';
|
|
6
11
|
|
|
7
|
-
const net = require('net');
|
|
8
|
-
const { promisify } = require('util');
|
|
9
|
-
const crypto = require('crypto');
|
|
10
|
-
const asn1js = require('asn1js');
|
|
11
|
-
const x509 = require('@peculiar/x509');
|
|
12
12
|
|
|
13
13
|
const randomInt = promisify(crypto.randomInt);
|
|
14
14
|
const generateKeyPair = promisify(crypto.generateKeyPair);
|
|
@@ -67,7 +67,7 @@ function getKeyInfo(keyPem) {
|
|
|
67
67
|
* ```
|
|
68
68
|
*/
|
|
69
69
|
|
|
70
|
-
async function createPrivateRsaKey(modulusLength = 2048, encodingType = 'pkcs8') {
|
|
70
|
+
export async function createPrivateRsaKey(modulusLength = 2048, encodingType = 'pkcs8') {
|
|
71
71
|
const pair = await generateKeyPair('rsa', {
|
|
72
72
|
modulusLength,
|
|
73
73
|
privateKeyEncoding: {
|
|
@@ -79,7 +79,6 @@ async function createPrivateRsaKey(modulusLength = 2048, encodingType = 'pkcs8')
|
|
|
79
79
|
return Buffer.from(pair.privateKey);
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
exports.createPrivateRsaKey = createPrivateRsaKey;
|
|
83
82
|
|
|
84
83
|
/**
|
|
85
84
|
* Alias of `createPrivateRsaKey()`
|
|
@@ -87,7 +86,7 @@ exports.createPrivateRsaKey = createPrivateRsaKey;
|
|
|
87
86
|
* @function
|
|
88
87
|
*/
|
|
89
88
|
|
|
90
|
-
|
|
89
|
+
export const createPrivateKey = createPrivateRsaKey;
|
|
91
90
|
|
|
92
91
|
/**
|
|
93
92
|
* Generate a private ECDSA key
|
|
@@ -106,7 +105,7 @@ exports.createPrivateKey = createPrivateRsaKey;
|
|
|
106
105
|
* ```
|
|
107
106
|
*/
|
|
108
107
|
|
|
109
|
-
|
|
108
|
+
export const createPrivateEcdsaKey = async (namedCurve = 'P-256', encodingType = 'pkcs8') => {
|
|
110
109
|
const pair = await generateKeyPair('ec', {
|
|
111
110
|
namedCurve,
|
|
112
111
|
privateKeyEncoding: {
|
|
@@ -130,7 +129,7 @@ exports.createPrivateEcdsaKey = async (namedCurve = 'P-256', encodingType = 'pkc
|
|
|
130
129
|
* ```
|
|
131
130
|
*/
|
|
132
131
|
|
|
133
|
-
|
|
132
|
+
export const getPublicKey = (keyPem) => {
|
|
134
133
|
const info = getKeyInfo(keyPem);
|
|
135
134
|
|
|
136
135
|
const publicKey = info.publicKey.export({
|
|
@@ -155,7 +154,7 @@ exports.getPublicKey = (keyPem) => {
|
|
|
155
154
|
* ```
|
|
156
155
|
*/
|
|
157
156
|
|
|
158
|
-
function getJwk(keyPem) {
|
|
157
|
+
export function getJwk(keyPem) {
|
|
159
158
|
const jwk = crypto.createPublicKey(keyPem).export({
|
|
160
159
|
format: 'jwk',
|
|
161
160
|
});
|
|
@@ -167,7 +166,6 @@ function getJwk(keyPem) {
|
|
|
167
166
|
}, {});
|
|
168
167
|
}
|
|
169
168
|
|
|
170
|
-
exports.getJwk = getJwk;
|
|
171
169
|
|
|
172
170
|
/**
|
|
173
171
|
* Produce CryptoKeyPair and signing algorithm from a PEM encoded private key
|
|
@@ -215,7 +213,7 @@ async function getWebCryptoKeyPair(keyPem) {
|
|
|
215
213
|
* @returns {string[]} Array of PEM objects including headers
|
|
216
214
|
*/
|
|
217
215
|
|
|
218
|
-
function splitPemChain(chainPem) {
|
|
216
|
+
export function splitPemChain(chainPem) {
|
|
219
217
|
if (Buffer.isBuffer(chainPem)) {
|
|
220
218
|
chainPem = chainPem.toString();
|
|
221
219
|
}
|
|
@@ -225,7 +223,6 @@ function splitPemChain(chainPem) {
|
|
|
225
223
|
.map((params) => x509.PemConverter.encode([params]));
|
|
226
224
|
}
|
|
227
225
|
|
|
228
|
-
exports.splitPemChain = splitPemChain;
|
|
229
226
|
|
|
230
227
|
/**
|
|
231
228
|
* Parse body of PEM encoded object and return a Base64URL string
|
|
@@ -235,7 +232,7 @@ exports.splitPemChain = splitPemChain;
|
|
|
235
232
|
* @returns {string} Base64URL-encoded body
|
|
236
233
|
*/
|
|
237
234
|
|
|
238
|
-
|
|
235
|
+
export const getPemBodyAsB64u = (pem) => {
|
|
239
236
|
const chain = splitPemChain(pem);
|
|
240
237
|
|
|
241
238
|
if (!chain.length) {
|
|
@@ -286,7 +283,7 @@ function parseDomains(input) {
|
|
|
286
283
|
* ```
|
|
287
284
|
*/
|
|
288
285
|
|
|
289
|
-
|
|
286
|
+
export const readCsrDomains = (csrPem) => {
|
|
290
287
|
if (Buffer.isBuffer(csrPem)) {
|
|
291
288
|
csrPem = csrPem.toString();
|
|
292
289
|
}
|
|
@@ -315,7 +312,7 @@ exports.readCsrDomains = (csrPem) => {
|
|
|
315
312
|
* ```
|
|
316
313
|
*/
|
|
317
314
|
|
|
318
|
-
|
|
315
|
+
export const readCertificateInfo = (certPem) => {
|
|
319
316
|
if (Buffer.isBuffer(certPem)) {
|
|
320
317
|
certPem = certPem.toString();
|
|
321
318
|
}
|
|
@@ -449,7 +446,7 @@ function createSubjectAltNameExtension(altNames) {
|
|
|
449
446
|
* ```
|
|
450
447
|
*/
|
|
451
448
|
|
|
452
|
-
|
|
449
|
+
export const createCsr = async (data, keyPem = null) => {
|
|
453
450
|
if (!keyPem) {
|
|
454
451
|
keyPem = await createPrivateRsaKey(data.keySize);
|
|
455
452
|
}
|
|
@@ -520,7 +517,7 @@ exports.createCsr = async (data, keyPem = null) => {
|
|
|
520
517
|
* ```
|
|
521
518
|
*/
|
|
522
519
|
|
|
523
|
-
|
|
520
|
+
export const createAlpnCertificate = async (authz, keyAuthorization, keyPem = null) => {
|
|
524
521
|
if (!keyPem) {
|
|
525
522
|
keyPem = await createPrivateRsaKey();
|
|
526
523
|
}
|
|
@@ -583,7 +580,7 @@ exports.createAlpnCertificate = async (authz, keyAuthorization, keyPem = null) =
|
|
|
583
580
|
* @returns {boolean} True when valid
|
|
584
581
|
*/
|
|
585
582
|
|
|
586
|
-
|
|
583
|
+
export const isAlpnCertificateAuthorizationValid = (certPem, keyAuthorization) => {
|
|
587
584
|
const expected = crypto.createHash('sha256').update(keyAuthorization).digest('hex');
|
|
588
585
|
|
|
589
586
|
/* Attempt to locate ALPN extension */
|
package/src/error.js
CHANGED
package/src/http.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ACME HTTP client
|
|
3
3
|
*/
|
|
4
|
-
|
|
5
|
-
const {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
import { createHmac, createSign, constants } from 'crypto';
|
|
5
|
+
const { RSA_PKCS1_PADDING } = constants;
|
|
6
|
+
import axios from './axios.js';
|
|
7
|
+
import { log } from './logger.js';
|
|
8
|
+
import { getJwk } from './crypto/index.js';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* ACME HTTP client
|
|
@@ -324,4 +324,4 @@ class HttpClient {
|
|
|
324
324
|
}
|
|
325
325
|
|
|
326
326
|
/* Export client */
|
|
327
|
-
|
|
327
|
+
export default HttpClient;
|
package/src/index.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* acme-client
|
|
3
3
|
*/
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
import AcmeClinet from './client.js'
|
|
5
|
+
export const Client = AcmeClinet
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Directory URLs
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
export const directory = {
|
|
12
12
|
buypass: {
|
|
13
13
|
staging: 'https://api.test4.buypass.no/acme/directory',
|
|
14
14
|
production: 'https://api.buypass.com/acme/directory',
|
|
@@ -31,21 +31,18 @@ exports.directory = {
|
|
|
31
31
|
* Crypto
|
|
32
32
|
*/
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
export * as crypto from './crypto/index.js'
|
|
35
|
+
export * as forge from './crypto/forge.js'
|
|
36
36
|
|
|
37
37
|
/**
|
|
38
38
|
* Axios
|
|
39
39
|
*/
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
exports.agents = require('./agents');
|
|
43
|
-
|
|
41
|
+
export * from './axios.js'
|
|
44
42
|
/**
|
|
45
43
|
* Logger
|
|
46
44
|
*/
|
|
47
45
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
exports.CancelError = require('./error').CancelError;
|
|
46
|
+
export * from './logger.js'
|
|
47
|
+
export * from './verify.js'
|
|
48
|
+
export * from './error.js'
|
package/src/logger.js
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
* ACME logger
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
import debugg from 'debug'
|
|
6
|
+
const debug = debugg('acme-client');
|
|
6
7
|
|
|
7
8
|
let logger = () => {};
|
|
8
9
|
|
|
@@ -12,7 +13,7 @@ let logger = () => {};
|
|
|
12
13
|
* @param {function} fn Logger function
|
|
13
14
|
*/
|
|
14
15
|
|
|
15
|
-
|
|
16
|
+
export const setLogger = (fn) => {
|
|
16
17
|
logger = fn;
|
|
17
18
|
};
|
|
18
19
|
|
|
@@ -22,7 +23,7 @@ exports.setLogger = (fn) => {
|
|
|
22
23
|
* @param {string} msg Message
|
|
23
24
|
*/
|
|
24
25
|
|
|
25
|
-
|
|
26
|
+
export const log = (...msg) => {
|
|
26
27
|
debug(...msg);
|
|
27
28
|
logger(...msg);
|
|
28
29
|
};
|
package/src/util.js
CHANGED
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
* Utility methods
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
import tls from 'tls';
|
|
6
|
+
import dnsSdk from 'dns';
|
|
7
|
+
import { readCertificateInfo, splitPemChain }from './crypto/index.js'
|
|
8
|
+
import { log } from './logger.js'
|
|
9
9
|
|
|
10
|
+
const dns = dnsSdk.promises;
|
|
10
11
|
/**
|
|
11
12
|
* Exponential backoff
|
|
12
13
|
*
|
|
@@ -329,7 +330,7 @@ async function retrieveTlsAlpnCertificate(host, port, timeout = 30000) {
|
|
|
329
330
|
* Export utils
|
|
330
331
|
*/
|
|
331
332
|
|
|
332
|
-
|
|
333
|
+
export {
|
|
333
334
|
retry,
|
|
334
335
|
parseLinkHeader,
|
|
335
336
|
parseRetryAfterHeader,
|
|
@@ -338,3 +339,4 @@ module.exports = {
|
|
|
338
339
|
getAuthoritativeDnsResolver,
|
|
339
340
|
retrieveTlsAlpnCertificate,
|
|
340
341
|
};
|
|
342
|
+
|
package/src/verify.js
CHANGED
|
@@ -2,13 +2,15 @@
|
|
|
2
2
|
* ACME challenge verification
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
import dnsSdk from "dns"
|
|
6
|
+
import https from 'https'
|
|
7
|
+
import {log} from './logger.js'
|
|
8
|
+
import axios from './axios.js'
|
|
9
|
+
import * as util from './util.js'
|
|
10
|
+
import {isAlpnCertificateAuthorizationValid} from './crypto/index.js'
|
|
11
11
|
|
|
12
|
+
|
|
13
|
+
const dns = dnsSdk.promises
|
|
12
14
|
/**
|
|
13
15
|
* Verify ACME HTTP challenge
|
|
14
16
|
*
|
|
@@ -79,7 +81,7 @@ async function walkDnsChallengeRecord(recordName, resolver = dns) {
|
|
|
79
81
|
}
|
|
80
82
|
}
|
|
81
83
|
|
|
82
|
-
async function walkTxtRecord(recordName) {
|
|
84
|
+
export async function walkTxtRecord(recordName) {
|
|
83
85
|
try {
|
|
84
86
|
/* Default DNS resolver first */
|
|
85
87
|
log('Attempting to resolve TXT with default DNS resolver first');
|
|
@@ -153,9 +155,8 @@ async function verifyTlsAlpnChallenge(authz, challenge, keyAuthorization) {
|
|
|
153
155
|
* Export API
|
|
154
156
|
*/
|
|
155
157
|
|
|
156
|
-
|
|
158
|
+
export default {
|
|
157
159
|
'http-01': verifyHttpChallenge,
|
|
158
160
|
'dns-01': verifyDnsChallenge,
|
|
159
161
|
'tls-alpn-01': verifyTlsAlpnChallenge,
|
|
160
|
-
walkTxtRecord,
|
|
161
162
|
};
|
package/src/wait.js
CHANGED
package/src/agents.js
DELETED
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
const nodeHttp = require('node:http');
|
|
2
|
-
const https = require('node:https');
|
|
3
|
-
const { HttpProxyAgent } = require('http-proxy-agent');
|
|
4
|
-
const { HttpsProxyAgent } = require('https-proxy-agent');
|
|
5
|
-
const { log } = require('./logger');
|
|
6
|
-
|
|
7
|
-
function createAgent(opts = {}) {
|
|
8
|
-
let httpAgent;
|
|
9
|
-
let
|
|
10
|
-
httpsAgent;
|
|
11
|
-
const httpProxy = opts.httpProxy || process.env.HTTP_PROXY || process.env.http_proxy;
|
|
12
|
-
if (httpProxy) {
|
|
13
|
-
log(`acme use httpProxy:${httpProxy}`);
|
|
14
|
-
httpAgent = new HttpProxyAgent(httpProxy, opts);
|
|
15
|
-
}
|
|
16
|
-
else {
|
|
17
|
-
httpAgent = new nodeHttp.Agent(opts);
|
|
18
|
-
}
|
|
19
|
-
const httpsProxy = opts.httpsProxy || process.env.HTTPS_PROXY || process.env.https_proxy;
|
|
20
|
-
if (httpsProxy) {
|
|
21
|
-
log(`acme use httpsProxy:${httpsProxy}`);
|
|
22
|
-
httpsAgent = new HttpsProxyAgent(httpsProxy, opts);
|
|
23
|
-
}
|
|
24
|
-
else {
|
|
25
|
-
httpsAgent = new https.Agent(opts);
|
|
26
|
-
}
|
|
27
|
-
return {
|
|
28
|
-
httpAgent,
|
|
29
|
-
httpsAgent,
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
let defaultAgents = createAgent();
|
|
34
|
-
|
|
35
|
-
function getGlobalAgents() {
|
|
36
|
-
return defaultAgents;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
function setGlobalProxy(opts) {
|
|
40
|
-
log('acme setGlobalProxy:', opts);
|
|
41
|
-
defaultAgents = createAgent(opts);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
class HttpError extends Error {
|
|
45
|
-
// eslint-disable-next-line constructor-super
|
|
46
|
-
constructor(error) {
|
|
47
|
-
if (!error) {
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
super(error.message);
|
|
51
|
-
|
|
52
|
-
this.message = error.message;
|
|
53
|
-
const { message } = error;
|
|
54
|
-
if (message && typeof message === 'string') {
|
|
55
|
-
if (message.indexOf && message.indexOf('ssl3_get_record:wrong version number') >= 0) {
|
|
56
|
-
this.message = `${message}(http协议错误,服务端要求http协议,请检查是否使用了https请求)`;
|
|
57
|
-
}
|
|
58
|
-
else if (message.indexOf('getaddrinfo EAI_AGAIN')) {
|
|
59
|
-
this.message = `${message}(无法解析域名,请检查网络连接或dns配置)`;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
this.name = error.name;
|
|
64
|
-
this.code = error.code;
|
|
65
|
-
|
|
66
|
-
if (error.response) {
|
|
67
|
-
this.status = error.response.status;
|
|
68
|
-
this.statusText = error.response.statusText;
|
|
69
|
-
this.response = {
|
|
70
|
-
data: error.response.data,
|
|
71
|
-
};
|
|
72
|
-
if (!this.message) {
|
|
73
|
-
this.message = this.statusText;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
let url = '';
|
|
78
|
-
if (error.config) {
|
|
79
|
-
this.request = {
|
|
80
|
-
baseURL: error.config.baseURL,
|
|
81
|
-
url: error.config.url,
|
|
82
|
-
method: error.config.method,
|
|
83
|
-
params: error.config.params,
|
|
84
|
-
data: error.config.data,
|
|
85
|
-
};
|
|
86
|
-
url = (error.config.baseURL || '') + error.config.url;
|
|
87
|
-
}
|
|
88
|
-
if (url) {
|
|
89
|
-
this.message = `${this.message}:${url}`;
|
|
90
|
-
}
|
|
91
|
-
// const { stack, cause } = error;
|
|
92
|
-
delete this.cause;
|
|
93
|
-
delete this.stack;
|
|
94
|
-
// this.cause = cause;
|
|
95
|
-
// this.stack = stack;
|
|
96
|
-
delete error.stack;
|
|
97
|
-
delete error.cause;
|
|
98
|
-
delete error.response;
|
|
99
|
-
delete error.config;
|
|
100
|
-
delete error.request;
|
|
101
|
-
// logger.error(error);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
module.exports = {
|
|
106
|
-
setGlobalProxy,
|
|
107
|
-
createAgent,
|
|
108
|
-
getGlobalAgents,
|
|
109
|
-
HttpError,
|
|
110
|
-
};
|