@blamejs/pki 0.7.7 → 0.7.8
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/CHANGELOG.md +10 -0
- package/lib/crl-sign.js +22 -0
- package/package.json +1 -1
- package/sbom.cdx.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,16 @@ All notable changes to `@blamejs/pki` are documented here. The format
|
|
|
4
4
|
follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this
|
|
5
5
|
project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## v0.7.8 — 2026-09-10
|
|
8
|
+
|
|
9
|
+
A pre-encoded CRL extension whose value does not decode is refused instead of signed.
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- A pre-encoded extension supplied to pki.crl.sign is put through the extension decoder registered for its identifier, and a value that does not decode is refused with the decoder's own typed code, the same one pki.x509.sign raises for the same bytes. An issuerAltName whose value is a NULL now raises crl/bad-extension-value and a keyUsage whose value is a NULL raises crl/bad-key-usage, where both were previously signed. Revoked-entry extensions take the same check.
|
|
14
|
+
- The check runs after the per-extension profile rules this verb already applied, so a CRL whose only fault is one malformed extension keeps the code it has always raised: a pre-encoded cRLNumber that is not an INTEGER stays crl/bad-crl-number, and the criticality, delta-ordering and issuingDistributionPoint rules are unchanged. No CRL that was accepted before is refused for a different reason; the extensions newly refused are ones nothing was reading, and an extension with no registered decoder is unaffected.
|
|
15
|
+
- Where a CRL carries more than one fault, the reported code can differ from earlier releases. The rules that compare extensions to each other, such as freshestCRL not appearing in a delta CRL and a delta's cRLNumber exceeding its baseCRLNumber, run once every extension has been read, so a malformed value found first is now reported first. Such a CRL was refused before and is refused now; only which of its faults is named has changed. A caller matching on a specific code for a CRL with several faults should re-check the code it expects.
|
|
16
|
+
|
|
7
17
|
## v0.7.7 — 2026-09-10
|
|
8
18
|
|
|
9
19
|
The two GeneralName arms that were taken on their tag alone are now read.
|
package/lib/crl-sign.js
CHANGED
|
@@ -44,6 +44,9 @@ function _err(code, message, cause) { return new CrlError(code, message, cause);
|
|
|
44
44
|
function _signE(kind, message, cause) { return new CrlError("crl/" + kind, message, cause); }
|
|
45
45
|
function O(n) { return oid.byName(n); }
|
|
46
46
|
|
|
47
|
+
/** @internal The builder is handed no decoder map: this module does not use the builder's
|
|
48
|
+
* extension-building path, it walks the pre-encoded array itself below and validates each value
|
|
49
|
+
* against this map there. */
|
|
47
50
|
var _b = pkiBuild.makeBuilder({ ErrorClass: CrlError, prefix: "crl", O: O, NS: NS, NAME_SCHEMA: NAME_SCHEMA, SPKI_SCHEMA: SPKI_SCHEMA, EXT_DECODERS: {} });
|
|
48
51
|
var _encodeName = _b.encodeName, _isEmptyName = _b.isEmptyName, _reqDer = _b.reqDer,
|
|
49
52
|
_assertValidSpki = _b.assertValidSpki, _assertValidExtension = _b.assertValidExtension,
|
|
@@ -52,6 +55,23 @@ var _encodeName = _b.encodeName, _isEmptyName = _b.isEmptyName, _reqDer = _b.req
|
|
|
52
55
|
_certLikeFromSpki = _b.certLikeFromSpki, _assertSignatureVerifies = _b.assertSignatureVerifies;
|
|
53
56
|
var EXT_DECODERS = pkix.certExtensionDecoders(NS).byOid;
|
|
54
57
|
|
|
58
|
+
/** @internal A pre-encoded extension is admitted on the shape of its Extension SEQUENCE, which says
|
|
59
|
+
* nothing about whether extnValue decodes as the structure its extnID names. Where a decoder is
|
|
60
|
+
* registered for that OID, the value is put through it, so a value that cannot be read is refused
|
|
61
|
+
* here rather than signed and left for a relying party to find. The decoder's own typed code is
|
|
62
|
+
* kept, since it names the field that failed. Called AFTER this module's own profile checks, so an
|
|
63
|
+
* extension it already answers for keeps the code it has always raised and this only reaches the
|
|
64
|
+
* ones nothing was checking. */
|
|
65
|
+
function _assertExtensionValueDecodes(node, extnId, what) {
|
|
66
|
+
var dec = EXT_DECODERS[extnId];
|
|
67
|
+
if (!dec) return;
|
|
68
|
+
try { dec(asn1.read.octetString(node.children[node.children.length - 1])); }
|
|
69
|
+
catch (err) {
|
|
70
|
+
if (err instanceof CrlError) throw err;
|
|
71
|
+
throw _err("crl/bad-input", "pre-encoded " + what + " " + (oid.name(extnId) || extnId) + " value is malformed", err);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
55
75
|
var OID_SKI = O("subjectKeyIdentifier");
|
|
56
76
|
|
|
57
77
|
var CRL_REASON = constants.NAMES.CRL_REASON;
|
|
@@ -221,6 +241,7 @@ function _buildCrlExtensions(spec, ctx) {
|
|
|
221
241
|
if (extnId === O("issuingDistributionPoint")) _validatePreEncodedIdp(inner);
|
|
222
242
|
}
|
|
223
243
|
}
|
|
244
|
+
_assertExtensionValueDecodes(node, extnId, "extension");
|
|
224
245
|
if (extnId === O("deltaCRLIndicator")) isDelta = true;
|
|
225
246
|
out.push(b.raw(der));
|
|
226
247
|
});
|
|
@@ -307,6 +328,7 @@ function _buildRevoked(entryList, isDelta) {
|
|
|
307
328
|
try { asn1.read.time(einner); } catch (e) { throw _err("crl/bad-input", "pre-encoded invalidityDate is not a well-formed GeneralizedTime (RFC 5280 sec. 5.3.2)", e); }
|
|
308
329
|
}
|
|
309
330
|
}
|
|
331
|
+
_assertExtensionValueDecodes(xnode, extnId, "entry extension");
|
|
310
332
|
entryExts.push(b.raw(der));
|
|
311
333
|
});
|
|
312
334
|
}
|
package/package.json
CHANGED
package/sbom.cdx.json
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
"$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json",
|
|
3
3
|
"bomFormat": "CycloneDX",
|
|
4
4
|
"specVersion": "1.5",
|
|
5
|
-
"serialNumber": "urn:uuid:
|
|
5
|
+
"serialNumber": "urn:uuid:eb6258f5-7cf4-4371-80b7-ed98047003ac",
|
|
6
6
|
"version": 1,
|
|
7
7
|
"metadata": {
|
|
8
|
-
"timestamp": "2026-09-10T13:
|
|
8
|
+
"timestamp": "2026-09-10T13:51:21.922Z",
|
|
9
9
|
"lifecycles": [
|
|
10
10
|
{
|
|
11
11
|
"phase": "build"
|
|
@@ -19,14 +19,14 @@
|
|
|
19
19
|
}
|
|
20
20
|
],
|
|
21
21
|
"component": {
|
|
22
|
-
"bom-ref": "@blamejs/pki@0.7.
|
|
22
|
+
"bom-ref": "@blamejs/pki@0.7.8",
|
|
23
23
|
"type": "application",
|
|
24
24
|
"name": "pki",
|
|
25
|
-
"version": "0.7.
|
|
25
|
+
"version": "0.7.8",
|
|
26
26
|
"scope": "required",
|
|
27
27
|
"author": "blamejs contributors",
|
|
28
28
|
"description": "Pure-JavaScript PKI toolkit that owns its stack — X.509, ASN.1/DER, CMS, PQC-first.",
|
|
29
|
-
"purl": "pkg:npm/%40blamejs/pki@0.7.
|
|
29
|
+
"purl": "pkg:npm/%40blamejs/pki@0.7.8",
|
|
30
30
|
"properties": [],
|
|
31
31
|
"externalReferences": [
|
|
32
32
|
{
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"components": [],
|
|
55
55
|
"dependencies": [
|
|
56
56
|
{
|
|
57
|
-
"ref": "@blamejs/pki@0.7.
|
|
57
|
+
"ref": "@blamejs/pki@0.7.8",
|
|
58
58
|
"dependsOn": []
|
|
59
59
|
}
|
|
60
60
|
]
|