@blamejs/pki 0.8.28 → 0.8.31
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 +60 -0
- package/README.md +1 -1
- package/lib/constants.js +2 -0
- package/lib/inspect.js +1575 -10
- package/lib/ocsp.js +10 -3
- package/lib/schema-pkix.js +39 -2
- package/package.json +1 -1
- package/sbom.cdx.json +6 -6
package/lib/ocsp.js
CHANGED
|
@@ -197,9 +197,16 @@ function _buildRequest(query, opts) {
|
|
|
197
197
|
var issuer = _certOf(q.issuer, "the issuer certificate");
|
|
198
198
|
return _buildCertID(cert, issuer, hashName).then(function (certID) {
|
|
199
199
|
var reqChildren = [certID];
|
|
200
|
-
if (q.singleRequestExtensions
|
|
201
|
-
|
|
202
|
-
|
|
200
|
+
if (q.singleRequestExtensions != null) {
|
|
201
|
+
/** @internal Read through the same door the sibling lists in this module use, so a value that is
|
|
202
|
+
* not an array is refused rather than passed over: read as truthy-and-has-length, an object or a
|
|
203
|
+
* number produced a Request carrying none of the extensions the caller asked for, and nothing in
|
|
204
|
+
* the result said so. */
|
|
205
|
+
var singles = pkiBuild.reqDenseArray(q.singleRequestExtensions, "singleRequestExtensions", _err, "ocsp/bad-input");
|
|
206
|
+
if (singles.length) {
|
|
207
|
+
if (lightweight) throw _err("ocsp/bad-input", "the lightweight profile permits no singleRequestExtensions (RFC 5019 sec. 2.1.1)");
|
|
208
|
+
reqChildren.push(b.explicit(0, b.sequence(singles)));
|
|
209
|
+
}
|
|
203
210
|
}
|
|
204
211
|
return b.sequence(reqChildren);
|
|
205
212
|
});
|
package/lib/schema-pkix.js
CHANGED
|
@@ -479,11 +479,44 @@ function coerceToDer(input, opts) {
|
|
|
479
479
|
* would otherwise be read end to end on the way to being refused for its size. */
|
|
480
480
|
guard.limits.byteCap(buf, _COERCE_MAX_BYTES, function (c, m) { return new opts.ErrorClass(c, m); },
|
|
481
481
|
opts.prefix + "/too-large", "parse input");
|
|
482
|
-
|
|
482
|
+
if (!_isPemArmor(buf)) return buf;
|
|
483
|
+
/** @internal A DER header short enough for the short form can be entirely text bytes, so the
|
|
484
|
+
* probe alone cannot separate armor from a DER value carrying an armor line in its content: an
|
|
485
|
+
* APPLICATION 3 primitive is identifier 0x43 and any content length from 32 to 126 is a
|
|
486
|
+
* printable length octet. Bytes that do not decode as one complete DER value are armor, which is
|
|
487
|
+
* the resolution `pki convert` takes and keeps every PEM file a caller reads into a Buffer on the
|
|
488
|
+
* PEM path. The decode runs only where the probe already said armor, so DER input reaches its
|
|
489
|
+
* parser without it. */
|
|
490
|
+
if (!_isCompleteDer(buf)) return pemDecode(buf, opts.pemLabel, opts.PemError);
|
|
491
|
+
/** @internal A primitive tag makes any content valid, so bytes can satisfy both readings at once
|
|
492
|
+
* and no rule chooses between them: a caller handed the wrong one would be handed the other
|
|
493
|
+
* reading's bytes, silently. The argument is what is ambiguous, not the file, so the message
|
|
494
|
+
* names the two unambiguous ways to say which was meant. */
|
|
495
|
+
if (_isPemBlock(buf, opts)) {
|
|
496
|
+
throw new opts.ErrorClass(opts.prefix + "/bad-input",
|
|
497
|
+
"parse input is both one complete DER value and a well-formed PEM block, so which was meant " +
|
|
498
|
+
"cannot be read from the bytes: pass PEM as a string, or pass the DER value on its own");
|
|
499
|
+
}
|
|
500
|
+
return buf;
|
|
483
501
|
}
|
|
484
502
|
throw new opts.ErrorClass(opts.prefix + "/bad-input", "parse expects a DER BufferSource (Buffer, typed array, DataView, or ArrayBuffer) or a PEM string");
|
|
485
503
|
}
|
|
486
504
|
|
|
505
|
+
/** @internal Whether a buffer also holds a well-formed PEM block, asked only to detect that both
|
|
506
|
+
* readings hold. The decoded bytes are discarded: the caller refuses rather than choosing one. */
|
|
507
|
+
function _isPemBlock(buf, opts) {
|
|
508
|
+
try { pemDecode(buf, opts.pemLabel, opts.PemError); return true; }
|
|
509
|
+
catch (_e) { return false; }
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
/** @internal Whether a buffer is exactly one complete DER value. Trailing bytes disqualify it, so a
|
|
513
|
+
* PEM file whose leading text happened to decode cannot be taken for DER on that prefix alone. */
|
|
514
|
+
function _isCompleteDer(buf) {
|
|
515
|
+
// allow:bare-decode classifies bytes AT the door, before a parse context exists to carry caps; the buffer is byte-capped above and the decode holds the codec's own caps.
|
|
516
|
+
try { asn1.decode(buf); return true; }
|
|
517
|
+
catch (_e) { return false; }
|
|
518
|
+
}
|
|
519
|
+
|
|
487
520
|
/** @internal Whether a buffer is armored text rather than DER. Read from a fixed window at the
|
|
488
521
|
* front, the answer is wrong for a file whose explanatory text is longer than the window, and the
|
|
489
522
|
* caller then hands PEM to the DER decoder and reports the DER as malformed. So the whole buffer is
|
|
@@ -493,7 +526,11 @@ function _isPemArmor(buf) {
|
|
|
493
526
|
var n = buf.length;
|
|
494
527
|
for (var i = 0; i < n; i++) {
|
|
495
528
|
var c = buf[i];
|
|
496
|
-
|
|
529
|
+
/** @internal ASCII whitespace has six members and a text file carries all six, so the walk
|
|
530
|
+
* passes tab, line feed, vertical tab, form feed, carriage return and space, plus the printable
|
|
531
|
+
* range and the byte-order mark. Every other byte ends the walk: a boundary behind one means the
|
|
532
|
+
* buffer is not text, and DER is binary. A PEM file that does carry one is passed as a string. */
|
|
533
|
+
var textByte = (c >= 0x20 && c < 0x7f) || (c >= 0x09 && c <= 0x0d) ||
|
|
497
534
|
c === 0xef || c === 0xbb || c === 0xbf;
|
|
498
535
|
if (!textByte) return false;
|
|
499
536
|
if (c === 0x2d && _bufToString(_subarray(buf, i, i + 10), "latin1") === "-----BEGIN") return true;
|
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:ea5fc812-c57e-4508-9ef7-3dc7126381e6",
|
|
6
6
|
"version": 1,
|
|
7
7
|
"metadata": {
|
|
8
|
-
"timestamp": "2026-09-
|
|
8
|
+
"timestamp": "2026-09-29T06:11:34.254Z",
|
|
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.8.
|
|
22
|
+
"bom-ref": "@blamejs/pki@0.8.31",
|
|
23
23
|
"type": "application",
|
|
24
24
|
"name": "pki",
|
|
25
|
-
"version": "0.8.
|
|
25
|
+
"version": "0.8.31",
|
|
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.8.
|
|
29
|
+
"purl": "pkg:npm/%40blamejs/pki@0.8.31",
|
|
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.8.
|
|
57
|
+
"ref": "@blamejs/pki@0.8.31",
|
|
58
58
|
"dependsOn": []
|
|
59
59
|
}
|
|
60
60
|
]
|