@primust/verifier 1.0.0 → 1.1.0
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/dist/chunk-LTWQK3HT.js +432 -0
- package/dist/chunk-NOADQWB6.js +3012 -0
- package/dist/cli.d.ts +3 -2
- package/dist/cli.js +309 -361
- package/dist/index.d.ts +335 -13
- package/dist/index.js +1181 -13
- package/dist/tsa-chain-7KSQ5LAH.js +235 -0
- package/dist/v29-envelope-GFVVA2S6.js +42 -0
- package/package.json +7 -8
- package/dist/bounded-trace.d.ts +0 -46
- package/dist/bounded-trace.d.ts.map +0 -1
- package/dist/bounded-trace.js +0 -558
- package/dist/bounded-trace.js.map +0 -1
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/key-cache.d.ts +0 -20
- package/dist/key-cache.d.ts.map +0 -1
- package/dist/key-cache.js +0 -68
- package/dist/key-cache.js.map +0 -1
- package/dist/scoped.d.ts +0 -35
- package/dist/scoped.d.ts.map +0 -1
- package/dist/scoped.js +0 -582
- package/dist/scoped.js.map +0 -1
- package/dist/types.d.ts +0 -60
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -5
- package/dist/types.js.map +0 -1
- package/dist/upstream_resolver.d.ts +0 -60
- package/dist/upstream_resolver.d.ts.map +0 -1
- package/dist/upstream_resolver.js +0 -126
- package/dist/upstream_resolver.js.map +0 -1
- package/dist/v29-envelope.d.ts +0 -55
- package/dist/v29-envelope.d.ts.map +0 -1
- package/dist/v29-envelope.js +0 -450
- package/dist/v29-envelope.js.map +0 -1
- package/dist/verifier.d.ts +0 -36
- package/dist/verifier.d.ts.map +0 -1
- package/dist/verifier.js +0 -1235
- package/dist/verifier.js.map +0 -1
- package/dist/verifier.test.d.ts +0 -2
- package/dist/verifier.test.d.ts.map +0 -1
- package/dist/verifier.test.js +0 -395
- package/dist/verifier.test.js.map +0 -1
- package/dist/verify-html-template.d.ts +0 -45
- package/dist/verify-html-template.d.ts.map +0 -1
- package/dist/verify-html-template.js +0 -182
- package/dist/verify-html-template.js.map +0 -1
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
// src/tsa-chain.ts
|
|
2
|
+
import { X509Certificate, createHash } from "crypto";
|
|
3
|
+
var DIGICERT_TRUSTED_ROOT_G4_FPR_HEX = "552f7bdcf1a7af9e6ce672017f4f12abf77240c78e761ac203d1d9d20ac89988";
|
|
4
|
+
var TIME_STAMPING_EKU_OID = "1.3.6.1.5.5.7.3.8";
|
|
5
|
+
var DIGICERT_TRUSTED_ROOT_G4_PEM = `-----BEGIN CERTIFICATE-----
|
|
6
|
+
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
|
|
36
|
+
-----END CERTIFICATE-----`;
|
|
37
|
+
function loadBundledRoots() {
|
|
38
|
+
const out = [];
|
|
39
|
+
try {
|
|
40
|
+
out.push(new X509Certificate(DIGICERT_TRUSTED_ROOT_G4_PEM));
|
|
41
|
+
} catch {
|
|
42
|
+
}
|
|
43
|
+
return out;
|
|
44
|
+
}
|
|
45
|
+
var BUNDLED_ROOTS = loadBundledRoots();
|
|
46
|
+
function trustedRootFprs() {
|
|
47
|
+
const env = globalThis.process?.env?.PRIMUST_TSA_ROOT_FPR;
|
|
48
|
+
if (!env || !env.trim()) {
|
|
49
|
+
return /* @__PURE__ */ new Set([DIGICERT_TRUSTED_ROOT_G4_FPR_HEX]);
|
|
50
|
+
}
|
|
51
|
+
return new Set(
|
|
52
|
+
env.split(",").map((f) => f.trim().toLowerCase().replace(/:/g, "")).filter(Boolean)
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
function verifyTsaChain(tsTokenB64) {
|
|
56
|
+
let tokenDer;
|
|
57
|
+
try {
|
|
58
|
+
tokenDer = Buffer.from(tsTokenB64, "base64");
|
|
59
|
+
} catch {
|
|
60
|
+
return { ok: false, reason: "parse_error" };
|
|
61
|
+
}
|
|
62
|
+
let certs;
|
|
63
|
+
try {
|
|
64
|
+
certs = extractCertificates(tokenDer);
|
|
65
|
+
} catch {
|
|
66
|
+
return { ok: false, reason: "parse_error" };
|
|
67
|
+
}
|
|
68
|
+
if (certs.length === 0) {
|
|
69
|
+
return { ok: false, reason: "no_certs" };
|
|
70
|
+
}
|
|
71
|
+
const trusted = trustedRootFprs();
|
|
72
|
+
let leaf = null;
|
|
73
|
+
for (const c of certs) {
|
|
74
|
+
if (hasTimeStampingEku(c)) {
|
|
75
|
+
leaf = c;
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (!leaf) {
|
|
80
|
+
const subjects = new Set(certs.map((c) => c.subject));
|
|
81
|
+
const issuers = new Set(certs.map((c) => c.issuer));
|
|
82
|
+
for (const c of certs) {
|
|
83
|
+
if (subjects.has(c.subject) && !issuers.has(c.subject)) {
|
|
84
|
+
leaf = c;
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
if (!leaf) {
|
|
90
|
+
return { ok: false, reason: "leaf_not_found" };
|
|
91
|
+
}
|
|
92
|
+
if (!hasTimeStampingEku(leaf)) {
|
|
93
|
+
return { ok: false, reason: "missing_eku" };
|
|
94
|
+
}
|
|
95
|
+
if (!isWithinValidity(leaf)) {
|
|
96
|
+
return { ok: false, reason: "expired" };
|
|
97
|
+
}
|
|
98
|
+
const candidateRoots = BUNDLED_ROOTS.filter(
|
|
99
|
+
(r) => trusted.has(certFingerprint(r))
|
|
100
|
+
);
|
|
101
|
+
const opRootPem = globalThis.process?.env?.PRIMUST_TSA_ROOT_PEM;
|
|
102
|
+
if (opRootPem) {
|
|
103
|
+
try {
|
|
104
|
+
const opRoot = new X509Certificate(opRootPem);
|
|
105
|
+
if (trusted.has(certFingerprint(opRoot))) {
|
|
106
|
+
candidateRoots.push(opRoot);
|
|
107
|
+
}
|
|
108
|
+
} catch {
|
|
109
|
+
return { ok: false, reason: "parse_error" };
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
if (candidateRoots.length === 0) {
|
|
113
|
+
return { ok: false, reason: "root_not_trusted" };
|
|
114
|
+
}
|
|
115
|
+
const bySubject = /* @__PURE__ */ new Map();
|
|
116
|
+
for (const c of certs) bySubject.set(c.subject, c);
|
|
117
|
+
const byRootSubject = /* @__PURE__ */ new Map();
|
|
118
|
+
for (const r of candidateRoots) byRootSubject.set(r.subject, r);
|
|
119
|
+
let current = leaf;
|
|
120
|
+
const seen = /* @__PURE__ */ new Set();
|
|
121
|
+
for (let hop = 0; hop < 8; hop++) {
|
|
122
|
+
if (seen.has(current.subject)) {
|
|
123
|
+
return { ok: false, reason: "chain_incomplete" };
|
|
124
|
+
}
|
|
125
|
+
seen.add(current.subject);
|
|
126
|
+
const rootCert = byRootSubject.get(current.issuer);
|
|
127
|
+
if (rootCert) {
|
|
128
|
+
if (!current.verify(rootCert.publicKey)) {
|
|
129
|
+
return { ok: false, reason: "signature_invalid" };
|
|
130
|
+
}
|
|
131
|
+
if (!isWithinValidity(rootCert)) {
|
|
132
|
+
return { ok: false, reason: "expired" };
|
|
133
|
+
}
|
|
134
|
+
return { ok: true, reason: "ok" };
|
|
135
|
+
}
|
|
136
|
+
const issuerCert = bySubject.get(current.issuer);
|
|
137
|
+
if (issuerCert && issuerCert !== current) {
|
|
138
|
+
if (!current.verify(issuerCert.publicKey)) {
|
|
139
|
+
return { ok: false, reason: "signature_invalid" };
|
|
140
|
+
}
|
|
141
|
+
if (!isWithinValidity(issuerCert)) {
|
|
142
|
+
return { ok: false, reason: "expired" };
|
|
143
|
+
}
|
|
144
|
+
if (issuerCert.subject === issuerCert.issuer) {
|
|
145
|
+
if (trusted.has(certFingerprint(issuerCert))) {
|
|
146
|
+
return { ok: true, reason: "ok" };
|
|
147
|
+
}
|
|
148
|
+
return { ok: false, reason: "root_not_trusted" };
|
|
149
|
+
}
|
|
150
|
+
current = issuerCert;
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
return { ok: false, reason: "chain_incomplete" };
|
|
154
|
+
}
|
|
155
|
+
return { ok: false, reason: "chain_incomplete" };
|
|
156
|
+
}
|
|
157
|
+
function certFingerprint(cert) {
|
|
158
|
+
return createHash("sha256").update(cert.raw).digest("hex");
|
|
159
|
+
}
|
|
160
|
+
function hasTimeStampingEku(cert) {
|
|
161
|
+
const info = cert.toString();
|
|
162
|
+
return info.includes(TIME_STAMPING_EKU_OID) || info.includes("Time Stamping");
|
|
163
|
+
}
|
|
164
|
+
function isWithinValidity(cert) {
|
|
165
|
+
const now = Date.now();
|
|
166
|
+
const nb = Date.parse(cert.validFrom);
|
|
167
|
+
const na = Date.parse(cert.validTo);
|
|
168
|
+
if (Number.isNaN(nb) || Number.isNaN(na)) return false;
|
|
169
|
+
return nb <= now && now <= na;
|
|
170
|
+
}
|
|
171
|
+
function extractCertificates(tokenDer) {
|
|
172
|
+
const signedDataOid = Buffer.from([
|
|
173
|
+
6,
|
|
174
|
+
9,
|
|
175
|
+
42,
|
|
176
|
+
134,
|
|
177
|
+
72,
|
|
178
|
+
134,
|
|
179
|
+
247,
|
|
180
|
+
13,
|
|
181
|
+
1,
|
|
182
|
+
7,
|
|
183
|
+
2
|
|
184
|
+
]);
|
|
185
|
+
const oidIdx = tokenDer.indexOf(signedDataOid);
|
|
186
|
+
if (oidIdx === -1) return [];
|
|
187
|
+
const scanStart = oidIdx + signedDataOid.length;
|
|
188
|
+
const limit = tokenDer.length;
|
|
189
|
+
for (let i = scanStart; i < limit - 2; i++) {
|
|
190
|
+
if (tokenDer[i] === 160) {
|
|
191
|
+
const lenInfo = parseDerLength(tokenDer, i + 1);
|
|
192
|
+
if (!lenInfo) continue;
|
|
193
|
+
const { length, headerLen } = lenInfo;
|
|
194
|
+
const setStart = i + 1 + headerLen;
|
|
195
|
+
const setEnd = setStart + length;
|
|
196
|
+
if (setEnd > limit) continue;
|
|
197
|
+
const certs = [];
|
|
198
|
+
let p = setStart;
|
|
199
|
+
while (p < setEnd) {
|
|
200
|
+
if (tokenDer[p] !== 48) break;
|
|
201
|
+
const li = parseDerLength(tokenDer, p + 1);
|
|
202
|
+
if (!li) break;
|
|
203
|
+
const certLen = li.length;
|
|
204
|
+
const certHdr = li.headerLen;
|
|
205
|
+
const certEnd = p + 1 + certHdr + certLen;
|
|
206
|
+
if (certEnd > setEnd) break;
|
|
207
|
+
const certDer = tokenDer.subarray(p, certEnd);
|
|
208
|
+
try {
|
|
209
|
+
certs.push(new X509Certificate(certDer));
|
|
210
|
+
} catch {
|
|
211
|
+
}
|
|
212
|
+
p = certEnd;
|
|
213
|
+
}
|
|
214
|
+
if (certs.length > 0) return certs;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return [];
|
|
218
|
+
}
|
|
219
|
+
function parseDerLength(buf, offset) {
|
|
220
|
+
if (offset >= buf.length) return null;
|
|
221
|
+
const first = buf[offset];
|
|
222
|
+
if ((first & 128) === 0) {
|
|
223
|
+
return { length: first, headerLen: 1 };
|
|
224
|
+
}
|
|
225
|
+
const n = first & 127;
|
|
226
|
+
if (n === 0 || n > 4 || offset + n >= buf.length) return null;
|
|
227
|
+
let val = 0;
|
|
228
|
+
for (let i = 0; i < n; i++) {
|
|
229
|
+
val = val << 8 | buf[offset + 1 + i];
|
|
230
|
+
}
|
|
231
|
+
return { length: val, headerLen: 1 + n };
|
|
232
|
+
}
|
|
233
|
+
export {
|
|
234
|
+
verifyTsaChain
|
|
235
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ALLOWED_KINDS,
|
|
3
|
+
ALLOWED_TRUST_EDGES,
|
|
4
|
+
ENVELOPE_VERSION,
|
|
5
|
+
PROOF_TIER_HIERARCHY,
|
|
6
|
+
canonicalHash,
|
|
7
|
+
canonicalJson,
|
|
8
|
+
reproduceAggregations,
|
|
9
|
+
reproduceManifestCanonicalHash,
|
|
10
|
+
reproduceTierCeiling,
|
|
11
|
+
v29Fail,
|
|
12
|
+
v29Pass,
|
|
13
|
+
validateAggregations,
|
|
14
|
+
validateEnvelopeShape,
|
|
15
|
+
validateManifestCanonicalHash,
|
|
16
|
+
validateManifestSignature,
|
|
17
|
+
validateRecordsAgainstHarness,
|
|
18
|
+
validateRuntimeBindingHash,
|
|
19
|
+
validateRuntimeBindingSignature,
|
|
20
|
+
verifyV29
|
|
21
|
+
} from "./chunk-LTWQK3HT.js";
|
|
22
|
+
export {
|
|
23
|
+
ALLOWED_KINDS,
|
|
24
|
+
ALLOWED_TRUST_EDGES,
|
|
25
|
+
ENVELOPE_VERSION,
|
|
26
|
+
PROOF_TIER_HIERARCHY,
|
|
27
|
+
canonicalHash,
|
|
28
|
+
canonicalJson,
|
|
29
|
+
reproduceAggregations,
|
|
30
|
+
reproduceManifestCanonicalHash,
|
|
31
|
+
reproduceTierCeiling,
|
|
32
|
+
v29Fail,
|
|
33
|
+
v29Pass,
|
|
34
|
+
validateAggregations,
|
|
35
|
+
validateEnvelopeShape,
|
|
36
|
+
validateManifestCanonicalHash,
|
|
37
|
+
validateManifestSignature,
|
|
38
|
+
validateRecordsAgainstHarness,
|
|
39
|
+
validateRuntimeBindingHash,
|
|
40
|
+
validateRuntimeBindingSignature,
|
|
41
|
+
verifyV29
|
|
42
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@primust/verifier",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Offline and CLI verifier for Primust VPECs. Free forever. No account required.",
|
|
5
5
|
"homepage": "https://primust.com",
|
|
6
6
|
"repository": {
|
|
@@ -15,15 +15,10 @@
|
|
|
15
15
|
"primust-verify": "dist/cli.js"
|
|
16
16
|
},
|
|
17
17
|
"scripts": {
|
|
18
|
-
"build": "
|
|
18
|
+
"build": "tsup src/index.ts src/cli.ts --format esm --dts --target node20",
|
|
19
19
|
"test": "vitest run",
|
|
20
20
|
"test:list": "vitest list --filesOnly"
|
|
21
21
|
},
|
|
22
|
-
"dependencies": {
|
|
23
|
-
"@primust/artifact-core": "^1.0.0",
|
|
24
|
-
"@noble/hashes": "^1.8.0",
|
|
25
|
-
"@zkpassport/poseidon2": "^0.6.2"
|
|
26
|
-
},
|
|
27
22
|
"peerDependencies": {
|
|
28
23
|
"better-sqlite3": "^12.0.0"
|
|
29
24
|
},
|
|
@@ -35,9 +30,13 @@
|
|
|
35
30
|
"devDependencies": {
|
|
36
31
|
"@types/node": "^22.0.0",
|
|
37
32
|
"better-sqlite3": "^12.6.2",
|
|
33
|
+
"tsup": "^8.5.1",
|
|
38
34
|
"tsx": "^4.19.0",
|
|
39
35
|
"typescript": "^5.6.0",
|
|
40
|
-
"vitest": "^3.0.0"
|
|
36
|
+
"vitest": "^3.0.0",
|
|
37
|
+
"@primust/artifact-core": "^1.0.0",
|
|
38
|
+
"@noble/hashes": "^1.8.0",
|
|
39
|
+
"@zkpassport/poseidon2": "^0.6.2"
|
|
41
40
|
},
|
|
42
41
|
"files": [
|
|
43
42
|
"dist"
|
package/dist/bounded-trace.d.ts
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Reference TypeScript interpreter for bounded_trace_v1 verification.
|
|
3
|
-
*
|
|
4
|
-
* This is the canonical second-opinion verifier described in PRIMUST_V27 §20.2,
|
|
5
|
-
* ported from verifier-py/src/primust_verify/bounded_trace.py. It is
|
|
6
|
-
* intentionally small and obviously-correct: consumes a BoundedTraceV1 payload
|
|
7
|
-
* plus a ProfileRecord and produces one of the §16.3 canonical downgrade
|
|
8
|
-
* reason codes (or "ok" on success).
|
|
9
|
-
*
|
|
10
|
-
* Crypto used: SHA-256 with RFC 6962-style domain-separated leaves (0x00)
|
|
11
|
-
* and nodes (0x01). Canonical JSON follows RFC 8785 + ECMAScript 7.1.12.1
|
|
12
|
-
* number serialization for cross-language parity.
|
|
13
|
-
*
|
|
14
|
-
* SI-3 (VPEC verifiability): this module's output MUST match the Python
|
|
15
|
-
* reference byte-for-byte across the shared conformance fixture corpus at
|
|
16
|
-
* packages/verifier-py/tests/fixtures/bounded_trace_v1/. The conformance
|
|
17
|
-
* runner in scripts/lane_a_conformance.* enforces this.
|
|
18
|
-
*
|
|
19
|
-
* Zero runtime dependencies besides node:crypto.
|
|
20
|
-
*/
|
|
21
|
-
export declare function canonicalNumber(x: number): string;
|
|
22
|
-
/**
|
|
23
|
-
* Canonical JSON serialization:
|
|
24
|
-
* - object keys sorted lexicographically
|
|
25
|
-
* - UTF-8
|
|
26
|
-
* - separators ",":":", no whitespace
|
|
27
|
-
* - numbers via canonicalNumber
|
|
28
|
-
* - strings via JSON.stringify (same escape rules as Python json with ensure_ascii=False)
|
|
29
|
-
*/
|
|
30
|
-
export declare function canonicalJson(obj: unknown): Uint8Array;
|
|
31
|
-
export declare function canonicalJsonString(obj: unknown): string;
|
|
32
|
-
export declare function buildMerkleRoot(leaves: Uint8Array[]): string;
|
|
33
|
-
export interface BoundedTraceResult {
|
|
34
|
-
valid: boolean;
|
|
35
|
-
proof_level: "operator_bound" | "execution";
|
|
36
|
-
reason: string;
|
|
37
|
-
disclosed_operator_count: number;
|
|
38
|
-
verified_merkle_paths: number;
|
|
39
|
-
details: Record<string, unknown>;
|
|
40
|
-
}
|
|
41
|
-
export declare const REASONS: readonly ["profile_not_found", "profile_signature_invalid", "profile_not_empirical", "profile_expired", "profile_revoked", "profile_no_freshness_window", "profile_trace_mismatch", "runtime_not_supported", "trace_schema_unknown", "missing_merkle_root", "merkle_inclusion_failed", "threshold_violation", "runtime_section_missing", "retrieval_section_missing", "closed_api_pre_cohort", "closed_api_pre_promote", "closed_api_v2_promoted", "profile_deprecated", "unknown_lifecycle_state"];
|
|
42
|
-
export type ReasonCode = (typeof REASONS)[number] | "thresholds_verified";
|
|
43
|
-
export declare function verifyBoundedTrace(trace: Record<string, unknown>, profile: Record<string, unknown>, options?: {
|
|
44
|
-
now?: Date;
|
|
45
|
-
}): BoundedTraceResult;
|
|
46
|
-
//# sourceMappingURL=bounded-trace.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"bounded-trace.d.ts","sourceRoot":"","sources":["../src/bounded-trace.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAMH,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CA6BjD;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,UAAU,CAGtD;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAiBxD;AAiCD,wBAAgB,eAAe,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,CAgB5D;AAID,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,OAAO,CAAC;IACf,WAAW,EAAE,gBAAgB,GAAG,WAAW,CAAC;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,wBAAwB,EAAE,MAAM,CAAC;IACjC,qBAAqB,EAAE,MAAM,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAID,eAAO,MAAM,OAAO,qeA0BV,CAAC;AAEX,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,OAAO,CAAC,CAAC,MAAM,CAAC,GAAG,qBAAqB,CAAC;AAsS1E,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,OAAO,GAAE;IAAE,GAAG,CAAC,EAAE,IAAI,CAAA;CAAO,GAC3B,kBAAkB,CA2JpB"}
|