@certd/acme-client 0.3.0 → 1.0.0
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 +5 -3
- package/src/auto.js +27 -10
- package/src/crypto/forge.js +14 -22
- package/types/index.d.ts +1 -1
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@certd/acme-client",
|
|
3
3
|
"description": "Simple and unopinionated ACME client",
|
|
4
|
+
"private": false,
|
|
4
5
|
"author": "nmorsman",
|
|
5
|
-
"version": "0.
|
|
6
|
+
"version": "1.0.0",
|
|
6
7
|
"main": "src/index.js",
|
|
7
8
|
"types": "types",
|
|
8
9
|
"license": "MIT",
|
|
@@ -31,7 +32,7 @@
|
|
|
31
32
|
"jsdoc-to-markdown": "^7.1.1",
|
|
32
33
|
"mocha": "^10.0.0",
|
|
33
34
|
"nock": "^13.2.4",
|
|
34
|
-
"typescript": "^4.
|
|
35
|
+
"typescript": "^4.8.4",
|
|
35
36
|
"uuid": "^8.3.2"
|
|
36
37
|
},
|
|
37
38
|
"scripts": {
|
|
@@ -56,5 +57,6 @@
|
|
|
56
57
|
],
|
|
57
58
|
"bugs": {
|
|
58
59
|
"url": "https://github.com/publishlab/node-acme-client/issues"
|
|
59
|
-
}
|
|
60
|
+
},
|
|
61
|
+
"gitHead": "5950e1cae7cf30ebfc5128c15c7d1b0d101cbbb8"
|
|
60
62
|
}
|
package/src/auto.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
const { readCsrDomains } = require('./crypto');
|
|
6
6
|
const { log } = require('./logger');
|
|
7
|
+
|
|
7
8
|
const defaultOpts = {
|
|
8
9
|
csr: null,
|
|
9
10
|
email: null,
|
|
@@ -83,7 +84,7 @@ module.exports = async function(client, userOpts) {
|
|
|
83
84
|
|
|
84
85
|
log('[auto] Resolving and satisfying authorization challenges');
|
|
85
86
|
|
|
86
|
-
const
|
|
87
|
+
const challengeFunc = async (authz) => {
|
|
87
88
|
const d = authz.identifier.value;
|
|
88
89
|
let challengeCompleted = false;
|
|
89
90
|
|
|
@@ -113,9 +114,9 @@ module.exports = async function(client, userOpts) {
|
|
|
113
114
|
/* Trigger challengeCreateFn() */
|
|
114
115
|
log(`[auto] [${d}] Trigger challengeCreateFn()`);
|
|
115
116
|
const keyAuthorization = await client.getChallengeKeyAuthorization(challenge);
|
|
116
|
-
|
|
117
|
+
let recordItem = null;
|
|
117
118
|
try {
|
|
118
|
-
await opts.challengeCreateFn(authz, challenge, keyAuthorization);
|
|
119
|
+
recordItem = await opts.challengeCreateFn(authz, challenge, keyAuthorization);
|
|
119
120
|
|
|
120
121
|
/* Challenge verification */
|
|
121
122
|
if (opts.skipChallengeVerification === true) {
|
|
@@ -133,12 +134,16 @@ module.exports = async function(client, userOpts) {
|
|
|
133
134
|
|
|
134
135
|
await client.waitForValidStatus(challenge);
|
|
135
136
|
}
|
|
137
|
+
catch (e) {
|
|
138
|
+
log(`[auto] [${d}] challengeCreateFn threw error: ${e.message}`);
|
|
139
|
+
throw e;
|
|
140
|
+
}
|
|
136
141
|
finally {
|
|
137
142
|
/* Trigger challengeRemoveFn(), suppress errors */
|
|
138
143
|
log(`[auto] [${d}] Trigger challengeRemoveFn()`);
|
|
139
144
|
|
|
140
145
|
try {
|
|
141
|
-
await opts.challengeRemoveFn(authz, challenge, keyAuthorization);
|
|
146
|
+
await opts.challengeRemoveFn(authz, challenge, keyAuthorization, recordItem);
|
|
142
147
|
}
|
|
143
148
|
catch (e) {
|
|
144
149
|
log(`[auto] [${d}] challengeRemoveFn threw error: ${e.message}`);
|
|
@@ -162,16 +167,28 @@ module.exports = async function(client, userOpts) {
|
|
|
162
167
|
|
|
163
168
|
throw e;
|
|
164
169
|
}
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
const challengePromises = authorizations.map((authz) => async () => {
|
|
173
|
+
await challengeFunc(authz);
|
|
165
174
|
});
|
|
166
175
|
|
|
167
|
-
log('
|
|
176
|
+
log('开始challenge');
|
|
177
|
+
let promise = Promise.resolve();
|
|
178
|
+
function runPromisesSerially(tasks) {
|
|
179
|
+
tasks.forEach((task) => {
|
|
180
|
+
promise = promise.then(task);
|
|
181
|
+
});
|
|
182
|
+
return promise;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
await runPromisesSerially(challengePromises);
|
|
186
|
+
log('challenge结束');
|
|
187
|
+
|
|
188
|
+
// log('[auto] Waiting for challenge valid status');
|
|
168
189
|
// await Promise.all(challengePromises);
|
|
169
190
|
|
|
170
|
-
|
|
171
|
-
for (let challenge of challengePromises) {
|
|
172
|
-
await challenge
|
|
173
|
-
}
|
|
174
|
-
log("challenge结束")
|
|
191
|
+
|
|
175
192
|
/**
|
|
176
193
|
* Finalize order and download certificate
|
|
177
194
|
*/
|
package/src/crypto/forge.js
CHANGED
|
@@ -74,7 +74,8 @@ function parseDomains(obj) {
|
|
|
74
74
|
|
|
75
75
|
if (rootAltNames && rootAltNames.altNames && rootAltNames.altNames.length) {
|
|
76
76
|
altNamesDict = rootAltNames.altNames;
|
|
77
|
-
}
|
|
77
|
+
}
|
|
78
|
+
else if (rootExtensions && rootExtensions.extensions && rootExtensions.extensions.length) {
|
|
78
79
|
const extAltNames = rootExtensions.extensions.find((e) => 'altNames' in e);
|
|
79
80
|
|
|
80
81
|
if (extAltNames && extAltNames.altNames && extAltNames.altNames.length) {
|
|
@@ -115,21 +116,11 @@ function parseDomains(obj) {
|
|
|
115
116
|
*/
|
|
116
117
|
|
|
117
118
|
async function createPrivateKey(size = 2048) {
|
|
118
|
-
const keyPair = await generateKeyPair({bits: size});
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
// convert a Forge private key to an ASN.1 RSAPrivateKey
|
|
122
|
-
var rsaPrivateKey = forge.pki.privateKeyToAsn1(keyPair.privateKey);
|
|
123
|
-
|
|
124
|
-
// wrap an RSAPrivateKey ASN.1 object in a PKCS#8 ASN.1 PrivateKeyInfo
|
|
125
|
-
var privateKeyInfo = forge.pki.wrapRsaPrivateKey(rsaPrivateKey);
|
|
126
|
-
|
|
127
|
-
// convert a PKCS#8 ASN.1 PrivateKeyInfo to PEM
|
|
128
|
-
var pemKey = forge.pki.privateKeyInfoToPem(privateKeyInfo);
|
|
119
|
+
const keyPair = await generateKeyPair({ bits: size });
|
|
120
|
+
const pemKey = forge.pki.privateKeyToPem(keyPair.privateKey);
|
|
129
121
|
return Buffer.from(pemKey);
|
|
130
122
|
}
|
|
131
123
|
|
|
132
|
-
|
|
133
124
|
exports.createPrivateKey = createPrivateKey;
|
|
134
125
|
|
|
135
126
|
|
|
@@ -145,7 +136,7 @@ exports.createPrivateKey = createPrivateKey;
|
|
|
145
136
|
* ```
|
|
146
137
|
*/
|
|
147
138
|
|
|
148
|
-
exports.createPublicKey = async function
|
|
139
|
+
exports.createPublicKey = async function(key) {
|
|
149
140
|
const privateKey = forge.pki.privateKeyFromPem(key);
|
|
150
141
|
const publicKey = forge.pki.rsa.setPublicKey(privateKey.n, privateKey.e);
|
|
151
142
|
const pemKey = forge.pki.publicKeyToPem(publicKey);
|
|
@@ -191,7 +182,7 @@ exports.splitPemChain = (str) => forge.pem.decode(str).map(forge.pem.encode);
|
|
|
191
182
|
* ```
|
|
192
183
|
*/
|
|
193
184
|
|
|
194
|
-
exports.getModulus = async function
|
|
185
|
+
exports.getModulus = async function(input) {
|
|
195
186
|
if (!Buffer.isBuffer(input)) {
|
|
196
187
|
input = Buffer.from(input);
|
|
197
188
|
}
|
|
@@ -215,7 +206,7 @@ exports.getModulus = async function (input) {
|
|
|
215
206
|
* ```
|
|
216
207
|
*/
|
|
217
208
|
|
|
218
|
-
exports.getPublicExponent = async function
|
|
209
|
+
exports.getPublicExponent = async function(input) {
|
|
219
210
|
if (!Buffer.isBuffer(input)) {
|
|
220
211
|
input = Buffer.from(input);
|
|
221
212
|
}
|
|
@@ -240,7 +231,7 @@ exports.getPublicExponent = async function (input) {
|
|
|
240
231
|
* ```
|
|
241
232
|
*/
|
|
242
233
|
|
|
243
|
-
exports.readCsrDomains = async function
|
|
234
|
+
exports.readCsrDomains = async function(csr) {
|
|
244
235
|
if (!Buffer.isBuffer(csr)) {
|
|
245
236
|
csr = Buffer.from(csr);
|
|
246
237
|
}
|
|
@@ -269,7 +260,7 @@ exports.readCsrDomains = async function (csr) {
|
|
|
269
260
|
* ```
|
|
270
261
|
*/
|
|
271
262
|
|
|
272
|
-
exports.readCertificateInfo = async function
|
|
263
|
+
exports.readCertificateInfo = async function(cert) {
|
|
273
264
|
if (!Buffer.isBuffer(cert)) {
|
|
274
265
|
cert = Buffer.from(cert);
|
|
275
266
|
}
|
|
@@ -321,7 +312,7 @@ function createCsrSubject(subjectObj) {
|
|
|
321
312
|
return Object.entries(subjectObj).reduce((result, [shortName, value]) => {
|
|
322
313
|
if (value) {
|
|
323
314
|
const valueTagClass = getCsrValueTagClass(shortName);
|
|
324
|
-
result.push({shortName, value, valueTagClass});
|
|
315
|
+
result.push({ shortName, value, valueTagClass });
|
|
325
316
|
}
|
|
326
317
|
|
|
327
318
|
return result;
|
|
@@ -341,7 +332,7 @@ function createCsrSubject(subjectObj) {
|
|
|
341
332
|
function formatCsrAltNames(altNames) {
|
|
342
333
|
return altNames.map((value) => {
|
|
343
334
|
const type = net.isIP(value) ? 7 : 2;
|
|
344
|
-
return {type, value};
|
|
335
|
+
return { type, value };
|
|
345
336
|
});
|
|
346
337
|
}
|
|
347
338
|
|
|
@@ -400,10 +391,11 @@ function formatCsrAltNames(altNames) {
|
|
|
400
391
|
* }, certificateKey);
|
|
401
392
|
*/
|
|
402
393
|
|
|
403
|
-
exports.createCsr = async function
|
|
394
|
+
exports.createCsr = async function(data, key = null) {
|
|
404
395
|
if (!key) {
|
|
405
396
|
key = await createPrivateKey(data.keySize);
|
|
406
|
-
}
|
|
397
|
+
}
|
|
398
|
+
else if (!Buffer.isBuffer(key)) {
|
|
407
399
|
key = Buffer.from(key);
|
|
408
400
|
}
|
|
409
401
|
|
package/types/index.d.ts
CHANGED
|
@@ -51,7 +51,7 @@ export interface ClientExternalAccountBindingOptions {
|
|
|
51
51
|
export interface ClientAutoOptions {
|
|
52
52
|
csr: CsrBuffer | CsrString;
|
|
53
53
|
challengeCreateFn: (authz: Authorization, challenge: rfc8555.Challenge, keyAuthorization: string) => Promise<any>;
|
|
54
|
-
challengeRemoveFn: (authz: Authorization, challenge: rfc8555.Challenge, keyAuthorization: string) => Promise<any>;
|
|
54
|
+
challengeRemoveFn: (authz: Authorization, challenge: rfc8555.Challenge, keyAuthorization: string, recordRes:any) => Promise<any>;
|
|
55
55
|
email?: string;
|
|
56
56
|
termsOfServiceAgreed?: boolean;
|
|
57
57
|
skipChallengeVerification?: boolean;
|