|
1 | 1 | import { describe, it, expect } from "vitest"; |
2 | | -import { SigstoreVerifier } from "./sigstore.js"; |
| 2 | +import { SigstoreVerifier, assertRekorV2Timestamp } from "./sigstore.js"; |
3 | 3 | import { X509Certificate } from "./x509/cert.js"; |
4 | 4 |
|
5 | 5 | describe("Sigstore Browser Integration Tests", () => { |
@@ -254,3 +254,37 @@ ewS+2T7Qz4oXaQMidPOjr1Q8WKqaKO4yCtC8cz4qVWi3lNqAcAGtonQMXUiflEWV |
254 | 254 | expect(parsed.verificationMaterial.tlogEntries[0].logIndex).toBe("123"); |
255 | 255 | }); |
256 | 256 | }); |
| 257 | + |
| 258 | +describe("Rekor v2 observer-timestamp enforcement", () => { |
| 259 | + // Regression test: a Rekor-v2-shaped bundle (no integratedTime in the tlog |
| 260 | + // entry) must carry a signed RFC3161 timestamp. A previous guard only checked |
| 261 | + // that `timestampVerificationData` was present, which an empty object ({}) |
| 262 | + // satisfies in JavaScript — letting a crafted bundle pass verification with |
| 263 | + // zero verified timestamps and the signing certificate's validity window left |
| 264 | + // completely unanchored in time. |
| 265 | + |
| 266 | + it("rejects a missing timestampVerificationData", () => { |
| 267 | + expect(() => assertRekorV2Timestamp(undefined)).toThrow( |
| 268 | + "Rekor v2 bundles require a timestamp for verification.", |
| 269 | + ); |
| 270 | + }); |
| 271 | + |
| 272 | + it("rejects an empty timestampVerificationData object ({})", () => { |
| 273 | + // This is the exact bypass the fix closes: {} is truthy. |
| 274 | + expect(() => assertRekorV2Timestamp({})).toThrow( |
| 275 | + "Rekor v2 bundles require a timestamp for verification.", |
| 276 | + ); |
| 277 | + }); |
| 278 | + |
| 279 | + it("rejects timestampVerificationData with an empty rfc3161Timestamps array", () => { |
| 280 | + expect(() => |
| 281 | + assertRekorV2Timestamp({ rfc3161Timestamps: [] }), |
| 282 | + ).toThrow("Rekor v2 bundles require a timestamp for verification."); |
| 283 | + }); |
| 284 | + |
| 285 | + it("accepts timestampVerificationData with at least one RFC3161 timestamp", () => { |
| 286 | + expect(() => |
| 287 | + assertRekorV2Timestamp({ rfc3161Timestamps: [{ signedTimestamp: "…" }] }), |
| 288 | + ).not.toThrow(); |
| 289 | + }); |
| 290 | +}); |
0 commit comments