@blamejs/pki 0.1.3 → 0.1.5
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 +22 -0
- package/lib/asn1-der.js +48 -37
- package/package.json +1 -1
- package/sbom.cdx.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,28 @@ 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.1.5 — 2026-07-04
|
|
8
|
+
|
|
9
|
+
Container healthcheck honors WIKI_PORT; release-tooling supply-chain hardening.
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- The example wiki container's HEALTHCHECK now probes the port from WIKI_PORT (defaulting to 3009) rather than a hardcoded 3009, so overriding WIKI_PORT at runtime no longer leaves the container reporting unhealthy while the server is serving on the configured port.
|
|
14
|
+
|
|
15
|
+
### Security
|
|
16
|
+
|
|
17
|
+
- The CI secret-scan gate now fetches the gitleaks binary over authenticated requests and verifies it against the checksums file published in the same release before executing it, so a corrupted or tampered download fails closed instead of running as the gate. Tracking the latest release keeps detection rules current.
|
|
18
|
+
- The release-container workflow validates that the base image resolved to a well-formed sha256 digest before building against it, so a failed resolution can no longer silently produce an unpinned base — the scanned image is always the published one.
|
|
19
|
+
- The workflow-security audit re-runs when its own configuration file changes, so an edit that would suppress a finding is itself audited.
|
|
20
|
+
|
|
21
|
+
## v0.1.4 — 2026-07-04
|
|
22
|
+
|
|
23
|
+
The ASN.1 codec's universal-type metadata moves to a single descriptor registry.
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
|
|
27
|
+
- The ASN.1/DER codec's universal-type metadata is now defined once in a descriptor registry (each entry carries the type's tag and its required DER encoding form). pki.asn1.TAGS, the primitive-only set (a type DER requires primitive, encoded constructed, is rejected) and the constructed-only set (a SEQUENCE/SET encoded primitive is rejected) are all derived from it, so registering a universal type is a single data entry. This is an internal refactor: the public surface and every decode/encode result are unchanged, and it lays the groundwork for schema-driven format parsers.
|
|
28
|
+
|
|
7
29
|
## v0.1.3 — 2026-07-04
|
|
8
30
|
|
|
9
31
|
WebCrypto EC key import validates the curve against the key material.
|
package/lib/asn1-der.js
CHANGED
|
@@ -38,46 +38,56 @@ var OidError = frameworkError.OidError;
|
|
|
38
38
|
|
|
39
39
|
// ---- Tag constants (universal class) --------------------------------
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
41
|
+
// L1 — the ASN.1 universal-type descriptor registry: the single source of
|
|
42
|
+
// truth for the codec's type metadata. Each entry is DECLARATIVE DATA —
|
|
43
|
+
// { tag, form } where form is the DER encoding form ("primitive" or
|
|
44
|
+
// "constructed", X.690 §8/§10.2). TAGS and the two structural type-sets below
|
|
45
|
+
// are all DERIVED from it, so registering a universal type is one descriptor
|
|
46
|
+
// entry and the decoder's form checks (below) cover it automatically.
|
|
47
|
+
var UNIVERSAL_TYPES = {
|
|
48
|
+
BOOLEAN: { tag: 0x01, form: "primitive" },
|
|
49
|
+
INTEGER: { tag: 0x02, form: "primitive" },
|
|
50
|
+
BIT_STRING: { tag: 0x03, form: "primitive" },
|
|
51
|
+
OCTET_STRING: { tag: 0x04, form: "primitive" },
|
|
52
|
+
NULL: { tag: 0x05, form: "primitive" },
|
|
53
|
+
OBJECT_IDENTIFIER: { tag: 0x06, form: "primitive" },
|
|
54
|
+
ENUMERATED: { tag: 0x0a, form: "primitive" },
|
|
55
|
+
UTF8_STRING: { tag: 0x0c, form: "primitive" },
|
|
56
|
+
SEQUENCE: { tag: 0x10, form: "constructed" },
|
|
57
|
+
SET: { tag: 0x11, form: "constructed" },
|
|
58
|
+
PRINTABLE_STRING: { tag: 0x13, form: "primitive" },
|
|
59
|
+
TELETEX_STRING: { tag: 0x14, form: "primitive" },
|
|
60
|
+
IA5_STRING: { tag: 0x16, form: "primitive" },
|
|
61
|
+
UTC_TIME: { tag: 0x17, form: "primitive" },
|
|
62
|
+
GENERALIZED_TIME: { tag: 0x18, form: "primitive" },
|
|
63
|
+
VISIBLE_STRING: { tag: 0x1a, form: "primitive" },
|
|
64
|
+
UNIVERSAL_STRING: { tag: 0x1c, form: "primitive" },
|
|
65
|
+
BMP_STRING: { tag: 0x1e, form: "primitive" },
|
|
60
66
|
};
|
|
61
67
|
|
|
68
|
+
// TAGS { name: tag } — derived from the registry; the public constant consumers
|
|
69
|
+
// read (pki.asn1.TAGS.INTEGER, ...).
|
|
70
|
+
var TAGS = {};
|
|
71
|
+
Object.keys(UNIVERSAL_TYPES).forEach(function (k) { TAGS[k] = UNIVERSAL_TYPES[k].tag; });
|
|
72
|
+
|
|
62
73
|
var CLASS_UNIVERSAL = 0x00;
|
|
63
74
|
var CLASS_APPLICATION = 0x40;
|
|
64
75
|
var CLASS_CONTEXT = 0x80;
|
|
65
76
|
var CLASS_PRIVATE = 0xc0;
|
|
66
77
|
var CONSTRUCTED_BIT = 0x20;
|
|
67
78
|
|
|
68
|
-
// X.690 §8.
|
|
69
|
-
//
|
|
70
|
-
//
|
|
71
|
-
//
|
|
72
|
-
//
|
|
73
|
-
//
|
|
74
|
-
var PRIMITIVE_ONLY_UNIVERSAL_TAGS
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
})();
|
|
79
|
+
// X.690 §8.9.1 / §8.11.1 / §10.2 (DER), the mirror rules — a constructed-only
|
|
80
|
+
// universal type (SEQUENCE/SET) MUST be encoded constructed, and a
|
|
81
|
+
// primitive-only type (every other universal type the codec handles) MUST be
|
|
82
|
+
// encoded primitive. Both sets are DERIVED from the registry above and keyed by
|
|
83
|
+
// tag for an O(1) decode-time form check; a new descriptor is covered with no
|
|
84
|
+
// code change here.
|
|
85
|
+
var PRIMITIVE_ONLY_UNIVERSAL_TAGS = Object.create(null);
|
|
86
|
+
var CONSTRUCTED_ONLY_UNIVERSAL_TAGS = Object.create(null);
|
|
87
|
+
Object.keys(UNIVERSAL_TYPES).forEach(function (k) {
|
|
88
|
+
var d = UNIVERSAL_TYPES[k];
|
|
89
|
+
(d.form === "constructed" ? CONSTRUCTED_ONLY_UNIVERSAL_TAGS : PRIMITIVE_ONLY_UNIVERSAL_TAGS)[d.tag] = true;
|
|
90
|
+
});
|
|
81
91
|
|
|
82
92
|
function _className(bits) {
|
|
83
93
|
switch (bits) {
|
|
@@ -172,11 +182,12 @@ function _decodeTLV(buf, start, limit, depth, maxDepth) {
|
|
|
172
182
|
}
|
|
173
183
|
}
|
|
174
184
|
|
|
175
|
-
// X.690 8.9.1 / 8.11.1 — a universal SEQUENCE
|
|
176
|
-
// a primitive-tagged
|
|
177
|
-
// leaf that constructed-structure consumers dereference as a
|
|
178
|
-
|
|
179
|
-
|
|
185
|
+
// X.690 8.9.1 / 8.11.1 — a universal constructed-only type (SEQUENCE / SET)
|
|
186
|
+
// is always constructed; a primitive-tagged one is not valid DER (and would
|
|
187
|
+
// decode to a leaf that constructed-structure consumers dereference as a
|
|
188
|
+
// parent). Driven by the registry-derived set, not a hardcoded tag list.
|
|
189
|
+
if (tagClassBits === CLASS_UNIVERSAL && CONSTRUCTED_ONLY_UNIVERSAL_TAGS[tagNumber] && !constructed) {
|
|
190
|
+
throw new Asn1Error("asn1/bad-tlv", "a universal constructed-only type (SEQUENCE/SET) must be constructed");
|
|
180
191
|
}
|
|
181
192
|
|
|
182
193
|
// X.690 §8.x / §10.2 — the mirror rule: a universal primitive-only type
|
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:76df9bb3-81f7-4e82-8639-fd06f6b37a59",
|
|
6
6
|
"version": 1,
|
|
7
7
|
"metadata": {
|
|
8
|
-
"timestamp": "2026-07-
|
|
8
|
+
"timestamp": "2026-07-04T20:32:20.563Z",
|
|
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.1.
|
|
22
|
+
"bom-ref": "@blamejs/pki@0.1.5",
|
|
23
23
|
"type": "application",
|
|
24
24
|
"name": "pki",
|
|
25
|
-
"version": "0.1.
|
|
25
|
+
"version": "0.1.5",
|
|
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.1.
|
|
29
|
+
"purl": "pkg:npm/%40blamejs/pki@0.1.5",
|
|
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.1.
|
|
57
|
+
"ref": "@blamejs/pki@0.1.5",
|
|
58
58
|
"dependsOn": []
|
|
59
59
|
}
|
|
60
60
|
]
|