@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.
- package/.github/workflows/conformance.yml +1 -1
- package/.github/workflows/publish.yml +1 -1
- package/README.md +20 -16
- package/dist/bundle.d.ts +2 -0
- package/dist/bundle.d.ts.map +1 -1
- package/dist/bundle.js +66 -1
- package/dist/bundle.js.map +1 -1
- package/dist/interfaces.d.ts +17 -2
- package/dist/interfaces.d.ts.map +1 -1
- package/dist/interfaces.js +14 -0
- package/dist/interfaces.js.map +1 -1
- package/dist/policy.d.ts +3 -3
- package/dist/policy.d.ts.map +1 -1
- package/dist/policy.js +4 -4
- package/dist/policy.js.map +1 -1
- package/dist/sigstore.d.ts +8 -17
- package/dist/sigstore.d.ts.map +1 -1
- package/dist/sigstore.js +159 -392
- package/dist/sigstore.js.map +1 -1
- package/dist/timestamp/tsa.d.ts +6 -2
- package/dist/timestamp/tsa.d.ts.map +1 -1
- package/dist/timestamp/tsa.js +15 -18
- package/dist/timestamp/tsa.js.map +1 -1
- package/dist/tlog/body.d.ts +3 -1
- package/dist/tlog/body.d.ts.map +1 -1
- package/dist/tlog/body.js +18 -5
- package/dist/tlog/body.js.map +1 -1
- package/dist/tlog/checkpoint.d.ts +2 -2
- package/dist/tlog/checkpoint.d.ts.map +1 -1
- package/dist/tlog/checkpoint.js +17 -95
- package/dist/tlog/checkpoint.js.map +1 -1
- package/dist/tlog/dsse.d.ts +3 -2
- package/dist/tlog/dsse.d.ts.map +1 -1
- package/dist/tlog/dsse.js +8 -5
- package/dist/tlog/dsse.js.map +1 -1
- package/dist/tlog/hashedrekord.d.ts +3 -2
- package/dist/tlog/hashedrekord.d.ts.map +1 -1
- package/dist/tlog/hashedrekord.js +8 -5
- package/dist/tlog/hashedrekord.js.map +1 -1
- package/dist/tlog/intoto.d.ts +3 -2
- package/dist/tlog/intoto.d.ts.map +1 -1
- package/dist/tlog/intoto.js +3 -1
- package/dist/tlog/intoto.js.map +1 -1
- package/package.json +2 -2
- package/src/bundle.ts +87 -0
- package/src/ed25519.browser.test.ts +76 -0
- package/src/index.browser.test.ts +38 -27
- package/src/interfaces.ts +29 -2
- package/src/policy.ts +5 -5
- package/src/security.browser.test.ts +249 -0
- package/src/sigstore.ts +191 -534
- package/src/timestamp/tsa.ts +29 -28
- package/src/tlog/body.ts +24 -5
- package/src/tlog/checkpoint.ts +22 -122
- package/src/tlog/dsse.ts +12 -6
- package/src/tlog/hashedrekord.ts +14 -8
- package/src/tlog/intoto.ts +5 -2
- package/src/verify.browser.test.ts +281 -0
- package/test/fixtures/rekor2.ts +14 -0
- 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"}}]};
|