@blamejs/pki 0.6.12 → 0.6.13
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 -2
- package/lib/sigstore.js +16 -7
- package/package.json +1 -1
- package/sbom.cdx.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -4,13 +4,21 @@ 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.6.
|
|
7
|
+
## v0.6.13 — 2026-09-01
|
|
8
|
+
|
|
9
|
+
pki.sigstore.verifyBundle now reports which transparency-log entry attested a bundle: the verdict carries `logIndex` and `logId` so a caller can locate the exact Rekor record it verified against.
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- pki.sigstore.verifyBundle's verdict carries `logIndex` (the attested Rekor entry's global log index) and `logId` (the log's key id, hex) beside `integratedTime`, so a caller can fetch or audit the exact transparency-log record the bundle was verified against instead of re-deriving it.
|
|
14
|
+
|
|
15
|
+
## v0.6.12 — 2026-08-31
|
|
8
16
|
|
|
9
17
|
Three verify verbs that returned a bare boolean now return a verdict object naming the checks they had hidden, a canonical `valid` field is present on every object verify verdict so `if (res.valid)` reads the same everywhere, and revocation, digest, and provenance data omitted before is surfaced.
|
|
10
18
|
|
|
11
19
|
### Added
|
|
12
20
|
|
|
13
|
-
- Every object verify verdict now carries a canonical `valid` boolean beside its existing terminal, so `if (res.valid)` reads the verdict the same way across the toolkit: pki.sigstore.verifyBundle, pki.csr.verify, pki.crmf.verifyPop (top and per message), pki.attrcert.verify, pki.webauthn.verify, pki.webauthn.verifyAssertion, pki.ocsp.verifyRequest (`valid` is `signed && signatureValid`), pki.ct.verifySctList (`valid` is `policyOk`), and pki.pkcs12.open (`valid` is
|
|
21
|
+
- Every object verify verdict now carries a canonical `valid` boolean beside its existing terminal, so `if (res.valid)` reads the verdict the same way across the toolkit: pki.sigstore.verifyBundle, pki.csr.verify, pki.crmf.verifyPop (top and per message), pki.attrcert.verify, pki.webauthn.verify, pki.webauthn.verifyAssertion, pki.ocsp.verifyRequest (`valid` is `signed && signatureValid`), pki.ct.verifySctList (`valid` is `policyOk`), and pki.pkcs12.open (`valid` is the store's verified integrity: the password MAC for a password store, or the CMS signature for a public-key store). The existing fields (`verified`, `policyOk`, `macVerified`, and the rest) are unchanged. The multi-state string verdicts (pki.ocsp.verify `status`, pki.scep `status`) keep their terminal and do not gain a `valid` alias, since a boolean cannot carry their states.
|
|
14
22
|
- pki.ocsp.verify and pki.path.verifyOcspResponse surface `revocationTime` (the revocation instant) beside `revocationReason` on a revoked verdict, for long-term validation.
|
|
15
23
|
- pki.cms.verify's primary signer node carries `digestAlgorithm`, the digest the countersignature node already reported, so a caller reading a signer's verdict learns it without a second parse.
|
|
16
24
|
- pki.sigstore.verifyBundle carries `predicateTypeChecked`, so a caller that did not pin `opts.predicateType` learns the in-toto predicate went unverified rather than assuming it was checked.
|
package/lib/sigstore.js
CHANGED
|
@@ -411,7 +411,10 @@ function _verifyRekor(te, envelope, rekorKeys, leafDer) {
|
|
|
411
411
|
if (!setOk) throw _err("sigstore/unattested-time", "the Rekor SET (the signed source of integratedTime) did not verify -- the log time is not attested and cannot date the Fulcio certificate");
|
|
412
412
|
var t = Number(te.integratedTime);
|
|
413
413
|
if (!Number.isFinite(t) || t < 0) throw _err("sigstore/bad-tlog-entry", "the transparency-log entry has a malformed integratedTime");
|
|
414
|
-
|
|
414
|
+
// Surface which attested Rekor log entry this is: the global log index and the log's key id (hex), so a
|
|
415
|
+
// caller can locate the exact transparency-log record for an audit rather than re-deriving it.
|
|
416
|
+
var li = Number(te.logIndex);
|
|
417
|
+
return { integratedTime: t, logIndex: Number.isFinite(li) ? li : null, logId: te.logId && te.logId.keyId ? _b64(te.logId.keyId, "logId.keyId").toString("hex") : null };
|
|
415
418
|
}
|
|
416
419
|
|
|
417
420
|
// ---- Fulcio chain leg (RFC 5280 path validation, as-of the log time) ----------
|
|
@@ -648,9 +651,10 @@ function _statement(payload, payloadType, expectedPredicate) {
|
|
|
648
651
|
* the log entry bound to this exact signature; and the in-toto SLSA statement.
|
|
649
652
|
* Any leg failing throws a typed `sigstore/*` error. On success returns
|
|
650
653
|
* `{ valid: true, verified: true, payload, statement, subjects, predicateType, predicate,
|
|
651
|
-
* identity, identityChecked, predicateTypeChecked, integratedTime }` (`valid` is the
|
|
652
|
-
* toolkit-wide verdict alias of `verified`,
|
|
653
|
-
* `opts.predicateType` was checked
|
|
654
|
+
* identity, identityChecked, predicateTypeChecked, integratedTime, logIndex, logId }` (`valid` is the
|
|
655
|
+
* canonical toolkit-wide verdict alias of `verified`, `predicateTypeChecked` says whether a pinned
|
|
656
|
+
* `opts.predicateType` was checked, and `logIndex` / `logId` identify the attested Rekor log entry).
|
|
657
|
+
* `payload` is the raw verified
|
|
654
658
|
* envelope bytes (never a re-serialization), and the caller confirms a
|
|
655
659
|
* `subjects[].digest` matches the published artifact.
|
|
656
660
|
*
|
|
@@ -708,13 +712,14 @@ async function verifyBundle(bundle, opts) {
|
|
|
708
712
|
// verifies (and binds this signature), rejecting only if none do.
|
|
709
713
|
var tlogs = Array.isArray(vm.tlogEntries) ? vm.tlogEntries : [];
|
|
710
714
|
if (!tlogs.length) throw _err("sigstore/bad-bundle", "a keyless bundle requires at least one transparency-log entry");
|
|
711
|
-
var
|
|
715
|
+
var rekor = null, lastErr = null;
|
|
712
716
|
for (var ti = 0; ti < tlogs.length; ti++) {
|
|
713
717
|
if (!tlogs[ti] || typeof tlogs[ti] !== "object") { lastErr = _err("sigstore/bad-bundle", "a transparency-log entry is not an object"); continue; }
|
|
714
|
-
try {
|
|
718
|
+
try { rekor = _verifyRekor(tlogs[ti], env, rekorKeys, leafDer); break; }
|
|
715
719
|
catch (e) { lastErr = e; }
|
|
716
720
|
}
|
|
717
|
-
if (
|
|
721
|
+
if (rekor === null) throw lastErr;
|
|
722
|
+
var integratedTime = rekor.integratedTime;
|
|
718
723
|
|
|
719
724
|
// Leg 3 -- Fulcio chain, validated as of the (trusted) log time; then identity.
|
|
720
725
|
// The instant comes through the time guard's intrinsic read. `getTime` is an ordinary method a
|
|
@@ -747,6 +752,10 @@ async function verifyBundle(bundle, opts) {
|
|
|
747
752
|
// a caller that omitted the pin gets `false` and knows the SLSA predicate went unverified.
|
|
748
753
|
predicateTypeChecked: opts.predicateType != null,
|
|
749
754
|
integratedTime: integratedTime,
|
|
755
|
+
// The attested Rekor entry this verdict rests on: `logIndex` is its global log index and `logId` the
|
|
756
|
+
// log's key id (hex), so a caller can fetch or audit the exact transparency-log record.
|
|
757
|
+
logIndex: rekor.logIndex,
|
|
758
|
+
logId: rekor.logId,
|
|
750
759
|
};
|
|
751
760
|
}
|
|
752
761
|
|
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:7a020e1d-6d6a-4d9e-9a8b-d17c7e4fa867",
|
|
6
6
|
"version": 1,
|
|
7
7
|
"metadata": {
|
|
8
|
-
"timestamp": "2026-09-
|
|
8
|
+
"timestamp": "2026-09-01T02:27:31.392Z",
|
|
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.6.
|
|
22
|
+
"bom-ref": "@blamejs/pki@0.6.13",
|
|
23
23
|
"type": "application",
|
|
24
24
|
"name": "pki",
|
|
25
|
-
"version": "0.6.
|
|
25
|
+
"version": "0.6.13",
|
|
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.6.
|
|
29
|
+
"purl": "pkg:npm/%40blamejs/pki@0.6.13",
|
|
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.6.
|
|
57
|
+
"ref": "@blamejs/pki@0.6.13",
|
|
58
58
|
"dependsOn": []
|
|
59
59
|
}
|
|
60
60
|
]
|