@blamejs/pki 0.5.27 → 0.5.28
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 +13 -1
- package/lib/guard-identifier.js +10 -6
- package/lib/webcrypto.js +14 -1
- package/package.json +1 -1
- package/sbom.cdx.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -4,7 +4,19 @@ 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.5.
|
|
7
|
+
## v0.5.28 — 2026-08-23
|
|
8
|
+
|
|
9
|
+
Importing the toolkit is now silent, and a key's WebCrypto algorithm can no longer change under a signature once the key has been created.
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- `require("@blamejs/pki")` no longer prints Node experimental-feature warnings on load. The engine's typed-array scan reads each global's property descriptor and uses only a data value, so it never touches a host's lazy accessor (Node's `localStorage` and `WASI` emit an `ExperimentalWarning` the moment they are read). Recognition of the concrete typed-array kinds -- the reason for the scan -- is unchanged, since those are ordinary data properties.
|
|
14
|
+
|
|
15
|
+
### Security
|
|
16
|
+
|
|
17
|
+
- A `CryptoKey`'s `algorithm` is immutable once the key is created: the property is non-writable so it cannot be replaced, and its value is frozen so its fields cannot be changed. This engine reads `key.algorithm.hash` at sign time, and a mutable algorithm let the hash checked against a JWS `alg` (an `RS256` header signs under SHA-256) be rewritten between that check and the signature -- by swapping the whole object or a field of it, including from a microtask during the signing await -- producing a JWS whose signature does not match the algorithm its header advertises. The frozen value is a copy, so a caller's own `importKey` parameters object is left untouched. A key adopted from another WebCrypto implementation is re-imported from its own algorithm; the keys this engine mints, which is what the enrollment builders sign with, carry the immutable one.
|
|
18
|
+
|
|
19
|
+
## v0.5.27 — 2026-08-22
|
|
8
20
|
|
|
9
21
|
A mistyped option passed to pki.trust.anchor or the pki.acme.client constructor is now refused, naming it, instead of being read as absent and silently defaulted.
|
|
10
22
|
|
package/lib/guard-identifier.js
CHANGED
|
@@ -433,13 +433,17 @@ var _INTRINSIC_HOLDERS = (function () {
|
|
|
433
433
|
// built over `%TypedArray%.prototype`, and a bag inheriting `BYTES_PER_ELEMENT` from such an
|
|
434
434
|
// object then read as an intrinsic member rather than as the unknown option it was.
|
|
435
435
|
//
|
|
436
|
-
//
|
|
437
|
-
//
|
|
436
|
+
// Read the DESCRIPTOR, never the value through the runtime. `globalThis[n]` invokes a getter, and a
|
|
437
|
+
// host may define one that warns on read -- Node exposes `localStorage` and `WASI` as lazy accessors
|
|
438
|
+
// that emit an ExperimentalWarning the moment they are touched, so a plain read here printed that
|
|
439
|
+
// warning on every import -- or one that throws. A typed-array constructor is a plain data property, so
|
|
440
|
+
// taking `d.value` finds every concrete kind without ever invoking an accessor, which also means such
|
|
441
|
+
// an accessor can neither warn nor fault this load over a name it does not need.
|
|
438
442
|
_forEach(_getOwnPropertyNames(globalThis), function (n) {
|
|
439
|
-
var
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
if (typeof C
|
|
443
|
+
var d = _getOwnPropertyDescriptor(globalThis, n);
|
|
444
|
+
if (!d || typeof d.value !== "function") return;
|
|
445
|
+
var C = d.value;
|
|
446
|
+
if (typeof C.BYTES_PER_ELEMENT !== "number") return;
|
|
443
447
|
if (!C.prototype || _getPrototypeOf(C.prototype) !== _TYPED_ARRAY_PROTO) return;
|
|
444
448
|
_mapSet(m, C.prototype, _CONCRETE_TYPED_MEMBERS);
|
|
445
449
|
});
|
package/lib/webcrypto.js
CHANGED
|
@@ -254,7 +254,20 @@ var SECRET_KEY_NAMES = { "AES-GCM": true, "AES-CBC": true, "AES-CTR": true, "AES
|
|
|
254
254
|
function CryptoKey(type, extractable, algorithm, usages, handle) {
|
|
255
255
|
this.type = type;
|
|
256
256
|
this.extractable = !!extractable;
|
|
257
|
-
|
|
257
|
+
// The algorithm is immutable both ways. The PROPERTY is defined non-writable and non-configurable so
|
|
258
|
+
// it cannot be REPLACED wholesale (`key.algorithm = { hash: "SHA-512" }`), and its value is a frozen
|
|
259
|
+
// COPY -- a caller's importKey params object is left untouched -- so its fields, the nested `hash` an
|
|
260
|
+
// RSA/HMAC signature reads among them, cannot be MUTATED. This engine reads key.algorithm.hash live
|
|
261
|
+
// when it signs, and a W3C CryptoKey's [[algorithm]] is immutable for exactly this reason: neither
|
|
262
|
+
// swapping the object nor a field of it (e.g. from a microtask during a signing await) can make the
|
|
263
|
+
// hash the signature is computed under differ from the one checked against a header algorithm.
|
|
264
|
+
var frozenAlg = algorithm;
|
|
265
|
+
if (frozenAlg && typeof frozenAlg === "object") {
|
|
266
|
+
frozenAlg = _assign({}, algorithm);
|
|
267
|
+
if (frozenAlg.hash && typeof frozenAlg.hash === "object") frozenAlg.hash = intrinsic.freeze(_assign({}, frozenAlg.hash));
|
|
268
|
+
frozenAlg = intrinsic.freeze(frozenAlg);
|
|
269
|
+
}
|
|
270
|
+
_defineProperty(this, "algorithm", { value: frozenAlg, enumerable: true });
|
|
258
271
|
// The copy is what the key will be asked about for the rest of its life, so the method that makes
|
|
259
272
|
// it is the captured one: a replaced `slice` hands back a list the caller still controls. The
|
|
260
273
|
// list-ness is checked rather than left to the copy to discover -- `Array.prototype.slice` on a
|
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:c0564356-6da6-47da-a75d-a05ee2125d32",
|
|
6
6
|
"version": 1,
|
|
7
7
|
"metadata": {
|
|
8
|
-
"timestamp": "2026-08-
|
|
8
|
+
"timestamp": "2026-08-23T03:34:40.100Z",
|
|
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.5.
|
|
22
|
+
"bom-ref": "@blamejs/pki@0.5.28",
|
|
23
23
|
"type": "application",
|
|
24
24
|
"name": "pki",
|
|
25
|
-
"version": "0.5.
|
|
25
|
+
"version": "0.5.28",
|
|
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.5.
|
|
29
|
+
"purl": "pkg:npm/%40blamejs/pki@0.5.28",
|
|
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.5.
|
|
57
|
+
"ref": "@blamejs/pki@0.5.28",
|
|
58
58
|
"dependsOn": []
|
|
59
59
|
}
|
|
60
60
|
]
|