@blamejs/pki 0.5.33 → 0.5.34
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 +8 -0
- package/lib/pki-build.js +29 -6
- package/package.json +1 -1
- package/sbom.cdx.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,14 @@ 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.34 — 2026-08-29
|
|
8
|
+
|
|
9
|
+
A subjectAltName URI shorthand whose authority is a bracketed IPv6 literal is now accepted rather than refused.
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- A bare-string `subjectAltName` entry whose value is a URI with a bracketed IPv6 authority, such as `https://[2001:db8::1]:443/path`, now classifies as a `uniformResourceIdentifier`. The bracketed host is taken as one unit before an optional port, so a colon inside the IPv6 literal is no longer read as the port separator. An unterminated bracket, a bracket body that is not a valid IPv6 address, or bytes other than a port after the closing bracket stay refused, and the explicit `{ uniformResourceIdentifier: ... }` object form is unchanged.
|
|
14
|
+
|
|
7
15
|
## v0.5.33 — 2026-08-29
|
|
8
16
|
|
|
9
17
|
pki.cms.sign and pki.cms.verify accept the content as an async iterable of byte chunks, so a detached signature over a large payload is produced and verified without holding the payload in memory.
|
package/lib/pki-build.js
CHANGED
|
@@ -70,7 +70,8 @@ function _isSubDelim(c) {
|
|
|
70
70
|
function _isUserinfoByte(c) { return _isUnreserved(c) || _isSubDelim(c) || c === 58; }
|
|
71
71
|
// A path/query/fragment byte: unreserved / sub-delim / a non-bracket gen-delim (":" "/" "?" "#" "@").
|
|
72
72
|
// "%" is handled separately (it must open a "%HEXHEX" triplet); the IP-literal brackets "[" "]" are
|
|
73
|
-
// excluded
|
|
73
|
+
// excluded here because they are authority syntax -- a bracketed IPv6 host is validated in
|
|
74
|
+
// _validUriAuthority (RFC 3986 sec. 3.2.2), never in the path.
|
|
74
75
|
function _isUriByte(c) {
|
|
75
76
|
return _isUnreserved(c) || _isSubDelim(c) || c === 58 || c === 47 || c === 63 || c === 35 || c === 64;
|
|
76
77
|
}
|
|
@@ -122,8 +123,8 @@ function _componentBytesOk(s, from, to, byteOk) {
|
|
|
122
123
|
// or an FQDN of strict-LDH labels (the email-domain grammar: no underscore, no hyphen at a label edge) with
|
|
123
124
|
// at least one dot -- a single-label host such as "localhost" is not fully qualified and uses the object
|
|
124
125
|
// form, matching the email domain. An IPv4-SHAPED host that is not a valid address is refused as ambiguous
|
|
125
|
-
// (the same rule the top-level classifier uses)
|
|
126
|
-
//
|
|
126
|
+
// (the same rule the top-level classifier uses). An IPv6-literal host is written in "[" "]" and validated
|
|
127
|
+
// by _validUriIp6Host from _validUriAuthority, never reaching this unbracketed-host check.
|
|
127
128
|
function _validUriHost(s, from, to) {
|
|
128
129
|
if (to <= from) return false; // empty host
|
|
129
130
|
var host = _sliceStr(s, from, to), len = host.length;
|
|
@@ -135,10 +136,21 @@ function _validUriHost(s, from, to) {
|
|
|
135
136
|
return _labelsValid(host, 0, len, _isHostLabelRange, true); // strict-LDH FQDN, root "." allowed
|
|
136
137
|
}
|
|
137
138
|
|
|
139
|
+
// A bracketed IPv6-literal URI host (RFC 3986 sec. 3.2.2): the bytes between "[" and "]" must be a valid
|
|
140
|
+
// IPv6 address (16 packed octets), never an IPv4 literal (which uses the unbracketed IPv4address form). The
|
|
141
|
+
// bracket is the ONLY way to write an IPv6 host in a URI, and an IPv6 host is a valid iPAddress per RFC 5280
|
|
142
|
+
// sec. 4.2.1.6, so the shorthand accepts it rather than forcing the object form.
|
|
143
|
+
function _validUriIp6Host(s, from, to) {
|
|
144
|
+
if (to <= from) return false; // empty "[ ]"
|
|
145
|
+
var packed = _packIpLiteral(_sliceStr(s, from, to));
|
|
146
|
+
return packed !== null && intrinsic.sizeOf(packed) === 16; // IPv6 literal only (16 octets)
|
|
147
|
+
}
|
|
148
|
+
|
|
138
149
|
// The authority in [from,to) is "[ userinfo "@" ] host [ ":" port ]" (RFC 3986 sec. 3.2): at most one "@"
|
|
139
|
-
// (userinfo and reg-name each exclude it), a host
|
|
140
|
-
// an all-digit -- possibly empty -- port after the host's
|
|
141
|
-
//
|
|
150
|
+
// (userinfo and reg-name each exclude it), a host that is an RFC 5280 FQDN or IPv4 (_validUriHost) or a
|
|
151
|
+
// bracketed IPv6 literal (_validUriIp6Host), and an all-digit -- possibly empty -- port after the host's
|
|
152
|
+
// ":". A bracketed host is taken as ONE unit before the port, so a ":" inside the IPv6 literal is not read
|
|
153
|
+
// as the port separator. The userinfo bytes are validated against the RFC 3986 userinfo class.
|
|
142
154
|
function _validUriAuthority(s, from, to) {
|
|
143
155
|
var i, c, at = -1;
|
|
144
156
|
for (i = from; i < to; i += 1) {
|
|
@@ -147,6 +159,17 @@ function _validUriAuthority(s, from, to) {
|
|
|
147
159
|
}
|
|
148
160
|
var hostStart = at === -1 ? from : at + 1;
|
|
149
161
|
if (at !== -1 && !_componentBytesOk(s, from, at, _isUserinfoByte)) return false; // userinfo
|
|
162
|
+
if (hostStart < to && _charCodeAt(s, hostStart) === 91) { // "[" -> bracketed IPv6 host
|
|
163
|
+
var close = -1;
|
|
164
|
+
for (i = hostStart + 1; i < to; i += 1) { if (_charCodeAt(s, i) === 93) { close = i; break; } } // "]"
|
|
165
|
+
if (close === -1) return false; // unterminated "["
|
|
166
|
+
if (!_validUriIp6Host(s, hostStart + 1, close)) return false; // IPv6 literal in "[ ]"
|
|
167
|
+
var after = close + 1;
|
|
168
|
+
if (after === to) return true; // "[ ipv6 ]" with no port
|
|
169
|
+
if (_charCodeAt(s, after) !== 58) return false; // only a ":" port may follow "]"
|
|
170
|
+
for (i = after + 1; i < to; i += 1) { if (!_isDigitCode(_charCodeAt(s, i))) return false; } // port = *DIGIT
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
150
173
|
var colon = -1;
|
|
151
174
|
for (i = hostStart; i < to; i += 1) { if (_charCodeAt(s, i) === 58) { colon = i; break; } } // ":" -> port
|
|
152
175
|
var hostEnd = colon === -1 ? to : colon;
|
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:849173ca-4a17-451d-91be-1f2d75d83f00",
|
|
6
6
|
"version": 1,
|
|
7
7
|
"metadata": {
|
|
8
|
-
"timestamp": "2026-08-
|
|
8
|
+
"timestamp": "2026-08-29T10:04:44.768Z",
|
|
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.34",
|
|
23
23
|
"type": "application",
|
|
24
24
|
"name": "pki",
|
|
25
|
-
"version": "0.5.
|
|
25
|
+
"version": "0.5.34",
|
|
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.34",
|
|
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.34",
|
|
58
58
|
"dependsOn": []
|
|
59
59
|
}
|
|
60
60
|
]
|