@freedomofpress/sigstore-browser 0.1.14 → 0.1.15

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.
Files changed (60) hide show
  1. package/.github/workflows/conformance.yml +1 -1
  2. package/.github/workflows/publish.yml +1 -1
  3. package/README.md +20 -16
  4. package/dist/bundle.d.ts +2 -0
  5. package/dist/bundle.d.ts.map +1 -1
  6. package/dist/bundle.js +66 -1
  7. package/dist/bundle.js.map +1 -1
  8. package/dist/interfaces.d.ts +17 -2
  9. package/dist/interfaces.d.ts.map +1 -1
  10. package/dist/interfaces.js +14 -0
  11. package/dist/interfaces.js.map +1 -1
  12. package/dist/policy.d.ts +3 -3
  13. package/dist/policy.d.ts.map +1 -1
  14. package/dist/policy.js +4 -4
  15. package/dist/policy.js.map +1 -1
  16. package/dist/sigstore.d.ts +8 -17
  17. package/dist/sigstore.d.ts.map +1 -1
  18. package/dist/sigstore.js +159 -392
  19. package/dist/sigstore.js.map +1 -1
  20. package/dist/timestamp/tsa.d.ts +6 -2
  21. package/dist/timestamp/tsa.d.ts.map +1 -1
  22. package/dist/timestamp/tsa.js +15 -18
  23. package/dist/timestamp/tsa.js.map +1 -1
  24. package/dist/tlog/body.d.ts +3 -1
  25. package/dist/tlog/body.d.ts.map +1 -1
  26. package/dist/tlog/body.js +18 -5
  27. package/dist/tlog/body.js.map +1 -1
  28. package/dist/tlog/checkpoint.d.ts +2 -2
  29. package/dist/tlog/checkpoint.d.ts.map +1 -1
  30. package/dist/tlog/checkpoint.js +17 -95
  31. package/dist/tlog/checkpoint.js.map +1 -1
  32. package/dist/tlog/dsse.d.ts +3 -2
  33. package/dist/tlog/dsse.d.ts.map +1 -1
  34. package/dist/tlog/dsse.js +8 -5
  35. package/dist/tlog/dsse.js.map +1 -1
  36. package/dist/tlog/hashedrekord.d.ts +3 -2
  37. package/dist/tlog/hashedrekord.d.ts.map +1 -1
  38. package/dist/tlog/hashedrekord.js +8 -5
  39. package/dist/tlog/hashedrekord.js.map +1 -1
  40. package/dist/tlog/intoto.d.ts +3 -2
  41. package/dist/tlog/intoto.d.ts.map +1 -1
  42. package/dist/tlog/intoto.js +3 -1
  43. package/dist/tlog/intoto.js.map +1 -1
  44. package/package.json +2 -2
  45. package/src/bundle.ts +87 -0
  46. package/src/ed25519.browser.test.ts +76 -0
  47. package/src/index.browser.test.ts +38 -27
  48. package/src/interfaces.ts +29 -2
  49. package/src/policy.ts +5 -5
  50. package/src/security.browser.test.ts +249 -0
  51. package/src/sigstore.ts +191 -534
  52. package/src/timestamp/tsa.ts +29 -28
  53. package/src/tlog/body.ts +24 -5
  54. package/src/tlog/checkpoint.ts +22 -122
  55. package/src/tlog/dsse.ts +12 -6
  56. package/src/tlog/hashedrekord.ts +14 -8
  57. package/src/tlog/intoto.ts +5 -2
  58. package/src/verify.browser.test.ts +281 -0
  59. package/test/fixtures/rekor2.ts +14 -0
  60. package/test/fixtures/sigstore.ts +13 -0
