@certd/acme-client 1.20.2 → 1.20.6

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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2017-2022 Publish Lab
3
+ Copyright (c) 2017-2024 Labrador CMS AS
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,21 +1,13 @@
1
- # acme-client [![CircleCI](https://circleci.com/gh/publishlab/node-acme-client.svg?style=svg)](https://circleci.com/gh/publishlab/node-acme-client)
1
+ # acme-client [![test](https://github.com/publishlab/node-acme-client/actions/workflows/tests.yml/badge.svg)](https://github.com/publishlab/node-acme-client/actions/workflows/tests.yml)
2
2
 
3
3
  *A simple and unopinionated ACME client.*
4
4
 
5
5
  This module is written to handle communication with a Boulder/Let's Encrypt-style ACME API.
6
6
 
7
- * RFC 8555 - Automatic Certificate Management Environment (ACME): [https://tools.ietf.org/html/rfc8555](https://tools.ietf.org/html/rfc8555)
7
+ * RFC 8555 - Automatic Certificate Management Environment (ACME): [https://datatracker.ietf.org/doc/html/rfc8555](https://datatracker.ietf.org/doc/html/rfc8555)
8
8
  * Boulder divergences from ACME: [https://github.com/letsencrypt/boulder/blob/master/docs/acme-divergences.md](https://github.com/letsencrypt/boulder/blob/master/docs/acme-divergences.md)
9
9
 
10
-
11
- ## Important upgrade notice
12
-
13
- 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.
14
-
15
- 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).
16
-
17
-
18
- ### Compatibility
10
+ ## Compatibility
19
11
 
20
12
  | acme-client | Node.js | |
21
13
  | ------------- | --------- | ----------------------------------------- |
@@ -25,8 +17,7 @@ A more detailed explanation can be found [at the Let's Encrypt forums](https://c
25
17
  | v2.x | >= v4 | [Changelog](CHANGELOG.md#v200-2018-04-02) |
26
18
  | v1.x | >= v4 | [Changelog](CHANGELOG.md#v100-2017-10-20) |
27
19
 
28
-
29
- ### Table of contents
20
+ ## Table of contents
30
21
 
31
22
  * [Installation](#installation)
32
23
  * [Usage](#usage)
@@ -43,14 +34,12 @@ A more detailed explanation can be found [at the Let's Encrypt forums](https://c
43
34
  * [Debugging](#debugging)
44
35
  * [License](#license)
45
36
 
46
-
47
37
  ## Installation
48
38
 
49
39
  ```bash
50
40
  $ npm install acme-client
51
41
  ```
52
42
 
53
-
54
43
  ## Usage
55
44
 
56
45
  ```js
@@ -64,7 +53,6 @@ const client = new acme.Client({
64
53
  });
65
54
  ```
66
55
 
67
-
68
56
  ### Directory URLs
69
57
 
70
58
  ```js
@@ -77,10 +65,9 @@ acme.directory.letsencrypt.production;
77
65
  acme.directory.zerossl.production;
78
66
  ```
79
67
 
80
-
81
68
  ### External account binding
82
69
 
83
- To enable [external account binding](https://tools.ietf.org/html/rfc8555#section-7.3.4) when creating your ACME account, provide your KID and HMAC key to the client constructor.
70
+ To enable [external account binding](https://datatracker.ietf.org/doc/html/rfc8555#section-7.3.4) when creating your ACME account, provide your KID and HMAC key to the client constructor.
84
71
 
85
72
  ```js
86
73
  const client = new acme.Client({
@@ -93,7 +80,6 @@ const client = new acme.Client({
93
80
  });
94
81
  ```
95
82
 
96
-
97
83
  ### Specifying the account URL
98
84
 
99
85
  During the ACME account creation process, the server will check the supplied account key and either create a new account if the key is unused, or return the existing ACME account bound to that key.
@@ -114,14 +100,13 @@ You can fetch the clients current account URL, either after creating an account
114
100
  const myAccountUrl = client.getAccountUrl();
115
101
  ```
116
102
 
117
-
118
103
  ## Cryptography
119
104
 
120
- 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.
105
+ For key pairs `acme-client` utilizes native Node.js cryptography APIs, supporting signing and generation of both RSA and ECDSA keys. The module [@peculiar/x509](https://www.npmjs.com/package/@peculiar/x509) is used to generate and parse Certificate Signing Requests.
121
106
 
122
107
  These utility methods are exposed through `.crypto`.
123
108
 
124
- * __Documentation: [docs/crypto.md](docs/crypto.md)__
109
+ * **Documentation: [docs/crypto.md](docs/crypto.md)**
125
110
 
126
111
  ```js
127
112
  const privateRsaKey = await acme.crypto.createPrivateRsaKey();
@@ -133,22 +118,20 @@ const [certificateKey, certificateCsr] = await acme.crypto.createCsr({
133
118
  });
134
119
  ```
135
120
 
136
-
137
121
  ### Legacy `.forge` interface
138
122
 
139
123
  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`.
140
124
 
141
125
  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).
142
126
 
143
- * __Documentation: [docs/forge.md](docs/forge.md)__
144
-
127
+ * **Documentation: [docs/forge.md](docs/forge.md)**
145
128
 
146
129
  ## Auto mode
147
130
 
148
131
  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.
149
132
 
150
- * __Documentation: [docs/client.md#AcmeClient+auto](docs/client.md#AcmeClient+auto)__
151
- * __Full example: [examples/auto.js](examples/auto.js)__
133
+ * **Documentation: [docs/client.md#AcmeClient+auto](docs/client.md#AcmeClient+auto)**
134
+ * **Full example: [examples/auto.js](examples/auto.js)**
152
135
 
153
136
  ```js
154
137
  const autoOpts = {
@@ -162,12 +145,11 @@ const autoOpts = {
162
145
  const certificate = await client.auto(autoOpts);
163
146
  ```
164
147
 
165
-
166
148
  ### Challenge priority
167
149
 
168
150
  When ordering a certificate using auto mode, `acme-client` uses a priority list when selecting challenges to respond to. Its default value is `['http-01', 'dns-01']` which translates to "use `http-01` if any challenges exist, otherwise fall back to `dns-01`".
169
151
 
170
- While most challenges can be validated using the method of your choosing, please note that __wildcard certificates can only be validated through `dns-01`__. More information regarding Let's Encrypt challenge types [can be found here](https://letsencrypt.org/docs/challenge-types/).
152
+ While most challenges can be validated using the method of your choosing, please note that **wildcard certificates can only be validated through `dns-01`**. More information regarding Let's Encrypt challenge types [can be found here](https://letsencrypt.org/docs/challenge-types/).
171
153
 
172
154
  To modify challenge priority, provide a list of challenge types in `challengePriority`:
173
155
 
@@ -178,7 +160,6 @@ await client.auto({
178
160
  });
179
161
  ```
180
162
 
181
-
182
163
  ### Internal challenge verification
183
164
 
184
165
  When using auto mode, `acme-client` will first validate that challenges are satisfied internally before completing the challenge at the ACME provider. In some cases (firewalls, etc) this internal challenge verification might not be possible to complete.
@@ -194,13 +175,12 @@ await client.auto({
194
175
  });
195
176
  ```
196
177
 
197
-
198
178
  ## API
199
179
 
200
180
  For more fine-grained control you can interact with the ACME API using the methods documented below.
201
181
 
202
- * __Documentation: [docs/client.md](docs/client.md)__
203
- * __Full example: [examples/api.js](examples/api.js)__
182
+ * **Documentation: [docs/client.md](docs/client.md)**
183
+ * **Full example: [examples/api.js](examples/api.js)**
204
184
 
205
185
  ```js
206
186
  const account = await client.createAccount({
@@ -216,7 +196,6 @@ const order = await client.createOrder({
216
196
  });
217
197
  ```
218
198
 
219
-
220
199
  ## HTTP client defaults
221
200
 
222
201
  This module uses [axios](https://github.com/axios/axios) when communicating with the ACME HTTP API, and exposes the client instance through `.axios`.
@@ -237,7 +216,6 @@ A complete list of axios options and documentation can be found at:
237
216
  * [https://github.com/axios/axios#request-config](https://github.com/axios/axios#request-config)
238
217
  * [https://github.com/axios/axios#custom-instance-defaults](https://github.com/axios/axios#custom-instance-defaults)
239
218
 
240
-
241
219
  ## Debugging
242
220
 
243
221
  To get a better grasp of what `acme-client` is doing behind the scenes, you can either pass it a logger function, or enable debugging through an environment variable.
@@ -256,7 +234,6 @@ Debugging to the console can also be enabled through [debug](https://www.npmjs.c
256
234
  DEBUG=acme-client node index.js
257
235
  ```
258
236
 
259
-
260
237
  ## License
261
238
 
262
239
  [MIT](LICENSE)
package/package.json CHANGED
@@ -3,9 +3,9 @@
3
3
  "description": "Simple and unopinionated ACME client",
4
4
  "private": false,
5
5
  "author": "nmorsman",
6
- "version": "1.20.2",
6
+ "version": "1.20.6",
7
7
  "main": "src/index.js",
8
- "types": "types",
8
+ "types": "types/index.d.ts",
9
9
  "license": "MIT",
10
10
  "homepage": "https://github.com/publishlab/node-acme-client",
11
11
  "engines": {
@@ -16,32 +16,33 @@
16
16
  "types"
17
17
  ],
18
18
  "dependencies": {
19
- "axios": "0.27.2",
19
+ "@peculiar/x509": "^1.9.7",
20
+ "asn1js": "^3.0.5",
21
+ "axios": "^1.6.5",
20
22
  "debug": "^4.1.1",
21
- "jsrsasign": "^10.5.26",
23
+ "https-proxy-agent": "^7.0.4",
22
24
  "node-forge": "^1.3.1"
23
25
  },
24
26
  "devDependencies": {
25
- "@types/node": "^18.6.1",
26
- "chai": "^4.3.6",
27
+ "@types/node": "^20.11.5",
28
+ "chai": "^4.4.1",
27
29
  "chai-as-promised": "^7.1.1",
28
- "dtslint": "^4.2.1",
29
- "eslint": "^8.11.0",
30
+ "eslint": "^8.56.0",
30
31
  "eslint-config-airbnb-base": "^15.0.0",
31
- "eslint-plugin-import": "^2.25.4",
32
- "jsdoc-to-markdown": "^7.1.1",
33
- "mocha": "^10.0.0",
34
- "nock": "^13.2.4",
32
+ "eslint-plugin-import": "^2.29.1",
33
+ "jsdoc-to-markdown": "^8.0.0",
34
+ "mocha": "^10.2.0",
35
+ "nock": "^13.5.0",
36
+ "tsd": "^0.30.4",
35
37
  "typescript": "^4.8.4",
36
38
  "uuid": "^8.3.2"
37
39
  },
38
40
  "scripts": {
39
41
  "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",
40
42
  "lint": "eslint .",
41
- "lint-types": "dtslint types",
43
+ "lint-types": "tsd",
42
44
  "prepublishOnly": "npm run build-docs",
43
- "test": "mocha -t 60000 \"test/setup.js\" \"test/**/*.spec.js\"",
44
- "test-local": "/bin/bash scripts/run-tests.sh"
45
+ "test": "mocha -t 60000 \"test/setup.js\" \"test/**/*.spec.js\""
45
46
  },
46
47
  "repository": {
47
48
  "type": "git",
@@ -58,5 +59,5 @@
58
59
  "bugs": {
59
60
  "url": "https://github.com/publishlab/node-acme-client/issues"
60
61
  },
61
- "gitHead": "b745712791c1db2432c626fbdce385083eb68386"
62
+ "gitHead": "feb7bfc724636104c1f76621203bab6320c2afe7"
62
63
  }
package/src/api.js CHANGED
@@ -41,7 +41,7 @@ class AcmeApi {
41
41
  * @private
42
42
  * @param {string} url Request URL
43
43
  * @param {object} [payload] Request payload, default: `null`
44
- * @param {array} [validStatusCodes] Array of valid HTTP response status codes, default: `[]`
44
+ * @param {number[]} [validStatusCodes] Array of valid HTTP response status codes, default: `[]`
45
45
  * @param {object} [opts]
46
46
  * @param {boolean} [opts.includeJwsKid] Include KID instead of JWK in JWS header, default: `true`
47
47
  * @param {boolean} [opts.includeExternalAccountBinding] Include EAB in request, default: `false`
@@ -66,7 +66,7 @@ class AcmeApi {
66
66
  * @private
67
67
  * @param {string} resource Request resource name
68
68
  * @param {object} [payload] Request payload, default: `null`
69
- * @param {array} [validStatusCodes] Array of valid HTTP response status codes, default: `[]`
69
+ * @param {number[]} [validStatusCodes] Array of valid HTTP response status codes, default: `[]`
70
70
  * @param {object} [opts]
71
71
  * @param {boolean} [opts.includeJwsKid] Include KID instead of JWK in JWS header, default: `true`
72
72
  * @param {boolean} [opts.includeExternalAccountBinding] Include EAB in request, default: `false`
@@ -82,7 +82,7 @@ class AcmeApi {
82
82
  /**
83
83
  * Get Terms of Service URL if available
84
84
  *
85
- * https://tools.ietf.org/html/rfc8555#section-7.1.1
85
+ * https://datatracker.ietf.org/doc/html/rfc8555#section-7.1.1
86
86
  *
87
87
  * @returns {Promise<string|null>} ToS URL
88
88
  */
@@ -95,7 +95,7 @@ class AcmeApi {
95
95
  /**
96
96
  * Create new account
97
97
  *
98
- * https://tools.ietf.org/html/rfc8555#section-7.3
98
+ * https://datatracker.ietf.org/doc/html/rfc8555#section-7.3
99
99
  *
100
100
  * @param {object} data Request payload
101
101
  * @returns {Promise<object>} HTTP response
@@ -119,7 +119,7 @@ class AcmeApi {
119
119
  /**
120
120
  * Update account
121
121
  *
122
- * https://tools.ietf.org/html/rfc8555#section-7.3.2
122
+ * https://datatracker.ietf.org/doc/html/rfc8555#section-7.3.2
123
123
  *
124
124
  * @param {object} data Request payload
125
125
  * @returns {Promise<object>} HTTP response
@@ -133,7 +133,7 @@ class AcmeApi {
133
133
  /**
134
134
  * Update account key
135
135
  *
136
- * https://tools.ietf.org/html/rfc8555#section-7.3.5
136
+ * https://datatracker.ietf.org/doc/html/rfc8555#section-7.3.5
137
137
  *
138
138
  * @param {object} data Request payload
139
139
  * @returns {Promise<object>} HTTP response
@@ -147,7 +147,7 @@ class AcmeApi {
147
147
  /**
148
148
  * Create new order
149
149
  *
150
- * https://tools.ietf.org/html/rfc8555#section-7.4
150
+ * https://datatracker.ietf.org/doc/html/rfc8555#section-7.4
151
151
  *
152
152
  * @param {object} data Request payload
153
153
  * @returns {Promise<object>} HTTP response
@@ -161,7 +161,7 @@ class AcmeApi {
161
161
  /**
162
162
  * Get order
163
163
  *
164
- * https://tools.ietf.org/html/rfc8555#section-7.4
164
+ * https://datatracker.ietf.org/doc/html/rfc8555#section-7.4
165
165
  *
166
166
  * @param {string} url Order URL
167
167
  * @returns {Promise<object>} HTTP response
@@ -175,7 +175,7 @@ class AcmeApi {
175
175
  /**
176
176
  * Finalize order
177
177
  *
178
- * https://tools.ietf.org/html/rfc8555#section-7.4
178
+ * https://datatracker.ietf.org/doc/html/rfc8555#section-7.4
179
179
  *
180
180
  * @param {string} url Finalization URL
181
181
  * @param {object} data Request payload
@@ -190,7 +190,7 @@ class AcmeApi {
190
190
  /**
191
191
  * Get identifier authorization
192
192
  *
193
- * https://tools.ietf.org/html/rfc8555#section-7.5
193
+ * https://datatracker.ietf.org/doc/html/rfc8555#section-7.5
194
194
  *
195
195
  * @param {string} url Authorization URL
196
196
  * @returns {Promise<object>} HTTP response
@@ -204,7 +204,7 @@ class AcmeApi {
204
204
  /**
205
205
  * Update identifier authorization
206
206
  *
207
- * https://tools.ietf.org/html/rfc8555#section-7.5.2
207
+ * https://datatracker.ietf.org/doc/html/rfc8555#section-7.5.2
208
208
  *
209
209
  * @param {string} url Authorization URL
210
210
  * @param {object} data Request payload
@@ -219,7 +219,7 @@ class AcmeApi {
219
219
  /**
220
220
  * Complete challenge
221
221
  *
222
- * https://tools.ietf.org/html/rfc8555#section-7.5.1
222
+ * https://datatracker.ietf.org/doc/html/rfc8555#section-7.5.1
223
223
  *
224
224
  * @param {string} url Challenge URL
225
225
  * @param {object} data Request payload
@@ -234,7 +234,7 @@ class AcmeApi {
234
234
  /**
235
235
  * Revoke certificate
236
236
  *
237
- * https://tools.ietf.org/html/rfc8555#section-7.6
237
+ * https://datatracker.ietf.org/doc/html/rfc8555#section-7.6
238
238
  *
239
239
  * @param {object} data Request payload
240
240
  * @returns {Promise<object>} HTTP response
package/src/auto.js CHANGED
@@ -84,6 +84,8 @@ module.exports = async function(client, userOpts) {
84
84
 
85
85
  log('[auto] Resolving and satisfying authorization challenges');
86
86
 
87
+ const clearTasks = [];
88
+
87
89
  const challengeFunc = async (authz) => {
88
90
  const d = authz.identifier.value;
89
91
  let challengeCompleted = false;
@@ -139,15 +141,17 @@ module.exports = async function(client, userOpts) {
139
141
  throw e;
140
142
  }
141
143
  finally {
142
- /* Trigger challengeRemoveFn(), suppress errors */
143
- log(`[auto] [${d}] Trigger challengeRemoveFn()`);
144
-
145
- try {
146
- await opts.challengeRemoveFn(authz, challenge, keyAuthorization, recordItem);
147
- }
148
- catch (e) {
149
- log(`[auto] [${d}] challengeRemoveFn threw error: ${e.message}`);
150
- }
144
+ log(`[auto] [${d}] add challengeRemoveFn()`);
145
+ clearTasks.push(async () => {
146
+ /* Trigger challengeRemoveFn(), suppress errors */
147
+ log(`[auto] [${d}] Trigger challengeRemoveFn()`);
148
+ try {
149
+ await opts.challengeRemoveFn(authz, challenge, keyAuthorization, recordItem);
150
+ }
151
+ catch (e) {
152
+ log(`[auto] [${d}] challengeRemoveFn threw error: ${e.message}`);
153
+ }
154
+ });
151
155
  }
152
156
  }
153
157
  catch (e) {
@@ -182,7 +186,23 @@ module.exports = async function(client, userOpts) {
182
186
  return promise;
183
187
  }
184
188
 
185
- await runPromisesSerially(challengePromises);
189
+
190
+ try {
191
+ await runPromisesSerially(challengePromises);
192
+ }
193
+ finally {
194
+ await runPromisesSerially(clearTasks);
195
+ }
196
+
197
+ // try {
198
+ // await Promise.allSettled(challengePromises);
199
+ // }
200
+ // finally {
201
+ // log('清理challenge');
202
+ // await Promise.allSettled(clearTasks);
203
+ // }
204
+
205
+
186
206
  log('challenge结束');
187
207
 
188
208
  // log('[auto] Waiting for challenge valid status');
package/src/axios.js CHANGED
@@ -3,7 +3,6 @@
3
3
  */
4
4
 
5
5
  const axios = require('axios');
6
- const adapter = require('axios/lib/adapters/http');
7
6
  const pkg = require('./../package.json');
8
7
 
9
8
 
@@ -19,10 +18,14 @@ instance.defaults.headers.common['User-Agent'] = `node-${pkg.name}/${pkg.version
19
18
  /* Default ACME settings */
20
19
  instance.defaults.acmeSettings = {
21
20
  httpChallengePort: 80,
22
- bypassCustomDnsResolver: false
21
+ httpsChallengePort: 443,
22
+ tlsAlpnChallengePort: 443
23
23
  };
24
24
 
25
-
25
+ // instance.defaults.proxy = {
26
+ // host: '192.168.34.139',
27
+ // port: 10811
28
+ // };
26
29
  /**
27
30
  * Explicitly set Node as default HTTP adapter
28
31
  *
@@ -30,7 +33,7 @@ instance.defaults.acmeSettings = {
30
33
  * https://stackoverflow.com/questions/42677387
31
34
  */
32
35
 
33
- instance.defaults.adapter = adapter;
36
+ instance.defaults.adapter = 'http';
34
37
 
35
38
 
36
39
  /**
package/src/client.js CHANGED
@@ -154,7 +154,7 @@ class AcmeClient {
154
154
  /**
155
155
  * Create a new account
156
156
  *
157
- * https://tools.ietf.org/html/rfc8555#section-7.3
157
+ * https://datatracker.ietf.org/doc/html/rfc8555#section-7.3
158
158
  *
159
159
  * @param {object} [data] Request data
160
160
  * @returns {Promise<object>} Account
@@ -200,7 +200,7 @@ class AcmeClient {
200
200
  /**
201
201
  * Update existing account
202
202
  *
203
- * https://tools.ietf.org/html/rfc8555#section-7.3.2
203
+ * https://datatracker.ietf.org/doc/html/rfc8555#section-7.3.2
204
204
  *
205
205
  * @param {object} [data] Request data
206
206
  * @returns {Promise<object>} Account
@@ -240,7 +240,7 @@ class AcmeClient {
240
240
  /**
241
241
  * Update account private key
242
242
  *
243
- * https://tools.ietf.org/html/rfc8555#section-7.3.5
243
+ * https://datatracker.ietf.org/doc/html/rfc8555#section-7.3.5
244
244
  *
245
245
  * @param {buffer|string} newAccountKey New PEM encoded private key
246
246
  * @param {object} [data] Additional request data
@@ -286,7 +286,7 @@ class AcmeClient {
286
286
  /**
287
287
  * Create a new order
288
288
  *
289
- * https://tools.ietf.org/html/rfc8555#section-7.4
289
+ * https://datatracker.ietf.org/doc/html/rfc8555#section-7.4
290
290
  *
291
291
  * @param {object} data Request data
292
292
  * @returns {Promise<object>} Order
@@ -318,7 +318,7 @@ class AcmeClient {
318
318
  /**
319
319
  * Refresh order object from CA
320
320
  *
321
- * https://tools.ietf.org/html/rfc8555#section-7.4
321
+ * https://datatracker.ietf.org/doc/html/rfc8555#section-7.4
322
322
  *
323
323
  * @param {object} order Order object
324
324
  * @returns {Promise<object>} Order
@@ -345,7 +345,7 @@ class AcmeClient {
345
345
  /**
346
346
  * Finalize order
347
347
  *
348
- * https://tools.ietf.org/html/rfc8555#section-7.4
348
+ * https://datatracker.ietf.org/doc/html/rfc8555#section-7.4
349
349
  *
350
350
  * @param {object} order Order object
351
351
  * @param {buffer|string} csr PEM encoded Certificate Signing Request
@@ -380,7 +380,7 @@ class AcmeClient {
380
380
  /**
381
381
  * Get identifier authorizations from order
382
382
  *
383
- * https://tools.ietf.org/html/rfc8555#section-7.5
383
+ * https://datatracker.ietf.org/doc/html/rfc8555#section-7.5
384
384
  *
385
385
  * @param {object} order Order
386
386
  * @returns {Promise<object[]>} Authorizations
@@ -410,7 +410,7 @@ class AcmeClient {
410
410
  /**
411
411
  * Deactivate identifier authorization
412
412
  *
413
- * https://tools.ietf.org/html/rfc8555#section-7.5.2
413
+ * https://datatracker.ietf.org/doc/html/rfc8555#section-7.5.2
414
414
  *
415
415
  * @param {object} authz Identifier authorization
416
416
  * @returns {Promise<object>} Authorization
@@ -442,7 +442,7 @@ class AcmeClient {
442
442
  /**
443
443
  * Get key authorization for ACME challenge
444
444
  *
445
- * https://tools.ietf.org/html/rfc8555#section-8.1
445
+ * https://datatracker.ietf.org/doc/html/rfc8555#section-8.1
446
446
  *
447
447
  * @param {object} challenge Challenge object returned by API
448
448
  * @returns {Promise<string>} Key authorization
@@ -462,22 +462,19 @@ class AcmeClient {
462
462
  const thumbprint = keysum.digest('base64url');
463
463
  const result = `${challenge.token}.${thumbprint}`;
464
464
 
465
- /**
466
- * https://tools.ietf.org/html/rfc8555#section-8.3
467
- */
468
-
465
+ /* https://datatracker.ietf.org/doc/html/rfc8555#section-8.3 */
469
466
  if (challenge.type === 'http-01') {
470
467
  return result;
471
468
  }
472
469
 
473
- /**
474
- * https://tools.ietf.org/html/rfc8555#section-8.4
475
- * https://tools.ietf.org/html/draft-ietf-acme-tls-alpn-01
476
- */
470
+ /* https://datatracker.ietf.org/doc/html/rfc8555#section-8.4 */
471
+ if (challenge.type === 'dns-01') {
472
+ return createHash('sha256').update(result).digest('base64url');
473
+ }
477
474
 
478
- if ((challenge.type === 'dns-01') || (challenge.type === 'tls-alpn-01')) {
479
- const shasum = createHash('sha256').update(result);
480
- return shasum.digest('base64url');
475
+ /* https://datatracker.ietf.org/doc/html/rfc8737 */
476
+ if (challenge.type === 'tls-alpn-01') {
477
+ return result;
481
478
  }
482
479
 
483
480
  throw new Error(`Unable to produce key authorization, unknown challenge type: ${challenge.type}`);
@@ -522,7 +519,7 @@ class AcmeClient {
522
519
  /**
523
520
  * Notify CA that challenge has been completed
524
521
  *
525
- * https://tools.ietf.org/html/rfc8555#section-7.5.1
522
+ * https://datatracker.ietf.org/doc/html/rfc8555#section-7.5.1
526
523
  *
527
524
  * @param {object} challenge Challenge object returned by API
528
525
  * @returns {Promise<object>} Challenge
@@ -543,7 +540,7 @@ class AcmeClient {
543
540
  /**
544
541
  * Wait for ACME provider to verify status on a order, authorization or challenge
545
542
  *
546
- * https://tools.ietf.org/html/rfc8555#section-7.5.1
543
+ * https://datatracker.ietf.org/doc/html/rfc8555#section-7.5.1
547
544
  *
548
545
  * @param {object} item An order, authorization or challenge object
549
546
  * @returns {Promise<object>} Valid order, authorization or challenge
@@ -554,7 +551,7 @@ class AcmeClient {
554
551
  * await client.waitForValidStatus(challenge);
555
552
  * ```
556
553
  *
557
- * @example Wait for valid authoriation status
554
+ * @example Wait for valid authorization status
558
555
  * ```js
559
556
  * const authz = { ... };
560
557
  * await client.waitForValidStatus(authz);
@@ -600,7 +597,7 @@ class AcmeClient {
600
597
  /**
601
598
  * Get certificate from ACME order
602
599
  *
603
- * https://tools.ietf.org/html/rfc8555#section-7.4.2
600
+ * https://datatracker.ietf.org/doc/html/rfc8555#section-7.4.2
604
601
  *
605
602
  * @param {object} order Order object
606
603
  * @param {string} [preferredChain] Indicate which certificate chain is preferred if a CA offers multiple, by exact issuer common name, default: `null`
@@ -647,7 +644,7 @@ class AcmeClient {
647
644
  /**
648
645
  * Revoke certificate
649
646
  *
650
- * https://tools.ietf.org/html/rfc8555#section-7.6
647
+ * https://datatracker.ietf.org/doc/html/rfc8555#section-7.6
651
648
  *
652
649
  * @param {buffer|string} cert PEM encoded certificate
653
650
  * @param {object} [data] Additional request data
@@ -281,7 +281,7 @@ exports.readCertificateInfo = async function(cert) {
281
281
 
282
282
  /**
283
283
  * Determine ASN.1 type for CSR subject short name
284
- * Note: https://tools.ietf.org/html/rfc5280
284
+ * Note: https://datatracker.ietf.org/doc/html/rfc5280
285
285
  *
286
286
  * @private
287
287
  * @param {string} shortName CSR subject short name
@@ -343,7 +343,7 @@ function formatCsrAltNames(altNames) {
343
343
  * @param {object} data
344
344
  * @param {number} [data.keySize] Size of newly created private key, default: `2048`
345
345
  * @param {string} [data.commonName]
346
- * @param {array} [data.altNames] default: `[]`
346
+ * @param {string[]} [data.altNames] default: `[]`
347
347
  * @param {string} [data.country]
348
348
  * @param {string} [data.state]
349
349
  * @param {string} [data.locality]