tr-fetch 0.9.0 → 0.9.1
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/README.md +11 -1
- package/crl.js +6 -2
- package/package.json +1 -1
- package/pkiutils.js +8 -4
package/README.md
CHANGED
|
@@ -308,6 +308,9 @@ CRL retrieval:
|
|
|
308
308
|
- Allows at most five redirects, 16 MiB of decoded response data and ten seconds
|
|
309
309
|
per download including redirects and body reading. Caller cancellation also
|
|
310
310
|
cancels CRL retrieval. At most 32 distribution URIs are tried per certificate.
|
|
311
|
+
- Parses at most 1,000,000 ASN.1 nodes per CRL, enough for several hundred
|
|
312
|
+
thousand revoked entries. This bounds the memory that a hostile CRL can use
|
|
313
|
+
(about 0.6 GB); larger CRLs are invalid.
|
|
311
314
|
- Allows private-network HTTP(S) endpoints, including loopback, for private PKI.
|
|
312
315
|
It does not perform filesystem or LDAP lookup.
|
|
313
316
|
- Does not recursively check the CRL download server's CRLs or OCSP status.
|
|
@@ -388,7 +391,14 @@ checks. Only `http:` and `https:` URLs are supported; a URL without a scheme
|
|
|
388
391
|
defaults to `http://`.
|
|
389
392
|
|
|
390
393
|
```sh
|
|
391
|
-
npx tr-curl -v https://example.com/
|
|
394
|
+
npx -p tr-fetch tr-curl -v https://example.com/
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
The command is in the `tr-fetch` package, so `npx` needs `-p tr-fetch`.
|
|
398
|
+
After `npm install -g tr-fetch`, or inside a project that depends on it,
|
|
399
|
+
`tr-curl` can be run directly:
|
|
400
|
+
|
|
401
|
+
```sh
|
|
392
402
|
tr-curl -fsSL -o page.html https://example.com/
|
|
393
403
|
tr-curl --json '{"a":1}' -u user:password https://api.example.com/items
|
|
394
404
|
tr-curl --cacert private-ca.pem --crlfile current.crl https://internal.example/
|
package/crl.js
CHANGED
|
@@ -5,6 +5,10 @@ const pki = require('pkijs');
|
|
|
5
5
|
const { cryptoEngine, parseDer, extensionsById, extensionValue, parseCertificate } = require('./pkiutils');
|
|
6
6
|
|
|
7
7
|
const MAX_CRL_BYTES = 16 * 1024 * 1024;
|
|
8
|
+
// A revoked entry takes three to seven ASN.1 nodes, so this allows CRLs of
|
|
9
|
+
// several hundred thousand entries. Unlike the byte limit, it also bounds the
|
|
10
|
+
// memory used by hostile input made of minimal nodes (about 0.6 GB).
|
|
11
|
+
const MAX_CRL_NODES = 1000000;
|
|
8
12
|
|
|
9
13
|
function distributionPoints(certificate) {
|
|
10
14
|
const extension = extensionsById(certificate.extensions).get('2.5.29.31');
|
|
@@ -39,7 +43,7 @@ function parseCrl(bytes) {
|
|
|
39
43
|
throw new Error('Malformed base64 in PEM CRL');
|
|
40
44
|
}
|
|
41
45
|
}
|
|
42
|
-
return parseDer(bytes, pki.CertificateRevocationList);
|
|
46
|
+
return parseDer(bytes, pki.CertificateRevocationList, { maxNodes: MAX_CRL_NODES, maxContentLength: MAX_CRL_BYTES });
|
|
43
47
|
}
|
|
44
48
|
|
|
45
49
|
function checkValidity(crl, now = Date.now()) {
|
|
@@ -161,4 +165,4 @@ async function validateCrl(crl, certificate, issuer, urls, now = Date.now()) {
|
|
|
161
165
|
return { revoked, nextUpdate };
|
|
162
166
|
}
|
|
163
167
|
|
|
164
|
-
module.exports = { MAX_CRL_BYTES, parseCertificate, distributionPoints, parseCrl, validateCrl };
|
|
168
|
+
module.exports = { MAX_CRL_BYTES, MAX_CRL_NODES, parseCertificate, distributionPoints, parseCrl, validateCrl };
|
package/package.json
CHANGED
package/pkiutils.js
CHANGED
|
@@ -6,10 +6,14 @@ const { webcrypto } = require('node:crypto');
|
|
|
6
6
|
|
|
7
7
|
const cryptoEngine = new pki.CryptoEngine({ name: 'tr-fetch', crypto: webcrypto });
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
// Limits default to asn1js's own; see its fromBER() resource limits.
|
|
10
|
+
function parseDer(bytes, Type, limits) {
|
|
11
|
+
const decoded = asn1.fromBER(bytes, limits);
|
|
12
|
+
if (decoded.result.error) {
|
|
13
|
+
throw new Error(`Malformed ASN.1 data: ${decoded.result.error}`);
|
|
14
|
+
}
|
|
15
|
+
if (decoded.offset !== bytes.length) {
|
|
16
|
+
throw new Error('Malformed ASN.1 data: trailing bytes');
|
|
13
17
|
}
|
|
14
18
|
return new Type({ schema: decoded.result });
|
|
15
19
|
}
|