@@ -0,0 +1,281 @@
1
+ import { base64ToUint8Array, hexToUint8Array, Uint8ArrayToBase64, Uint8ArrayToHex } from "@freedomofpress/crypto-browser";
2
+ import { describe, expect, it } from "vitest";
3
+
4
+ import * as rekor2 from "../test/fixtures/rekor2.js";
5
+ import { bundle, digestHex, identity, issuer, trustRoot } from "../test/fixtures/sigstore.js";
6
+ import type { SigstoreBundle, TLogEntry } from "./bundle.js";
7
+ import type { TrustedRoot } from "./interfaces.js";
8
+ import { AllOf, AnyOf, Identity, OIDCIssuer, OIDCIssuerV2 } from "./policy.js";
9
+ import { RFC3161Timestamp } from "./rfc3161/index.js";
10
+ import { SigstoreVerifier, type SigstoreVerifierOptions } from "./sigstore.js";
11
+ import { verifyTLogBody } from "./tlog/body.js";
12
+ import { X509Certificate } from "./x509/cert.js";
13
+
14
+ const digest = hexToUint8Array(digestHex);
15
+ const policy = new AllOf([new Identity({ identity }), new AnyOf([new OIDCIssuerV2(issuer), new OIDCIssuer(issuer)])]);
16
+ const signingCertB64 = () => bundle().verificationMaterial.certificate?.rawBytes ?? "";
17
+ const signingCert = () => X509Certificate.parse(base64ToUint8Array(signingCertB64()));
18
+ const integratedTime = new Date(Number(bundle().verificationMaterial.tlogEntries[0].integratedTime) * 1000);
19
+ const dayAfterSigning = new Date(integratedTime.getTime() + 86_400_000).toISOString();
20
+
21
+ async function verifier(opts: SigstoreVerifierOptions = {}, root: TrustedRoot = trustRoot()) {
22
+ const v = new SigstoreVerifier(opts);
23
+ await v.loadSigstoreRoot(root);
24
+ return v;
25
+ }
26
+ const verify = async (b: SigstoreBundle, opts: SigstoreVerifierOptions = {}, root?: TrustedRoot) =>
27
+ (await verifier(opts, root)).verifyArtifact(identity, issuer, b, digest, true);
28
+
29
+ // Wraps an empty OCTET STRING in `depth` SEQUENCEs with minimal DER lengths.
30
+ function nested(depth: number): Uint8Array {
31
+ let buf = new Uint8Array([0x04, 0x00]);
32
+ for (let i = 0; i < depth; i++) {
33
+ const len = buf.length;
34
+ const hdr = len < 128 ? [0x30, len] : len < 256 ? [0x30, 0x81, len] : [0x30, 0x82, len >> 8, len & 0xff];
35
+ const next = new Uint8Array(hdr.length + len);
36
+ next.set(hdr);
37
+ next.set(buf, hdr.length);
38
+ buf = next;
39
+ }
40
+ return buf;
41
+ }
42
+
43
+ describe("Baseline", () => {
44
+ it("verifies the fixture bundle with verifyArtifact and verifyDsse", async () => {
45
+ await expect(verify(bundle())).resolves.toBe(true);
46
+ const result = await (await verifier()).verifyDsse(bundle(), policy);
47
+ expect(result.payloadType).toBe("application/vnd.in-toto+json");
48
+ expect(new TextDecoder().decode(result.payload)).toContain(digestHex);
49
+ });
50
+
51
+ it("rejects a wrong identity and a wrong artifact digest", async () => {
52
+ const v = await verifier();
53
+ await expect(v.verifyArtifact("someone@else", issuer, bundle(), digest, true)).rejects.toThrow();
54
+ await expect(v.verifyArtifact(identity, issuer, bundle(), new Uint8Array(32), true)).rejects.toThrow("does not match any subject");
55
+ });
56
+ });
57
+
58
+ describe("Transparency log entries and threshold", () => {
59
+ const withExtra = (make: (e: TLogEntry, i: number) => TLogEntry, count: number) => {
60
+ const b = bundle();
61
+ const [first] = b.verificationMaterial.tlogEntries;
62
+ for (let i = 1; i <= count; i++) b.verificationMaterial.tlogEntries.push(make(structuredClone(first), i));
63
+ return b;
64
+ };
65
+ const proofless = (e: TLogEntry, i: number) => {
66
+ e.logIndex = String(Number(e.logIndex) + i);
67
+ delete e.inclusionProof;
68
+ delete e.inclusionPromise;
69
+ return e;
70
+ };
71
+
72
+ it("counts distinct verified log operators against the threshold", async () => {
73
+ await expect(verify(bundle(), { tlogThreshold: 2 })).rejects.toThrow("Not enough verified transparency logs: 1 < 2");
74
+ await expect(verify(withExtra(proofless, 1), { tlogThreshold: 2 })).rejects.toThrow("requires an inclusion proof");
75
+ const unknown = (e: TLogEntry, i: number) => proofless({ ...e, logId: { keyId: Uint8ArrayToBase64(new Uint8Array(32).fill(i)) } }, i);
76
+ await expect(verify(withExtra(unknown, 3), { tlogThreshold: 4 })).rejects.toThrow("Not enough verified transparency logs: 1 < 4");
77
+ const b = bundle();
78
+ b.verificationMaterial.tlogEntries[0].logId = { keyId: Uint8ArrayToBase64(new Uint8Array(32)) };
79
+ await expect(verify(b)).rejects.toThrow("Not enough verified transparency logs: 0 < 1");
80
+ });
81
+
82
+ it("verifies the SET of every entry, so a copied entry with a forged logIndex fails", async () => {
83
+ const forged = (e: TLogEntry, i: number) => ({ ...e, logIndex: String(Number(e.logIndex) + i) });
84
+ await expect(verify(withExtra(forged, 1), { tlogThreshold: 2 })).rejects.toThrow("inclusion promise");
85
+ });
86
+
87
+ it("groups logs by operator and never infers independence from missing metadata", async () => {
88
+ const root = trustRoot();
89
+ expect(root.tlogs.every((t) => t.operator === undefined)).toBe(true);
90
+ const keys = await (await verifier()).loadLog(root.tlogs);
91
+ expect(new Set(keys.map((k) => k.operator)).size).toBe(1);
92
+ root.tlogs.forEach((t, i) => (t.operator = `operator-${i}`));
93
+ expect(new Set((await (await verifier()).loadLog(root.tlogs)).map((k) => k.operator)).size).toBe(2);
94
+ await expect(verify(bundle(), {}, root)).resolves.toBe(true);
95
+ });
96
+
97
+ it("requires the Rekor key to be valid at the integrated time", async () => {
98
+ const expired = trustRoot();
99
+ expired.tlogs[0].publicKey.validFor.end = new Date(integratedTime.getTime() - 1000).toISOString();
100
+ await expect(verify(bundle(), {}, expired)).rejects.toThrow("Rekor key was not valid at the integrated time");
101
+ const future = trustRoot();
102
+ future.tlogs[0].publicKey.validFor.start = dayAfterSigning;
103
+ await expect(verify(bundle(), {}, future)).rejects.toThrow("Rekor key was not valid at the integrated time");
104
+ });
105
+
106
+ it("rejects more than 32 entries", async () => {
107
+ await expect(verify(withExtra((e) => e, 32))).rejects.toThrow("Invalid bundle: tlogEntries");
108
+ });
109
+ });
110
+
111
+ describe("Logged certificate binding per entry kind and version", () => {
112
+ const pem = (b64: string) => Uint8ArrayToBase64(new TextEncoder().encode(`-----BEGIN CERTIFICATE-----\n${b64}\n-----END CERTIFICATE-----\n`));
113
+ const otherDer = trustRoot().certificateAuthorities[1].certChain.certificates[0].rawBytes;
114
+ const otherPem = pem(otherDer);
115
+ const ownPem = pem(signingCertB64());
116
+ const env = bundle().dsseEnvelope ?? { payload: "", payloadType: "", signatures: [{ sig: "" }] };
117
+ const sig = env.signatures[0].sig;
118
+ const hashHex = () =>
119
+ crypto.subtle.digest("SHA-256", base64ToUint8Array(env.payload) as BufferSource).then((h) => Uint8ArrayToHex(new Uint8Array(h)));
120
+ const entry = (kind: string, version: string, spec: unknown): TLogEntry => ({
121
+ logIndex: "1",
122
+ logId: { keyId: trustRoot().tlogs[0].logId.keyId },
123
+ kindVersion: { kind, version },
124
+ integratedTime: "1",
125
+ canonicalizedBody: Uint8ArrayToBase64(new TextEncoder().encode(JSON.stringify({ apiVersion: version, kind, spec }))),
126
+ });
127
+ const expectBinding = async (ok: TLogEntry, wrong: TLogEntry, missing: TLogEntry, b: SigstoreBundle) => {
128
+ await expect(verifyTLogBody(ok, b, signingCert())).resolves.toBeUndefined();
129
+ await expect(verifyTLogBody(wrong, b, signingCert())).rejects.toThrow("does not match the signing certificate");
130
+ await expect(verifyTLogBody(missing, b, signingCert())).rejects.toThrow("does not record the signing certificate");
131
+ };
132
+
133
+ it("dsse 0.0.1 and 0.0.2", async () => {
134
+ const h = await hashHex();
135
+ const v1 = (verifier?: string) => entry("dsse", "0.0.1", { payloadHash: { algorithm: "sha256", value: h }, signatures: [{ signature: sig, verifier }] });
136
+ const v2 = (rawBytes?: string) =>
137
+ entry("dsse", "0.0.2", {
138
+ dsseV002: {
139
+ payloadHash: { algorithm: "SHA2_256", digest: Uint8ArrayToBase64(hexToUint8Array(h)) },
140
+ signatures: [{ content: sig, verifier: rawBytes ? { x509Certificate: { rawBytes } } : undefined }],
141
+ },
142
+ });
143
+ await expectBinding(v1(ownPem), v1(otherPem), v1(undefined), bundle());
144
+ await expectBinding(v2(signingCertB64()), v2(otherDer), v2(undefined), bundle());
145
+ });
146
+
147
+ it("intoto 0.0.2", async () => {
148
+ const h = await hashHex();
149
+ const doubleB64 = Uint8ArrayToBase64(new TextEncoder().encode(sig));
150
+ const e = (publicKey?: string) =>
151
+ entry("intoto", "0.0.2", {
152
+ content: { envelope: { payload: "", payloadType: "", signatures: [{ sig: doubleB64, publicKey }] }, payloadHash: { algorithm: "sha256", value: h } },
153
+ });
154
+ await expectBinding(e(ownPem), e(otherPem), e(undefined), bundle());
155
+ });
156
+
157
+ it("hashedrekord 0.0.1 and 0.0.2", async () => {
158
+ const b = bundle() as unknown as Record<string, unknown>;
159
+ delete b.dsseEnvelope;
160
+ b.messageSignature = { messageDigest: { algorithm: "SHA2_256", digest: "AA==" }, signature: sig };
161
+ const hr = b as unknown as SigstoreBundle;
162
+ const v1 = (content?: string) =>
163
+ entry("hashedrekord", "0.0.1", { data: { hash: { algorithm: "sha256", value: "00" } }, signature: { content: sig, publicKey: { content } } });
164
+ const v2 = (rawBytes?: string) =>
165
+ entry("hashedrekord", "0.0.2", {
166
+ hashedRekordV002: { data: { algorithm: "SHA2_256", digest: "AA==" }, signature: { content: sig, verifier: rawBytes ? { x509Certificate: { rawBytes } } : undefined } },
167
+ });
168
+ await expectBinding(v1(ownPem), v1(otherPem), v1(undefined), hr);
169
+ await expectBinding(v2(signingCertB64()), v2(otherDer), v2(undefined), hr);
170
+ });
171
+ });
172
+
173
+ describe("Bundle media type and structure", () => {
174
+ const proofless = (mediaType: string) => {
175
+ const b = bundle();
176
+ b.mediaType = mediaType;
177
+ delete b.verificationMaterial.tlogEntries[0].inclusionProof;
178
+ return b;
179
+ };
180
+
181
+ it("accepts only bundle versions 0.1 to 0.3", async () => {
182
+ for (const mt of ["application/x-garbage", "APPLICATION/VND.DEV.SIGSTORE.BUNDLE.V0.3+JSON", "", "application/vnd.dev.sigstore.bundle.v0.4+json", "application/vnd.dev.sigstore.bundle.v1.0+json"]) {
183
+ await expect(verify(proofless(mt))).rejects.toThrow("Unsupported bundle media type");
184
+ }
185
+ await expect(verify(proofless("application/vnd.dev.sigstore.bundle.v0.3+json"))).rejects.toThrow("requires an inclusion proof");
186
+ await expect(verify(proofless("application/vnd.dev.sigstore.bundle+json;version=0.1"))).resolves.toBe(true);
187
+ });
188
+
189
+ it("rejects a bundle carrying both a message signature and a DSSE envelope", async () => {
190
+ const b = bundle() as unknown as Record<string, unknown>;
191
+ b.messageSignature = { messageDigest: { algorithm: "SHA2_256", digest: "AA==" }, signature: "AA==" };
192
+ await expect(verify(b as unknown as SigstoreBundle)).rejects.toThrow("exactly one of messageSignature or dsseEnvelope");
193
+ });
194
+
195
+ it("rejects DSSE payload types other than in-toto and non-dsse entries in verifyDsse", async () => {
196
+ const b = bundle();
197
+ if (b.dsseEnvelope) b.dsseEnvelope.payloadType = "application/json";
198
+ await expect(verify(b)).rejects.toThrow("Unsupported DSSE payload type");
199
+ const c = bundle();
200
+ c.verificationMaterial.tlogEntries[0].kindVersion.kind = "hashedrekord";
201
+ await expect((await verifier()).verifyDsse(c, policy)).rejects.toThrow(/kind\/version mismatch|Expected entry type dsse/);
202
+ });
203
+ });
204
+
205
+ describe("Strict DER from crypto-browser", () => {
206
+ const withCert = (der: Uint8Array) => {
207
+ const b = bundle();
208
+ b.verificationMaterial.certificate = { rawBytes: Uint8ArrayToBase64(der) };
209
+ return b;
210
+ };
211
+
212
+ it("rejects trailing bytes, BER lengths and deep nesting in certificates and timestamps", async () => {
213
+ const der = base64ToUint8Array(signingCertB64());
214
+ await expect(verify(withCert(new Uint8Array([...der, 0xde, 0xad])))).rejects.toThrow("trailing bytes");
215
+ await expect(verify(withCert(new Uint8Array([0x30, 0x83, 0x00, ...der.subarray(2)])))).rejects.toThrow("non-minimal length");
216
+ const deep = nested(8000);
217
+ await expect(verify(withCert(deep))).rejects.toThrow("nesting too deep");
218
+ expect(() => RFC3161Timestamp.parse(deep)).toThrow("nesting too deep");
219
+ });
220
+ });
221
+
222
+ describe("Observer timestamps and historical trust material", () => {
223
+ it("verifies against a CA or Rekor key that was retired after the signature was made", async () => {
224
+ const ca = trustRoot();
225
+ ca.certificateAuthorities[1].validFor.end = dayAfterSigning;
226
+ await expect(verify(bundle(), {}, ca)).resolves.toBe(true);
227
+ const log = trustRoot();
228
+ log.tlogs[0].publicKey.validFor.end = dayAfterSigning;
229
+ await expect(verify(bundle(), {}, log)).resolves.toBe(true);
230
+ });
231
+
232
+ it("checks the CA validity window at the observer time", async () => {
233
+ const root = trustRoot();
234
+ root.certificateAuthorities[1].validFor.start = dayAfterSigning;
235
+ await expect(verify(bundle(), {}, root)).rejects.toThrow("No valid CAs found");
236
+ });
237
+
238
+ it("requires at least one verified observer timestamp", async () => {
239
+ // Without a SET the integrated time is unauthenticated, and there is no TSA timestamp either.
240
+ const b = bundle();
241
+ delete b.verificationMaterial.tlogEntries[0].inclusionPromise;
242
+ await expect(verify(b)).rejects.toThrow("No verified observer timestamp");
243
+ });
244
+
245
+ it("loads all trust material regardless of the wall clock", async () => {
246
+ const root = trustRoot();
247
+ expect(root.certificateAuthorities.some((ca) => ca.validFor.end && new Date(ca.validFor.end) < new Date())).toBe(true);
248
+ const v = await verifier({}, root);
249
+ expect(v.loadCA(root.certificateAuthorities)).toHaveLength(root.certificateAuthorities.length);
250
+ expect(await v.loadLog(root.tlogs)).toHaveLength(root.tlogs.length);
251
+ });
252
+ });
253
+
254
+ describe("Rekor v2 bundle with RFC 3161 timestamp", () => {
255
+ const r2digest = base64ToUint8Array(rekor2.digestB64);
256
+ const verifyR2 = async (b: SigstoreBundle, data = r2digest, opts: SigstoreVerifierOptions = {}) =>
257
+ (await verifier(opts, rekor2.trustRoot())).verifyArtifact(rekor2.identity, rekor2.issuer, b, data, true);
258
+
259
+ it("verifies hashedrekord 0.0.2, an Ed25519 checkpoint and a real TSA response", async () => {
260
+ await expect(verifyR2(rekor2.bundle())).resolves.toBe(true);
261
+ await expect(verifyR2(rekor2.bundle(), r2digest, { tsaThreshold: 1 })).resolves.toBe(true);
262
+ await expect(verifyR2(rekor2.bundle(), r2digest, { tsaThreshold: 2 })).rejects.toThrow("Not enough verified TSA operators: 1 < 2");
263
+ });
264
+
265
+ it("needs the timestamp as its only observer time and matches the message digest to the artifact", async () => {
266
+ const b = rekor2.bundle();
267
+ delete b.verificationMaterial.timestampVerificationData;
268
+ await expect(verifyR2(b)).rejects.toThrow("No verified observer timestamp");
269
+ await expect(verifyR2(rekor2.bundle(), new Uint8Array(32))).rejects.toThrow("does not match the bundle message digest");
270
+ });
271
+
272
+ it("rejects a tampered timestamp and a swapped signing certificate", async () => {
273
+ const b = rekor2.bundle();
274
+ const ts = b.verificationMaterial.timestampVerificationData?.rfc3161Timestamps[0];
275
+ if (ts) ts.signedTimestamp = Uint8ArrayToBase64(new Uint8Array([...base64ToUint8Array(ts.signedTimestamp), 0]));
276
+ await expect(verifyR2(b)).rejects.toThrow("trailing bytes");
277
+ const c = rekor2.bundle();
278
+ c.verificationMaterial.certificate = bundle().verificationMaterial.certificate;
279
+ await expect(verifyR2(c)).rejects.toThrow();
280
+ });
281
+ });
@@ -0,0 +1,14 @@
1
+ // Sigstore staging material from the sigstore-conformance suite: a v0.3 message-signature bundle whose
2
+ // hashedrekord/0.0.2 entry comes from a Rekor v2 log with an Ed25519 checkpoint and a real RFC 3161 timestamp.
3
+ import type { SigstoreBundle } from "../../src/bundle.js";
4
+ import type { TrustedRoot } from "../../src/interfaces.js";
5
+
6
+ export const identity =
7
+ "https://github.com/sigstore-conformance/extremely-dangerous-public-oidc-beacon/.github/workflows/extremely-dangerous-oidc-beacon.yml@refs/heads/main";
8
+ export const issuer = "https://token.actions.githubusercontent.com";
9
+ export const digestB64 = "oM/HEnHW4njlfNMy/5V8P3BD/do1TEy7GQow1W76Ab8=";
10
+ export const bundle = (): SigstoreBundle => structuredClone(BUNDLE) as SigstoreBundle;
11
+ export const trustRoot = (): TrustedRoot => structuredClone(ROOT) as TrustedRoot;
12
+
13
+ const BUNDLE = {"mediaType":"application/vnd.dev.sigstore.bundle.v0.3+json","verificationMaterial":{"certificate":{"rawBytes":"MIIIMTCCB7egAwIBAgIUJGo5qgyKJj/TX1P23VhIcFW0gi4wCgYIKoZIzj0EAwMwNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRlcm1lZGlhdGUwHhcNMjUwNjEyMTIwMjE2WhcNMjUwNjEyMTIxMjE2WjAAMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE9WKdUhMKYRNGrsqtBl4wwhbuz+RNC1muGGSzMvNHwriIWC55x1KX3DiRADCKt38HhBY1CLjnB1Hc3qxtZCrDX6OCBtYwggbSMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQU/2fXeMOxe3bGQ691Q+dusSVoh90wHwYDVR0jBBgwFoAUcYYwphR8Ym/599b0BRp/X//rb6wwgaUGA1UdEQEB/wSBmjCBl4aBlGh0dHBzOi8vZ2l0aHViLmNvbS9zaWdzdG9yZS1jb25mb3JtYW5jZS9leHRyZW1lbHktZGFuZ2Vyb3VzLXB1YmxpYy1vaWRjLWJlYWNvbi8uZ2l0aHViL3dvcmtmbG93cy9leHRyZW1lbHktZGFuZ2Vyb3VzLW9pZGMtYmVhY29uLnltbEByZWZzL2hlYWRzL21haW4wOQYKKwYBBAGDvzABAQQraHR0cHM6Ly90b2tlbi5hY3Rpb25zLmdpdGh1YnVzZXJjb250ZW50LmNvbTAfBgorBgEEAYO/MAECBBF3b3JrZmxvd19kaXNwYXRjaDA2BgorBgEEAYO/MAEDBCg5NzM5Nzk4OTQ1YjJhODQ4ZTkxMWJjZjFkZGRiOTcyOThjYWRlMGIxMC0GCisGAQQBg78wAQQEH0V4dHJlbWVseSBkYW5nZXJvdXMgT0lEQyBiZWFjb24wSQYKKwYBBAGDvzABBQQ7c2lnc3RvcmUtY29uZm9ybWFuY2UvZXh0cmVtZWx5LWRhbmdlcm91cy1wdWJsaWMtb2lkYy1iZWFjb24wHQYKKwYBBAGDvzABBgQPcmVmcy9oZWFkcy9tYWluMDsGCisGAQQBg78wAQgELQwraHR0cHM6Ly90b2tlbi5hY3Rpb25zLmdpdGh1YnVzZXJjb250ZW50LmNvbTCBpgYKKwYBBAGDvzABCQSBlwyBlGh0dHBzOi8vZ2l0aHViLmNvbS9zaWdzdG9yZS1jb25mb3JtYW5jZS9leHRyZW1lbHktZGFuZ2Vyb3VzLXB1YmxpYy1vaWRjLWJlYWNvbi8uZ2l0aHViL3dvcmtmbG93cy9leHRyZW1lbHktZGFuZ2Vyb3VzLW9pZGMtYmVhY29uLnltbEByZWZzL2hlYWRzL21haW4wOAYKKwYBBAGDvzABCgQqDCg5NzM5Nzk4OTQ1YjJhODQ4ZTkxMWJjZjFkZGRiOTcyOThjYWRlMGIxMB0GCisGAQQBg78wAQsEDwwNZ2l0aHViLWhvc3RlZDBeBgorBgEEAYO/MAEMBFAMTmh0dHBzOi8vZ2l0aHViLmNvbS9zaWdzdG9yZS1jb25mb3JtYW5jZS9leHRyZW1lbHktZGFuZ2Vyb3VzLXB1YmxpYy1vaWRjLWJlYWNvbjA4BgorBgEEAYO/MAENBCoMKDk3Mzk3OTg5NDViMmE4NDhlOTExYmNmMWRkZGI5NzI5OGNhZGUwYjEwHwYKKwYBBAGDvzABDgQRDA9yZWZzL2hlYWRzL21haW4wGQYKKwYBBAGDvzABDwQLDAk2MzI1OTY4OTcwNwYKKwYBBAGDvzABEAQpDCdodHRwczovL2dpdGh1Yi5jb20vc2lnc3RvcmUtY29uZm9ybWFuY2UwGQYKKwYBBAGDvzABEQQLDAkxMzE4MDQ1NjMwgaYGCisGAQQBg78wARIEgZcMgZRodHRwczovL2dpdGh1Yi5jb20vc2lnc3RvcmUtY29uZm9ybWFuY2UvZXh0cmVtZWx5LWRhbmdlcm91cy1wdWJsaWMtb2lkYy1iZWFjb24vLmdpdGh1Yi93b3JrZmxvd3MvZXh0cmVtZWx5LWRhbmdlcm91cy1vaWRjLWJlYWNvbi55bWxAcmVmcy9oZWFkcy9tYWluMDgGCisGAQQBg78wARMEKgwoOTczOTc5ODk0NWIyYTg0OGU5MTFiY2YxZGRkYjk3Mjk4Y2FkZTBiMTAhBgorBgEEAYO/MAEUBBMMEXdvcmtmbG93X2Rpc3BhdGNoMIGCBgorBgEEAYO/MAEVBHQMcmh0dHBzOi8vZ2l0aHViLmNvbS9zaWdzdG9yZS1jb25mb3JtYW5jZS9leHRyZW1lbHktZGFuZ2Vyb3VzLXB1YmxpYy1vaWRjLWJlYWNvbi9hY3Rpb25zL3J1bnMvMTU2MDk4NzcwODYvYXR0ZW1wdHMvMTAWBgorBgEEAYO/MAEWBAgMBnB1YmxpYzCBiQYKKwYBBAHWeQIEAgR7BHkAdwB1ACswvNxoiMni4dgmKV50H0g5MZYC8pwzy15DQP6yrIZ6AAABl2QE9+oAAAQDAEYwRAIgcMDyOAyLXLPjZqFcfQgMvctTQo8lhUXYyU1cQDfWyy0CIB9ybqPHF1jY9pbZMHYUJd2gPtapR90L/RYQIo2SdI7NMAoGCCqGSM49BAMDA2gAMGUCMASvG7iyBIiTLy+l5YjKtSs43sNA0lg7JM/oJXwk/20B26P5Yl6SBKOHypGeoM28EAIxAOkdwVfpMuDU32aAf61O4CA1c4Sr1CjCuRmfQ3NfcxYzNTPmtTGwZuIDjKj29ZRBWA=="},"tlogEntries":[{"logIndex":"735","logId":{"keyId":"8w1amZ2S5mJIQkQmPxdMuOrL/oJkvFg9MnQXmeOCXck="},"kindVersion":{"kind":"hashedrekord","version":"0.0.2"},"inclusionProof":{"logIndex":"735","rootHash":"rs1YPY0ydAV0lxgfrq5pE4oRpUJwo3syeps5+eGUTDI=","treeSize":"736","hashes":["JW27adKabAL7le2rFDSEUhPM94lzNjlhqi1BDFCFLCQ=","RbML4EU6v7vmDTLhcSzoi9tXr2IpqvGdXSofxij89RA=","W04Xfh+3qi0jWpYoDkt7GOrs5rRcDkZ2DH4P7YRmeVo=","cuFXxcpaflWsMid8mdJIBbBm4X25GQzOS87ZCrU0zgY=","Q1YXRmGYBNGsajHNJEPEJJUBUCoG4RbZx2bpvuDUxBk=","+gnK+M5cyTZ0UncCImJch9APOM+yjuVvfEuX7z6AamQ=","QMesRTEZdIgthOEinYE/9J7wGv+VmArDZTICj9POmhY=","UNUMG62rMwoqCqFKknh4R5Ubkf5Z6dj+Pk0m/1xu8uo="],"checkpoint":{"envelope":"log2025-alpha1.rekor.sigstage.dev\n736\nrs1YPY0ydAV0lxgfrq5pE4oRpUJwo3syeps5+eGUTDI=\n\n\u2014 log2025-alpha1.rekor.sigstage.dev 8w1amdbj1mjNN674dHAkD92+QZoEgBC7o0mXYSTRluDjQrOPjrps3zQB9ut+ShLepyZPsWBDi5IB3yXyjgjQT6OG9A8=\n"}},"canonicalizedBody":"eyJhcGlWZXJzaW9uIjoiMC4wLjIiLCJraW5kIjoiaGFzaGVkcmVrb3JkIiwic3BlYyI6eyJoYXNoZWRSZWtvcmRWMDAyIjp7ImRhdGEiOnsiYWxnb3JpdGhtIjoiU0hBMl8yNTYiLCJkaWdlc3QiOiJvTS9IRW5IVzRuamxmTk15LzVWOFAzQkQvZG8xVEV5N0dRb3cxVzc2QWI4PSJ9LCJzaWduYXR1cmUiOnsiY29udGVudCI6Ik1FWUNJUURNMFl4Sm43VnNVYzdGdlU3U0JYZWxTekZVV2V3YWVRbGJoUDVtYnBWbmF3SWhBUGFaNWRuczFhMzhLZ2VsV1dDczFTVzFseXJYeFZ6MlJ0aWlGS0RPRUxsQyIsInZlcmlmaWVyIjp7ImtleURldGFpbHMiOiJQS0lYX0VDRFNBX1AyNTZfU0hBXzI1NiIsIng1MDlDZXJ0aWZpY2F0ZSI6eyJyYXdCeXRlcyI6Ik1JSUlNVENDQjdlZ0F3SUJBZ0lVSkdvNXFneUtKai9UWDFQMjNWaEljRlcwZ2k0d0NnWUlLb1pJemowRUF3TXdOekVWTUJNR0ExVUVDaE1NYzJsbmMzUnZjbVV1WkdWMk1SNHdIQVlEVlFRREV4VnphV2R6ZEc5eVpTMXBiblJsY20xbFpHbGhkR1V3SGhjTk1qVXdOakV5TVRJd01qRTJXaGNOTWpVd05qRXlNVEl4TWpFMldqQUFNRmt3RXdZSEtvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUU5V0tkVWhNS1lSTkdyc3F0Qmw0d3doYnV6K1JOQzFtdUdHU3pNdk5Id3JpSVdDNTV4MUtYM0RpUkFEQ0t0MzhIaEJZMUNMam5CMUhjM3F4dFpDckRYNk9DQnRZd2dnYlNNQTRHQTFVZER3RUIvd1FFQXdJSGdEQVRCZ05WSFNVRUREQUtCZ2dyQmdFRkJRY0RBekFkQmdOVkhRNEVGZ1FVLzJmWGVNT3hlM2JHUTY5MVErZHVzU1ZvaDkwd0h3WURWUjBqQkJnd0ZvQVVjWVl3cGhSOFltLzU5OWIwQlJwL1gvL3JiNnd3Z2FVR0ExVWRFUUVCL3dTQm1qQ0JsNGFCbEdoMGRIQnpPaTh2WjJsMGFIVmlMbU52YlM5emFXZHpkRzl5WlMxamIyNW1iM0p0WVc1alpTOWxlSFJ5WlcxbGJIa3RaR0Z1WjJWeWIzVnpMWEIxWW14cFl5MXZhV1JqTFdKbFlXTnZiaTh1WjJsMGFIVmlMM2R2Y210bWJHOTNjeTlsZUhSeVpXMWxiSGt0WkdGdVoyVnliM1Z6TFc5cFpHTXRZbVZoWTI5dUxubHRiRUJ5WldaekwyaGxZV1J6TDIxaGFXNHdPUVlLS3dZQkJBR0R2ekFCQVFRcmFIUjBjSE02THk5MGIydGxiaTVoWTNScGIyNXpMbWRwZEdoMVluVnpaWEpqYjI1MFpXNTBMbU52YlRBZkJnb3JCZ0VFQVlPL01BRUNCQkYzYjNKclpteHZkMTlrYVhOd1lYUmphREEyQmdvckJnRUVBWU8vTUFFREJDZzVOek01TnprNE9UUTFZakpoT0RRNFpUa3hNV0pqWmpGa1pHUmlPVGN5T1RoallXUmxNR0l4TUMwR0Npc0dBUVFCZzc4d0FRUUVIMFY0ZEhKbGJXVnNlU0JrWVc1blpYSnZkWE1nVDBsRVF5QmlaV0ZqYjI0d1NRWUtLd1lCQkFHRHZ6QUJCUVE3YzJsbmMzUnZjbVV0WTI5dVptOXliV0Z1WTJVdlpYaDBjbVZ0Wld4NUxXUmhibWRsY205MWN5MXdkV0pzYVdNdGIybGtZeTFpWldGamIyNHdIUVlLS3dZQkJBR0R2ekFCQmdRUGNtVm1jeTlvWldGa2N5OXRZV2x1TURzR0Npc0dBUVFCZzc4d0FRZ0VMUXdyYUhSMGNITTZMeTkwYjJ0bGJpNWhZM1JwYjI1ekxtZHBkR2gxWW5WelpYSmpiMjUwWlc1MExtTnZiVENCcGdZS0t3WUJCQUdEdnpBQkNRU0Jsd3lCbEdoMGRIQnpPaTh2WjJsMGFIVmlMbU52YlM5emFXZHpkRzl5WlMxamIyNW1iM0p0WVc1alpTOWxlSFJ5WlcxbGJIa3RaR0Z1WjJWeWIzVnpMWEIxWW14cFl5MXZhV1JqTFdKbFlXTnZiaTh1WjJsMGFIVmlMM2R2Y210bWJHOTNjeTlsZUhSeVpXMWxiSGt0WkdGdVoyVnliM1Z6TFc5cFpHTXRZbVZoWTI5dUxubHRiRUJ5WldaekwyaGxZV1J6TDIxaGFXNHdPQVlLS3dZQkJBR0R2ekFCQ2dRcURDZzVOek01TnprNE9UUTFZakpoT0RRNFpUa3hNV0pqWmpGa1pHUmlPVGN5T1RoallXUmxNR0l4TUIwR0Npc0dBUVFCZzc4d0FRc0VEd3dOWjJsMGFIVmlMV2h2YzNSbFpEQmVCZ29yQmdFRUFZTy9NQUVNQkZBTVRtaDBkSEJ6T2k4dloybDBhSFZpTG1OdmJTOXphV2R6ZEc5eVpTMWpiMjVtYjNKdFlXNWpaUzlsZUhSeVpXMWxiSGt0WkdGdVoyVnliM1Z6TFhCMVlteHBZeTF2YVdSakxXSmxZV052YmpBNEJnb3JCZ0VFQVlPL01BRU5CQ29NS0RrM016azNPVGc1TkRWaU1tRTRORGhsT1RFeFltTm1NV1JrWkdJNU56STVPR05oWkdVd1lqRXdId1lLS3dZQkJBR0R2ekFCRGdRUkRBOXlaV1p6TDJobFlXUnpMMjFoYVc0d0dRWUtLd1lCQkFHRHZ6QUJEd1FMREFrMk16STFPVFk0T1Rjd053WUtLd1lCQkFHRHZ6QUJFQVFwRENkb2RIUndjem92TDJkcGRHaDFZaTVqYjIwdmMybG5jM1J2Y21VdFkyOXVabTl5YldGdVkyVXdHUVlLS3dZQkJBR0R2ekFCRVFRTERBa3hNekU0TURRMU5qTXdnYVlHQ2lzR0FRUUJnNzh3QVJJRWdaY01nWlJvZEhSd2N6b3ZMMmRwZEdoMVlpNWpiMjB2YzJsbmMzUnZjbVV0WTI5dVptOXliV0Z1WTJVdlpYaDBjbVZ0Wld4NUxXUmhibWRsY205MWN5MXdkV0pzYVdNdGIybGtZeTFpWldGamIyNHZMbWRwZEdoMVlpOTNiM0pyWm14dmQzTXZaWGgwY21WdFpXeDVMV1JoYm1kbGNtOTFjeTF2YVdSakxXSmxZV052Ymk1NWJXeEFjbVZtY3k5b1pXRmtjeTl0WVdsdU1EZ0dDaXNHQVFRQmc3OHdBUk1FS2d3b09UY3pPVGM1T0RrME5XSXlZVGcwT0dVNU1URmlZMll4WkdSa1lqazNNams0WTJGa1pUQmlNVEFoQmdvckJnRUVBWU8vTUFFVUJCTU1FWGR2Y210bWJHOTNYMlJwYzNCaGRHTm9NSUdDQmdvckJnRUVBWU8vTUFFVkJIUU1jbWgwZEhCek9pOHZaMmwwYUhWaUxtTnZiUzl6YVdkemRHOXlaUzFqYjI1bWIzSnRZVzVqWlM5bGVIUnlaVzFsYkhrdFpHRnVaMlZ5YjNWekxYQjFZbXhwWXkxdmFXUmpMV0psWVdOdmJpOWhZM1JwYjI1ekwzSjFibk12TVRVMk1EazROemN3T0RZdllYUjBaVzF3ZEhNdk1UQVdCZ29yQmdFRUFZTy9NQUVXQkFnTUJuQjFZbXhwWXpDQmlRWUtLd1lCQkFIV2VRSUVBZ1I3QkhrQWR3QjFBQ3N3dk54b2lNbmk0ZGdtS1Y1MEgwZzVNWllDOHB3enkxNURRUDZ5cklaNkFBQUJsMlFFOStvQUFBUURBRVl3UkFJZ2NNRHlPQXlMWExQalpxRmNmUWdNdmN0VFFvOGxoVVhZeVUxY1FEZld5eTBDSUI5eWJxUEhGMWpZOXBiWk1IWVVKZDJnUHRhcFI5MEwvUllRSW8yU2RJN05NQW9HQ0NxR1NNNDlCQU1EQTJnQU1HVUNNQVN2RzdpeUJJaVRMeStsNVlqS3RTczQzc05BMGxnN0pNL29KWHdrLzIwQjI2UDVZbDZTQktPSHlwR2VvTTI4RUFJeEFPa2R3VmZwTXVEVTMyYUFmNjFPNENBMWM0U3IxQ2pDdVJtZlEzTmZjeFl6TlRQbXRUR3dadUlEaktqMjlaUkJXQT09In19fX19fQ=="}],"timestampVerificationData":{"rfc3161Timestamps":[{"signedTimestamp":"MIIE6jADAgEAMIIE4QYJKoZIhvcNAQcCoIIE0jCCBM4CAQMxDTALBglghkgBZQMEAgEwgcIGCyqGSIb3DQEJEAEEoIGyBIGvMIGsAgEBBgkrBgEEAYO/MAIwMTANBglghkgBZQMEAgEFAAQgbd8xYJ4qbIFPgmaqt1IEt6H16W0bwH3eb/Oa3YQIzaICFFWXQsce2uW2RSM6esQ6jQMxQqWsGA8yMDI1MDYxMjEyMDIyMFowAwIBAQIJAI9Z8q/mnMiooDKkMDAuMRUwEwYDVQQKEwxzaWdzdG9yZS5kZXYxFTATBgNVBAMTDHNpZ3N0b3JlLXRzYaCCAhMwggIPMIIBlqADAgECAhQKNaEGYdXiQXPGiZan8n3yfgN8pzAKBggqhkjOPQQDAzA5MRUwEwYDVQQKEwxzaWdzdG9yZS5kZXYxIDAeBgNVBAMTF3NpZ3N0b3JlLXRzYS1zZWxmc2lnbmVkMB4XDTI1MDMyODA5MTQwNloXDTM1MDMyNjA4MTQwNlowLjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MRUwEwYDVQQDEwxzaWdzdG9yZS10c2EwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATHW/kXcekP16Ae6SekEWVHPtAFEMm7hp5XO33MktFjSW+bHWUXtYEzZz0A3xkY9CyYOoeUk3ZH/v5HEuS+UvORzX0g7Hfy3uYYYRwHtqBQN0IX8rLdFMtIrRej/QCAdB2jajBoMA4GA1UdDwEB/wQEAwIHgDAdBgNVHQ4EFgQUqPxk9ijeLuY7c09UjFLE4ZzdU6UwHwYDVR0jBBgwFoAUOyBGWV61Mk1HMM5uY+5zdEfyBH0wFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwCgYIKoZIzj0EAwMDZwAwZAIwRK9VLoYa0Xff4nX1N/AQ1YleNG/iLT8dAXAtRKRfpN9XuDScbxWeo0cku8SkC06NAjBQPe7LBNeitA/UOBtXT2sX1h6f4ISqz+ISmJ4lY+y3bzRJI5nk1r53I9WT3/xIWToxggHcMIIB2AIBATBRMDkxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjEgMB4GA1UEAxMXc2lnc3RvcmUtdHNhLXNlbGZzaWduZWQCFAo1oQZh1eJBc8aJlqfyffJ+A3ynMAsGCWCGSAFlAwQCAaCB/DAaBgkqhkiG9w0BCQMxDQYLKoZIhvcNAQkQAQQwHAYJKoZIhvcNAQkFMQ8XDTI1MDYxMjEyMDIyMFowLwYJKoZIhvcNAQkEMSIEICXnz5HAQnH9WOuMmb4hZGrrZvGZPI98Lw0T3ZgcdddfMIGOBgsqhkiG9w0BCRACLzF/MH0wezB5BCAG9P/gR/6zWZm3M7DXoyNQHPwY5MAzZqhF13U250snRDBVMD2kOzA5MRUwEwYDVQQKEwxzaWdzdG9yZS5kZXYxIDAeBgNVBAMTF3NpZ3N0b3JlLXRzYS1zZWxmc2lnbmVkAhQKNaEGYdXiQXPGiZan8n3yfgN8pzAKBggqhkjOPQQDAgRoMGYCMQCH3FfjUxAybs2PGGGimOaahUA2wDuwYws22nzLnsGEwGg6b6GOuMduqGpbSuuJnoQCMQDhzG6dCCyjgB+O9++D89S2ShJeUeJ0QSMwYiAelDXX5nMg0m6dxLVJCB5HSyku32g="}]}},"messageSignature":{"messageDigest":{"algorithm":"SHA2_256","digest":"oM/HEnHW4njlfNMy/5V8P3BD/do1TEy7GQow1W76Ab8="},"signature":"MEYCIQDM0YxJn7VsUc7FvU7SBXelSzFUWewaeQlbhP5mbpVnawIhAPaZ5dns1a38KgelWWCs1SW1lyrXxVz2RtiiFKDOELlC"}};
14
+ const ROOT = {"mediaType":"application/vnd.dev.sigstore.trustedroot+json;version=0.1","tlogs":[{"baseUrl":"https://rekor.sigstage.dev","hashAlgorithm":"SHA2_256","publicKey":{"rawBytes":"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEDODRU688UYGuy54mNUlaEBiQdTE9nYLr0lg6RXowI/QV/RE1azBn4Eg5/2uTOMbhB1/gfcHzijzFi9Tk+g1Prg==","keyDetails":"PKIX_ECDSA_P256_SHA_256","validFor":{"start":"2021-01-12T11:53:27Z"}},"logId":{"keyId":"0y8wo8MtY5wrdiIFohx7sHeI5oKDpK5vQhGHI6G+pJY="}},{"baseUrl":"https://log2025-alpha1.rekor.sigstage.dev","hashAlgorithm":"SHA2_256","publicKey":{"rawBytes":"MCowBQYDK2VwAyEAPn+AREHoBaZ7wgS1zBqpxmLSGnyhxXj4lFxSdWVB8o8=","keyDetails":"PKIX_ED25519","validFor":{"start":"2025-04-16T00:00:00Z"}},"logId":{"keyId":"8w1amZ2S5mJIQkQmPxdMuOrL/oJkvFg9MnQXmeOCXck="}}],"certificateAuthorities":[{"subject":{"organization":"sigstore.dev","commonName":"sigstore"},"uri":"https://fulcio.sigstage.dev","certChain":{"certificates":[{"rawBytes":"MIICGTCCAaCgAwIBAgITJta/okfgHvjabGm1BOzuhrwA1TAKBggqhkjOPQQDAzAqMRUwEwYDVQQKEwxzaWdzdG9yZS5kZXYxETAPBgNVBAMTCHNpZ3N0b3JlMB4XDTIyMDQxNDIxMzg0MFoXDTMyMDMyMjE2NTA0NVowNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRlcm1lZGlhdGUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASosAySWJQ/tK5r8T5aHqavk0oI+BKQbnLLdmOMRXHQF/4Hx9KtNfpcdjH9hNKQSBxSlLFFN3tvFCco0qFBzWYwZtsYsBe1l91qYn/9VHFTaEVwYQWIJEEvrs0fvPuAqjajezB5MA4GA1UdDwEB/wQEAwIBBjATBgNVHSUEDDAKBggrBgEFBQcDAzASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBRxhjCmFHxib/n31vQFGn9f/+tvrDAfBgNVHSMEGDAWgBT/QjK6aH2rOnCv3AzUGuI+h49mZTAKBggqhkjOPQQDAwNnADBkAjAM1lbKkcqQlE/UspMTbWNo1y2TaJ44tx3l/FJFceTSdDZ+0W1OHHeU4twie/lq8XgCMHQxgEv26xNNiAGyPXbkYgrDPvbOqp0UeWX4mJnLSrBr3aN/KX1SBrKQu220FmVL0Q=="},{"rawBytes":"MIIB9jCCAXugAwIBAgITDdEJvluliE0AzYaIE4jTMdnFTzAKBggqhkjOPQQDAzAqMRUwEwYDVQQKEwxzaWdzdG9yZS5kZXYxETAPBgNVBAMTCHNpZ3N0b3JlMB4XDTIyMDMyNTE2NTA0NloXDTMyMDMyMjE2NTA0NVowKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTB2MBAGByqGSM49AgEGBSuBBAAiA2IABMo9BUNk9QIYisYysC24+2OytoV72YiLonYcqR3yeVnYziPt7Xv++CYE8yoCTiwedUECCWKOcvQKRCJZb9ht4Hzy+VvBx36hK+C6sECCSR0x6pPSiz+cTk1f788ZjBlUZaNjMGEwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP9CMrpofas6cK/cDNQa4j6Hj2ZlMB8GA1UdIwQYMBaAFP9CMrpofas6cK/cDNQa4j6Hj2ZlMAoGCCqGSM49BAMDA2kAMGYCMQD+kojuzMwztNay9Ibzjuk//ZL5m6T2OCsm45l1lY004pcb984L926BowodoirFMcMCMQDIJtFHhP/1D3a+M3dAGomOb6O4CmTry3TTPbPsAFnv22YA0Y+P21NVoxKDjdu0tkw="}]},"validFor":{"start":"2022-04-14T21:38:40Z"}}],"ctlogs":[{"baseUrl":"https://ctfe.sigstage.dev/test","hashAlgorithm":"SHA2_256","publicKey":{"rawBytes":"MIICCgKCAgEA27A2MPQXm0I0v7/Ly5BIauDjRZF5Jor9vU+QheoE2UIIsZHcyYq3slHzSSHy2lLj1ZD2d91CtJ492ZXqnBmsr4TwZ9jQ05tW2mGIRI8u2DqN8LpuNYZGz/f9SZrjhQQmUttqWmtu3UoLfKz6NbNXUnoo+NhZFcFRLXJ8VporVhuiAmL7zqT53cXR3yQfFPCUDeGnRksnlhVIAJc3AHZZSHQJ8DEXMhh35TVv2nYhTI3rID7GwjXXw4ocz7RGDD37ky6p39Tl5NB71gT1eSqhZhGHEYHIPXraEBd5+3w9qIuLWlp5Ej/K6Mu4ELioXKCUimCbwy+Cs8UhHFlqcyg4AysOHJwIadXIa8LsY51jnVSGrGOEBZevopmQPNPtyfFY3dmXSS+6Z3RD2Gd6oDnNGJzpSyEk410Ag5uvNDfYzJLCWX9tU8lIxNwdFYmIwpd89HijyRyoGnoJ3entd63cvKfuuix5r+GHyKp1Xm1L5j5AWM6P+z0xigwkiXnt+adexAl1J9wdDxv/pUFEESRF4DG8DFGVtbdH6aR1A5/vD4krO4tC1QYUSeyL5Mvsw8WRqIFHcXtgybtxylljvNcGMV1KXQC8UFDmpGZVDSHx6v3e/BHMrZ7gjoCCfVMZ/cFcQi0W2AIHPYEMH/C95J2r4XbHMRdYXpovpOoT5Ca78gsCAwEAAQ==","keyDetails":"PKCS1_RSA_PKCS1V5","validFor":{"start":"2021-03-14T00:00:00Z","end":"2022-07-31T00:00:00Z"}},"logId":{"keyId":"G3wUKk6ZK6ffHh/FdCRUE2wVekyzHEEIpSG4savnv0w="}},{"baseUrl":"https://ctfe.sigstage.dev/2022","hashAlgorithm":"SHA2_256","publicKey":{"rawBytes":"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEh99xuRi6slBFd8VUJoK/rLigy4bYeSYWO/fE6Br7r0D8NpMI94+A63LR/WvLxpUUGBpY8IJA3iU2telag5CRpA==","keyDetails":"PKIX_ECDSA_P256_SHA_256","validFor":{"start":"2022-07-01T00:00:00Z","end":"2022-07-31T00:00:00Z"}},"logId":{"keyId":"++JKOMQt7SJ3ynUHnCfnDhcKP8/58J4TueMqXuk3HmA="}},{"baseUrl":"https://ctfe.sigstage.dev/2022-2","hashAlgorithm":"SHA2_256","publicKey":{"rawBytes":"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8gEDKNme8AnXuPBgHjrtXdS6miHqc24CRblNEOFpiJRngeq8Ko73Y+K18yRYVf1DXD4AVLwvKyzdNdl5n0jUSQ==","keyDetails":"PKIX_ECDSA_P256_SHA_256","validFor":{"start":"2022-07-01T00:00:00Z"}},"logId":{"keyId":"KzC83GiIyeLh2CYpXnQfSDkxlgLynDPLXkNA/rKshno="}}],"timestampAuthorities":[{"subject":{"organization":"sigstore.dev","commonName":"sigstore-tsa-selfsigned"},"uri":"https://timestamp.sigstage.dev/api/v1/timestamp","certChain":{"certificates":[{"rawBytes":"MIICDzCCAZagAwIBAgIUCjWhBmHV4kFzxomWp/J98n4DfKcwCgYIKoZIzj0EAwMwOTEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MSAwHgYDVQQDExdzaWdzdG9yZS10c2Etc2VsZnNpZ25lZDAeFw0yNTAzMjgwOTE0MDZaFw0zNTAzMjYwODE0MDZaMC4xFTATBgNVBAoTDHNpZ3N0b3JlLmRldjEVMBMGA1UEAxMMc2lnc3RvcmUtdHNhMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEx1v5F3HpD9egHuknpBFlRz7QBRDJu4aeVzt9zJLRY0lvmx1lF7WBM2c9AN8ZGPQsmDqHlJN2R/7+RxLkvlLzkc19IOx38t7mGGEcB7agUDdCF/Ky3RTLSK0Xo/0AgHQdo2owaDAOBgNVHQ8BAf8EBAMCB4AwHQYDVR0OBBYEFKj8ZPYo3i7mO3NPVIxSxOGc3VOlMB8GA1UdIwQYMBaAFDsgRlletTJNRzDObmPuc3RH8gR9MBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMAoGCCqGSM49BAMDA2cAMGQCMESvVS6GGtF33+J19TfwENWJXjRv4i0/HQFwLUSkX6TfV7g0nG8VnqNHJLvEpAtOjQIwUD3uywTXorQP1DgbV09rF9Yen+CEqs/iEpieJWPst280SSOZ5Na+dyPVk9/8SFk6"},{"rawBytes":"MIIB9zCCAXygAwIBAgIUCPExEFKiQh0dP4sp5ltmSYSSkFUwCgYIKoZIzj0EAwMwOTEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MSAwHgYDVQQDExdzaWdzdG9yZS10c2Etc2VsZnNpZ25lZDAeFw0yNTAzMjgwOTE0MDZaFw0zNTAzMjYwODE0MDZaMDkxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjEgMB4GA1UEAxMXc2lnc3RvcmUtdHNhLXNlbGZzaWduZWQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATt0tIDWyo4ARfL9BaSo0W5bJQEbKJTU/u7llvdjSI5aTkOAJa8tixn2+LEfPG4dMFdsMPtsIuU1qn2OqFiuMk6vHv/c+az25RQVY1oo50iMb0jIL3N4FgwhPFpZnCbQPOjRTBDMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBQ7IEZZXrUyTUcwzm5j7nN0R/IEfTAKBggqhkjOPQQDAwNpADBmAjEA2MI1VXgbf3dUOSc95hSRypBKOab18eh2xzQtxUsHvWeY+1iFgyMluUuNR6taoSmFAjEA31m2czguZhKYX+4JSKu5pRYhBTXAd8KKQ3xdPRX/qCaLvT2qJAEQ1YQM3EJRrtI7"}]},"validFor":{"start":"2025-04-09T00:00:00Z"}}]};
@@ -0,0 +1,13 @@
1
+ // Real public-good Sigstore material from the tinfoil conformance vectors: a v0.3 DSSE bundle
2
+ // (dsse/0.0.1 entry with SET and inclusion proof) and the trusted root it verifies against.
3
+ import type { SigstoreBundle } from "../../src/bundle.js";
4
+ import type { TrustedRoot } from "../../src/interfaces.js";
5
+
6
+ export const identity = "https://github.com/tinfoilsh/confidential-model-router/.github/workflows/build.yml@refs/tags/v0.0.38";
7
+ export const issuer = "https://token.actions.githubusercontent.com";
8
+ export const digestHex = "5ed9d5c942528ec2eeb759919827f1bc2183c6810f80225a52147dd4020c12a0";
9
+ export const bundle = (): SigstoreBundle => structuredClone(BUNDLE) as SigstoreBundle;
10
+ export const trustRoot = (): TrustedRoot => structuredClone(ROOT) as TrustedRoot;
11
+
12
+ const BUNDLE = {"mediaType":"application/vnd.dev.sigstore.bundle.v0.3+json","verificationMaterial":{"tlogEntries":[{"logIndex":"845420855","logId":{"keyId":"wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="},"kindVersion":{"kind":"dsse","version":"0.0.1"},"integratedTime":"1769121722","inclusionPromise":{"signedEntryTimestamp":"MEYCIQDp6n17vPjI3saP/S1unI3vjGjRe6TBlyEJzaBW0hX+pgIhANhOdeHQhzb99xHmIuYw2xOC51L7WegbAWwcffvNwtcU"},"inclusionProof":{"logIndex":"723516593","rootHash":"bcnNJMxP3O41KH+tZSlqxljkVtCjK6N+8xV+6APwPoE=","treeSize":"723516595","hashes":["SoSru/5+KUcfOu1OGlGSo27db6SALH/rAHffx4fgDCg=","fTxN3o7iBYzIfzZz99U1ClC10yNGgxxdq0Tx2m8ISl8=","CRr5qLnqeynMQKZ+hRxfYsiBEDbSSr/rUd9sXQ0auxg=","F8XKu3m71Gdent31tzM94bC8Nfbwy19F3TZk88/Ou50=","2FIwoj0Q1s1nRVjpx+LLaN3wAK45bl4HWTS69OeDJdk=","fP4sQ6AIWrIe6EtunLwJyWcDgvyy46kN3seK0qO2M4M=","UQQSKngaZ+Usj/wDr/CmxIm9O1xIh5uHsqqSdjCRQko=","F5XSCRNey2jaKDiZ3POmhhPoL/a5DhlDieu2BqA4KdU=","O11kot9qj1yNK2pbskeTGMIGZxaJCgoAk5a3VoJKCQo=","P8Jo71slYipsIAlQO1zkvNb9hNgu+iLauxB8ak5ATVQ=","a1+JUJNc95YxlBvx2i70cYRbvVK/vtb5eX0RpofVlsI=","QAPqkYPsiaqX1B2ckuuIGHcMYYV12127Gcd0GZmE2Qc=","A6FaI53Kv6QdrtKOvuBBC9eaA2ThBlq5WYS40EsmPXM=","ab7PAC+EkOOMd4Z11/fUy6//deMVcMNpmowQZeTK0ew=","TDV59aI1Y2EjDzkY4AypVi0hXvBNCo+3inkYPaf6FpM=","uTgS+JyaWsVevrqzcNqFiFP6sZcY66CJdR+HT/Trt3s=","6OLWbtKvxLyT2cr4F2qdHh0quyYiSl/P7LpDfVrK6R8=","WFmkMhmL2tOzDi6lp4zGgaCzwux2vGOM44v1vr1wuDs=","F9MSQ5SmoFr+hoADclpdFY52/TLfHDnNPYb9ZNYO5gI=","T4DqWD42hAtN+vX8jKCWqoC4meE4JekI9LxYGCcPy1M="],"checkpoint":{"envelope":"rekor.sigstore.dev - 1193050959916656506\n723516595\nbcnNJMxP3O41KH+tZSlqxljkVtCjK6N+8xV+6APwPoE=\n\n\u2014 rekor.sigstore.dev wNI9ajBGAiEA3nFYLCB/sFxNr4vWZ/2MSDzXe6ianjsNO1ydIcGj1DgCIQCeVLcmv1CJ0SQvh2P0GWZeefsM+TPeNcZho3ACTMX+ig==\n"}},"canonicalizedBody":"eyJhcGlWZXJzaW9uIjoiMC4wLjEiLCJraW5kIjoiZHNzZSIsInNwZWMiOnsiZW52ZWxvcGVIYXNoIjp7ImFsZ29yaXRobSI6InNoYTI1NiIsInZhbHVlIjoiZTMyZTVmYTc0NTMyNTE5NDRjNDMxMTllNThlOTViMjY1NGNkODRjZjMzNDhhNjY0MmIyNmZhNGIxZDBhYWFiMiJ9LCJwYXlsb2FkSGFzaCI6eyJhbGdvcml0aG0iOiJzaGEyNTYiLCJ2YWx1ZSI6IjZjM2VmMDg4MmI1NGZkMmI2ZTYyN2NlNjI4ZGM0ZTY3MjY1Y2I5YTg2NzUzYjAxZjQxNTMxMTFhZjVkMmFjZTYifSwic2lnbmF0dXJlcyI6W3sic2lnbmF0dXJlIjoiTUVVQ0lRQ2Z0bjBsSC9FNVRtUFlNWExibTFoaFJEUDRBZXBYa2xMN2F0VW9EdVFxZWdJZ1J3eEhQLytVV0kxVU5uTkExL1o1RGtCbVBsMVE3WHBBT0FoWCt6OTE2dUE9IiwidmVyaWZpZXIiOiJMUzB0TFMxQ1JVZEpUaUJEUlZKVVNVWkpRMEZVUlMwdExTMHRDazFKU1VoTFZFTkRRbkVyWjBGM1NVSkJaMGxWWlZjM1RtWnhUVGd6WTI1NFIyWmpXVVpyUlhsNk5IQXlPRmRWZDBObldVbExiMXBKZW1vd1JVRjNUWGNLVG5wRlZrMUNUVWRCTVZWRlEyaE5UV015Ykc1ak0xSjJZMjFWZFZwSFZqSk5ValIzU0VGWlJGWlJVVVJGZUZaNllWZGtlbVJIT1hsYVV6RndZbTVTYkFwamJURnNXa2RzYUdSSFZYZElhR05PVFdwWmQwMVVTWGxOYWtrd1RXcEJlVmRvWTA1TmFsbDNUVlJKZVUxcVNURk5ha0Y1VjJwQlFVMUdhM2RGZDFsSUNrdHZXa2w2YWpCRFFWRlpTVXR2V2tsNmFqQkVRVkZqUkZGblFVVlJZVTgwTlRZNWNqSTBkVkp1Um1oMGNESlZhVFZYZFVGTk5VcHVWelZTVW1WSmEwd0tla2xoUkhGTFNETm1OMlJ1VWl0Tk9FeE1XWEZXYWpVeE1VUnVORlZsYzJ0a1IzWmFObmsxSzA1cE1HVldjbmhDY1hGUFEwSmpOSGRuWjFoTFRVRTBSd3BCTVZWa1JIZEZRaTkzVVVWQmQwbElaMFJCVkVKblRsWklVMVZGUkVSQlMwSm5aM0pDWjBWR1FsRmpSRUY2UVdSQ1owNVdTRkUwUlVablVWVk1TMHRXQ2xCSVdtd3JWVE5HVkd0U00wdFVkelJtYzFOTFdXNHdkMGgzV1VSV1VqQnFRa0puZDBadlFWVXpPVkJ3ZWpGWmEwVmFZalZ4VG1wd1MwWlhhWGhwTkZrS1drUTRkMk5uV1VSV1VqQlNRVkZJTDBKSFozZGFiMXByWVVoU01HTklUVFpNZVRsdVlWaFNiMlJYU1hWWk1qbDBURE5TY0dKdFduWmhWM2g2WVVNNWFncGlNalZ0WVZkU2JHSnVVbkJaVjNkMFlsYzVhMXBYZDNSamJUa3haRWRXZVV4NU5XNWhXRkp2WkZkSmRtUXlPWGxoTWxwellqTmtla3d5U2pGaFYzaHJDa3h1YkhSaVJVSjVXbGRhZWt3elVtaGFNMDEyWkdwQmRVMUROSHBQUkVFMVFtZHZja0puUlVWQldVOHZUVUZGUWtKRGRHOWtTRkozWTNwdmRrd3pVbllLWVRKV2RVeHRSbXBrUjJ4MlltNU5kVm95YkRCaFNGWnBaRmhPYkdOdFRuWmlibEpzWW01UmRWa3lPWFJOUWtsSFEybHpSMEZSVVVKbk56aDNRVkZKUlFwQ1NFSXhZekpuZDA1bldVdExkMWxDUWtGSFJIWjZRVUpCZDFGdlRqSkZNRmt5UlRST01sRXhUa1JuZUZwVVJtbE5lbVJxVFZkT2FGbFVhR2xPUkd4cUNrMVVZek5OVjFsM1dXcG5NazlVVW1oT2VrRnRRbWR2Y2tKblJVVkJXVTh2VFVGRlJVSkNhRVZpTWs1eVdsaEpaMUZ1Vm5CaVIxRm5XVmMxYTBsR1FqRUtXVzE0Y0dNeVozZE5VVmxMUzNkWlFrSkJSMFIyZWtGQ1FsRlJhbVJIYkhWYWJUbHdZa2hPYjB3eVRuWmliVnB3V2tkV2RXUkhiR2hpUXpGMFlqSlNiQXBpUXpGNVlqTldNRnBZU1hkSWQxbExTM2RaUWtKQlIwUjJla0ZDUW1kUlVtTnRWbTFqZVRrd1dWZGtla3d6V1hkTWFrRjFUWHBuZDA5M1dVdExkMWxDQ2tKQlIwUjJla0ZDUTBGUmRFUkRkRzlrU0ZKM1kzcHZka3d6VW5aaE1sWjFURzFHYW1SSGJIWmliazExV2pKc01HRklWbWxrV0U1c1kyMU9kbUp1VW13S1ltNVJkVmt5T1hSTlNGRkhRMmx6UjBGUlVVSm5OemgzUVZGclJWcG5lR3RoU0ZJd1kwaE5Oa3g1T1c1aFdGSnZaRmRKZFZreU9YUk1NMUp3WW0xYWRncGhWM2g2WVVNNWFtSXlOVzFoVjFKc1ltNVNjRmxYZDNSaVZ6bHJXbGQzZEdOdE9URmtSMVo1VEhrMWJtRllVbTlrVjBsMlpESTVlV0V5V25OaU0yUjZDa3d5U2pGaFYzaHJURzVzZEdKRlFubGFWMXA2VEROU2FGb3pUWFprYWtGMVRVTTBlazlFUVRSQ1oyOXlRbWRGUlVGWlR5OU5RVVZMUWtOdlRVdEVaR2dLVGtkT2FFOUVaR3RPVkZFMFRWZFZlRmxxVFROWmVrWnFXVmRGTkZscVVUVlpla1V6VG5wR2JVMUhTVFJPYW1zd1dWUmpkMGhSV1V0TGQxbENRa0ZIUkFwMmVrRkNRM2RSVUVSQk1XNWhXRkp2WkZkSmRHRkhPWHBrUjFaclRVVlpSME5wYzBkQlVWRkNaemM0ZDBGUmQwVlBRWGN5WVVoU01HTklUVFpNZVRsdUNtRllVbTlrVjBsMVdUSTVkRXd6VW5CaWJWcDJZVmQ0ZW1GRE9XcGlNalZ0WVZkU2JHSnVVbkJaVjNkMFlsYzVhMXBYZDNSamJUa3haRWRXZVUxRVowY0tRMmx6UjBGUlVVSm5OemgzUVZFd1JVdG5kMjlPTWtVd1dUSkZORTR5VVRGT1JHZDRXbFJHYVUxNlpHcE5WMDVvV1ZSb2FVNUViR3BOVkdNelRWZFpkd3BaYW1jeVQxUlNhRTU2UVdoQ1oyOXlRbWRGUlVGWlR5OU5RVVZQUWtKTlRVVllTbXhhYmsxMlpFZEdibU41T1RKTlF6UjNUR3BOTkUxQ2IwZERhWE5IQ2tGUlVVSm5OemgzUVZFNFJVUkJkMHROVkVFelRucEJOVTVFUlRST2VrRnpRbWR2Y2tKblJVVkJXVTh2VFVGRlVVSkNORTFJUjJnd1pFaENlazlwT0hZS1dqSnNNR0ZJVm1sTWJVNTJZbE01TUdGWE5XMWlNbXh6WXpKbmQwZFJXVXRMZDFsQ1FrRkhSSFo2UVVKRlVWRk1SRUZyZUU1cVp6QlBSR00wVGxSWmR3cGtRVmxMUzNkWlFrSkJSMFIyZWtGQ1JXZFNiVVJIVW05a1NGSjNZM3B2ZGt3eVpIQmtSMmd4V1drMWFtSXlNSFprUjJ4MVdtMDVjR0pJVG05TU1rNTJDbUp0V25CYVIxWjFaRWRzYUdKRE1YUmlNbEpzWWtNeGVXSXpWakJhV0VsMlRHMWtjR1JIYURGWmFUa3pZak5LY2xwdGVIWmtNMDEyV1c1V2NHSkhVWFVLWlZjeGMxRklTbXhhYmsxMlpFZEdibU41T1RKTlF6UjNUR3BOTkUxRVowZERhWE5IUVZGUlFtYzNPSGRCVWsxRlMyZDNiMDR5UlRCWk1rVTBUakpSTVFwT1JHZDRXbFJHYVUxNlpHcE5WMDVvV1ZSb2FVNUViR3BOVkdNelRWZFpkMWxxWnpKUFZGSm9UbnBCVlVKbmIzSkNaMFZGUVZsUEwwMUJSVlZDUVZsTkNrSklRakZqTW1kM1lXZFpTMHQzV1VKQ1FVZEVkbnBCUWtaUlVtTkVSbkJ2WkVoU2QyTjZiM1pNTW1Sd1pFZG9NVmxwTldwaU1qQjJaRWRzZFZwdE9YQUtZa2hPYjB3eVRuWmliVnB3V2tkV2RXUkhiR2hpUXpGMFlqSlNiR0pETVhsaU0xWXdXbGhKZGxsWFRqQmhWemwxWTNrNWVXUlhOWHBNZWtsNFRXcFpNd3BOYW1jeVRWUnJla3d5UmpCa1IxWjBZMGhTZWt4NlNYZEdaMWxMUzNkWlFrSkJSMFIyZWtGQ1JtZFJTVVJCV25ka1YwcHpZVmROZDJkWmMwZERhWE5IQ2tGUlVVSXhibXREUWtGSlJXWlJVamRCU0d0QlpIZEVaRkJVUW5GNGMyTlNUVzFOV2tob2VWcGFlbU5EYjJ0d1pYVk9ORGh5Wml0SWFXNUxRVXg1Ym5VS2FtZEJRVUZhZG00emVTczBRVUZCUlVGM1FrbE5SVmxEU1ZGRFZHVndOVzh6UkZGdVZteHZOMHRsV25NclJGQnNNVlY2VkV0cFFqaGFhRE5LYkdnMlVncFZTa2RqVEhkSmFFRk1XSEZ5YTJSS01uaGFaMVVyUVVsTllUQlVRMUJQWjFWT01sTkZaR2xWYjFob2RqVkhXbnAzZEROR1RVRnZSME5EY1VkVFRUUTVDa0pCVFVSQk1tZEJUVWRWUTAxUlExWkZZMGhoUlZkaWFFWnViWFZsU2tKc00xb3dOVUowTUVWYVFUZFJjRmRNWlhKUlQyUnViVmhHZWxoSFJrNTJXa3NLWmt4eVpqQkpSQ3N5T0RkNWFrMUpRMDFHWWl0TEwwNVRaMmxwYlZoWVVFUm1kVFVyTm1GM2JEQkxNR0kyWldOeWFFMXJNbEZHVDJrM2FGaEhOMVowZGdwUVdWaGhVVUUwVG5SMFIxcGlPV3RJWjFFOVBRb3RMUzB0TFVWT1JDQkRSVkpVU1VaSlEwRlVSUzB0TFMwdENnPT0ifV19fQ=="}],"timestampVerificationData":{},"certificate":{"rawBytes":"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"}},"dsseEnvelope":{"payload":"eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdjEiLCJzdWJqZWN0IjpbeyJuYW1lIjoidGluZm9pbC1kZXBsb3ltZW50Lmpzb24iLCJkaWdlc3QiOnsic2hhMjU2IjoiNWVkOWQ1Yzk0MjUyOGVjMmVlYjc1OTkxOTgyN2YxYmMyMTgzYzY4MTBmODAyMjVhNTIxNDdkZDQwMjBjMTJhMCJ9fV0sInByZWRpY2F0ZVR5cGUiOiJodHRwczovL3RpbmZvaWwuc2gvcHJlZGljYXRlL3NucC10ZHgtbXVsdGlwbGF0Zm9ybS92MSIsInByZWRpY2F0ZSI6eyJzbnBfbWVhc3VyZW1lbnQiOiIwOWVmMzJhY2Y5MGZjZmViNjIwNmQxYTQ2YzEzMTQ1Y2VmNzM2ZWJiYjgzZjE4ZWFmZjY4MGI2ODYyMzIwMzE1NDZmZjVmZDM5YzQ0NTk5Njk5ZWU4NzM0Y2JiZWI1MTkiLCJ0ZHhfbWVhc3VyZW1lbnQiOnsicnRtcjEiOiJhN2VkMWJjYmU2OTYyMjJlY2Y5NTZmMmM3OGEzYjI5ZmNjOGNhMjQ4MzFhNDc1MWI1OGY1ODU4ZDUzN2ZiZjI5NjY2ZTc5NDllODQwMjU5OWM5NmY0MWE4MGY3ZmUyNTMiLCJydG1yMiI6ImRkY2UzNmM3YmViZjg0MWIzYTRmZjBjOGMyZGY2Mzg2OWYxMDJiNzQ5MDQwNjNlZmMyNDI0NGJmNWI5ODNiNDRlODdmNjEwYzczZjk2M2JkM2U4NTkwMTQ5MDM1MDhjMyJ9LCJjbWRsaW5lIjoicmVhZG9ubHk9b24gcGNpPXJlYWxsb2Msbm9jcnMgbW9kcHJvYmUuYmxhY2tsaXN0PW5vdXZlYXUgbm91dmVhdS5tb2Rlc2V0PTAgcm9vdD0vZGV2L21hcHBlci9yb290IHJvb3RoYXNoPTAwYmIyZmY4MWUxMWY2ZWVlNzM3YzE2NjRlMDVmOTU2YzIwYWZlOTkwMzM3Yzk3M2FjYmIxM2FkMjBjYjU4MmYgdGluZm9pbC1jb25maWctaGFzaD1jM2ZhYjViMmNmYjlhMzkzNDEzZjQyYzYzNmU1Y2EyMzUzOGVjOGVjYmU1NmE2ZDI5NzAwOGMxZTA0NjQwMWNkIiwiaGFzaGVzIjp7InZlcnNpb24iOiJ2MC41LjE2Iiwicm9vdCI6IjAwYmIyZmY4MWUxMWY2ZWVlNzM3YzE2NjRlMDVmOTU2YzIwYWZlOTkwMzM3Yzk3M2FjYmIxM2FkMjBjYjU4MmYiLCJpbml0cmQiOiJiOTc5MjdiODFjODIwMzM4MWQ4OWNlZDhkOTBlNzgyYjFkODdhZTNlNmI3MWY1MjM3MGJhODFhZWJhMmFkZWQxIiwia2VybmVsIjoiMzljYzNkOTdkNDE1ZDk5NTIzNzU0YWYwMjAzZjM5NTFmYTNiZmRhY2U1ZjMzODc5MjZjY2YyYTdmZDRmYzhmMCIsInJhdyI6IjE1M2JiM2VhYWFjNjc2NTM4NDc2OGQyODk0MTE3YzdiMGZhOWJkZWE2YWUxZjg4OWJlYTZiYWI3M2JlZDI4NDgiLCJidWlsdF9hdCI6IjIwMjYtMDEtMTVUMDM6MjU6MzlaIn0sImNvbmZpZyI6ImMyaHBiUzEyWlhKemFXOXVPaUIyTUM0ekxqRXdRSE5vWVRJMU5qbzRNalZqWm1GbVltTTJaR1JsT0RrMk4yRmpOakJsTkRReU5qUm1ORFk0Tm1aalpqSmxaRE16Wm1GbE1URXlZV0kwWWpGak5qbGpOalkzTTJOa1l6aGxDbU4yYlMxMlpYSnphVzl1T2lBd0xqVXVNVFlLWTNCMWN6b2dPQXB0WlcxdmNuazZJREUyTXpnMENncHphR2x0T2dvZ0lHeHBjM1JsYmkxd2IzSjBPaUEwTkRNS0lDQjFjSE4wY21WaGJTMXdiM0owT2lBNE1EZzVDZ3BqYjI1MFlXbHVaWEp6T2dvZ0lDMGdibUZ0WlRvZ0luQnliM2g1SWdvZ0lDQWdhVzFoWjJVNklDSWlDaUFnSUNCaGNtZHpPaUJiQ2lBZ0lDQWdJQ0puYUdOeUxtbHZMM1JwYm1admFXeHphQzlqYjI1bWFXUmxiblJwWVd3dGJXOWtaV3d0Y205MWRHVnlPakF1TUM0ek9DSXNDaUFnSUNBZ0lDSXRaQ0lzSWlRb1lYZHJJQzFHSnpvZ0tpY2dKeVF4Zmk5ZVpHOXRZV2x1SkM5N2NISnBiblFnSkRJN0lHVjRhWFI5SnlBdmJXNTBMM0poYldScGMyc3ZaWGgwWlhKdVlXd3RZMjl1Wm1sbkxubHRiQ2tpTEFvZ0lDQWdYUW89In19","payloadType":"application/vnd.in-toto+json","signatures":[{"sig":"MEUCIQCftn0lH/E5TmPYMXLbm1hhRDP4AepXklL7atUoDuQqegIgRwxHP/+UWI1UNnNA1/Z5DkBmPl1Q7XpAOAhX+z916uA="}]}};
13
+ const ROOT = {"mediaType":"application/vnd.dev.sigstore.trustedroot+json;version=0.1","tlogs":[{"baseUrl":"https://rekor.sigstore.dev","hashAlgorithm":"SHA2_256","publicKey":{"rawBytes":"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE2G2Y+2tabdTV5BcGiBIx0a9fAFwrkBbmLSGtks4L3qX6yYY0zufBnhC8Ur/iy55GhWP/9A/bY2LhC30M9+RYtw==","keyDetails":"PKIX_ECDSA_P256_SHA_256","validFor":{"start":"2021-01-12T11:53:27Z"}},"logId":{"keyId":"wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="}},{"baseUrl":"https://log2025-1.rekor.sigstore.dev","hashAlgorithm":"SHA2_256","publicKey":{"rawBytes":"MCowBQYDK2VwAyEAt8rlp1knGwjfbcXAYPYAkn0XiLz1x8O4t0YkEhie244=","keyDetails":"PKIX_ED25519","validFor":{"start":"2025-09-23T00:00:00Z"}},"logId":{"keyId":"zxGZFVvd0FEmjR8WrFwMdcAJ9vtaY/QXf44Y1wUeP6A="}}],"certificateAuthorities":[{"subject":{"organization":"sigstore.dev","commonName":"sigstore"},"uri":"https://fulcio.sigstore.dev","certChain":{"certificates":[{"rawBytes":"MIIB+DCCAX6gAwIBAgITNVkDZoCiofPDsy7dfm6geLbuhzAKBggqhkjOPQQDAzAqMRUwEwYDVQQKEwxzaWdzdG9yZS5kZXYxETAPBgNVBAMTCHNpZ3N0b3JlMB4XDTIxMDMwNzAzMjAyOVoXDTMxMDIyMzAzMjAyOVowKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTB2MBAGByqGSM49AgEGBSuBBAAiA2IABLSyA7Ii5k+pNO8ZEWY0ylemWDowOkNa3kL+GZE5Z5GWehL9/A9bRNA3RbrsZ5i0JcastaRL7Sp5fp/jD5dxqc/UdTVnlvS16an+2Yfswe/QuLolRUCrcOE2+2iA5+tzd6NmMGQwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwHQYDVR0OBBYEFMjFHQBBmiQpMlEk6w2uSu1KBtPsMB8GA1UdIwQYMBaAFMjFHQBBmiQpMlEk6w2uSu1KBtPsMAoGCCqGSM49BAMDA2gAMGUCMH8liWJfMui6vXXBhjDgY4MwslmN/TJxVe/83WrFomwmNf056y1X48F9c4m3a3ozXAIxAKjRay5/aj/jsKKGIkmQatjI8uupHr/+CxFvaJWmpYqNkLDGRU+9orzh5hI2RrcuaQ=="}]},"validFor":{"start":"2021-03-07T03:20:29Z","end":"2022-12-31T23:59:59.999Z"}},{"subject":{"organization":"sigstore.dev","commonName":"sigstore"},"uri":"https://fulcio.sigstore.dev","certChain":{"certificates":[{"rawBytes":"MIICGjCCAaGgAwIBAgIUALnViVfnU0brJasmRkHrn/UnfaQwCgYIKoZIzj0EAwMwKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0yMjA0MTMyMDA2MTVaFw0zMTEwMDUxMzU2NThaMDcxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjEeMBwGA1UEAxMVc2lnc3RvcmUtaW50ZXJtZWRpYXRlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE8RVS/ysH+NOvuDZyPIZtilgUF9NlarYpAd9HP1vBBH1U5CV77LSS7s0ZiH4nE7Hv7ptS6LvvR/STk798LVgMzLlJ4HeIfF3tHSaexLcYpSASr1kS0N/RgBJz/9jWCiXno3sweTAOBgNVHQ8BAf8EBAMCAQYwEwYDVR0lBAwwCgYIKwYBBQUHAwMwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQU39Ppz1YkEZb5qNjpKFWixi4YZD8wHwYDVR0jBBgwFoAUWMAeX5FFpWapesyQoZMi0CrFxfowCgYIKoZIzj0EAwMDZwAwZAIwPCsQK4DYiZYDPIaDi5HFKnfxXx6ASSVmERfsynYBiX2X6SJRnZU84/9DZdnFvvxmAjBOt6QpBlc4J/0DxvkTCqpclvziL6BCCPnjdlIB3Pu3BxsPmygUY7Ii2zbdCdliiow="},{"rawBytes":"MIIB9zCCAXygAwIBAgIUALZNAPFdxHPwjeDloDwyYChAO/4wCgYIKoZIzj0EAwMwKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0yMTEwMDcxMzU2NTlaFw0zMTEwMDUxMzU2NThaMCoxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjERMA8GA1UEAxMIc2lnc3RvcmUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAT7XeFT4rb3PQGwS4IajtLk3/OlnpgangaBclYpsYBr5i+4ynB07ceb3LP0OIOZdxexX69c5iVuyJRQ+Hz05yi+UF3uBWAlHpiS5sh0+H2GHE7SXrk1EC5m1Tr19L9gg92jYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRYwB5fkUWlZql6zJChkyLQKsXF+jAfBgNVHSMEGDAWgBRYwB5fkUWlZql6zJChkyLQKsXF+jAKBggqhkjOPQQDAwNpADBmAjEAj1nHeXZp+13NWBNa+EDsDP8G1WWg1tCMWP/WHPqpaVo0jhsweNFZgSs0eE7wYI4qAjEA2WB9ot98sIkoF3vZYdd3/VtWB5b9TNMea7Ix/stJ5TfcLLeABLE4BNJOsQ4vnBHJ"}]},"validFor":{"start":"2022-04-13T20:06:15Z"}}],"ctlogs":[{"baseUrl":"https://ctfe.sigstore.dev/test","hashAlgorithm":"SHA2_256","publicKey":{"rawBytes":"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEbfwR+RJudXscgRBRpKX1XFDy3PyudDxz/SfnRi1fT8ekpfBd2O1uoz7jr3Z8nKzxA69EUQ+eFCFI3zeubPWU7w==","keyDetails":"PKIX_ECDSA_P256_SHA_256","validFor":{"start":"2021-03-14T00:00:00Z","end":"2022-10-31T23:59:59.999Z"}},"logId":{"keyId":"CGCS8ChS/2hF0dFrJ4ScRWcYrBY9wzjSbea8IgY2b3I="}},{"baseUrl":"https://ctfe.sigstore.dev/2022","hashAlgorithm":"SHA2_256","publicKey":{"rawBytes":"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEiPSlFi0CmFTfEjCUqF9HuCEcYXNKAaYalIJmBZ8yyezPjTqhxrKBpMnaocVtLJBI1eM3uXnQzQGAJdJ4gs9Fyw==","keyDetails":"PKIX_ECDSA_P256_SHA_256","validFor":{"start":"2022-10-20T00:00:00Z"}},"logId":{"keyId":"3T0wasbHETJjGR4cmWc3AqJKXrjePK3/h4pygC8p7o4="}}],"timestampAuthorities":[{"subject":{"organization":"sigstore.dev","commonName":"sigstore-tsa-selfsigned"},"uri":"https://timestamp.sigstore.dev/api/v1/timestamp","certChain":{"certificates":[{"rawBytes":"MIICEDCCAZagAwIBAgIUOhNULwyQYe68wUMvy4qOiyojiwwwCgYIKoZIzj0EAwMwOTEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MSAwHgYDVQQDExdzaWdzdG9yZS10c2Etc2VsZnNpZ25lZDAeFw0yNTA0MDgwNjU5NDNaFw0zNTA0MDYwNjU5NDNaMC4xFTATBgNVBAoTDHNpZ3N0b3JlLmRldjEVMBMGA1UEAxMMc2lnc3RvcmUtdHNhMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE4ra2Z8hKNig2T9kFjCAToGG30jky+WQv3BzL+mKvh1SKNR/UwuwsfNCg4sryoYAd8E6isovVA3M4aoNdm9QDi50Z8nTEyvqgfDPtTIwXItfiW/AFf1V7uwkbkAoj0xxco2owaDAOBgNVHQ8BAf8EBAMCB4AwHQYDVR0OBBYEFIn9eUOHz9BlRsMCRscsc1t9tOsDMB8GA1UdIwQYMBaAFJjsAe9/u1H/1JUeb4qImFMHic6/MBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMAoGCCqGSM49BAMDA2gAMGUCMDtpsV/6KaO0qyF/UMsX2aSUXKQFdoGTptQGc0ftq1csulHPGG6dsmyMNd3JB+G3EQIxAOajvBcjpJmKb4Nv+2Taoj8Uc5+b6ih6FXCCKraSqupe07zqswMcXJTe1cExvHvvlw=="},{"rawBytes":"MIIB9zCCAXygAwIBAgIUV7f0GLDOoEzIh8LXSW80OJiUp14wCgYIKoZIzj0EAwMwOTEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MSAwHgYDVQQDExdzaWdzdG9yZS10c2Etc2VsZnNpZ25lZDAeFw0yNTA0MDgwNjU5NDNaFw0zNTA0MDYwNjU5NDNaMDkxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjEgMB4GA1UEAxMXc2lnc3RvcmUtdHNhLXNlbGZzaWduZWQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQUQNtfRT/ou3YATa6wB/kKTe70cfJwyRIBovMnt8RcJph/COE82uyS6FmppLLL1VBPGcPfpQPYJNXzWwi8icwhKQ6W/Qe2h3oebBb2FHpwNJDqo+TMaC/tdfkv/ElJB72jRTBDMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBSY7AHvf7tR/9SVHm+KiJhTB4nOvzAKBggqhkjOPQQDAwNpADBmAjEAwGEGrfGZR1cen1R8/DTVMI943LssZmJRtDp/i7SfGHmGRP6gRbuj9vOK3b67Z0QQAjEAuT2H673LQEaHTcyQSZrkp4mX7WwkmF+sVbkYY5mXN+RMH13KUEHHOqASaemYWK/E"}]},"validFor":{"start":"2025-07-04T00:00:00Z"}}]};