← Back to Verify
Specification · Public Reference

CaseLedger Public Verification Specification.

Version 1.0 · Bundle schema 3 · Draft for CaseLedger 1.0

This specification lets reviewers verify a CaseLedger .evidencebundle without using the paid recorder and without uploading confidential files.

§ I

Verification Goals

  • The MP4 bytes match the signed recording manifest.
  • The recording manifest signature verifies with the included public key.
  • The bundle manifest is signed by the same public key.
  • The bundle inventory and signed content seal match the files present.
  • The audit sidecar, when present, has an intact hash chain and valid entry signatures.
  • Timestamp sidecars and tokens, when present, match the signed manifest hashes and RFC 3161 token data.
§ II

Bundle Layout

A schema 3 evidence bundle is a macOS package folder ending in .evidencebundle. It normally contains:

  • bundle-manifest.json
  • the recording file, usually .mp4
  • <recording>.manifest.json
  • public-evidence-identity.json
  • VERIFY-THIS-EVIDENCE.md
  • verification-report.json
  • audit-session.jsonl when audit logging was enabled
  • RFC 3161 timestamp request/response files when timestamping was enabled
§ III

Hashing Rules

All file hashes are SHA-256 over the exact file bytes, encoded as lowercase hexadecimal. Verification tools should stream file reads and fail closed on read errors.

§ IV

Recording Manifest Signature

The recording manifest signature uses ECDSA P-256 over SHA-256. The signature is DER encoded and then base64 encoded. The public key is the P-256 raw representation encoded as base64.

  1. Decode the JSON manifest.
  2. Clear the signature field.
  3. Re-encode UTF-8 JSON using sorted keys and pretty printing.
  4. Verify the DER/base64 ECDSA P-256 signature with signingPublicKey.
§ V

Bundle Manifest Signature

  1. Decode bundle-manifest.json.
  2. Confirm schemaVersion is 3 or newer.
  3. Confirm signingPublicKey matches the recording manifest signer.
  4. Clear the bundle manifest signature field.
  5. Re-encode UTF-8 JSON using sorted keys and pretty printing.
  6. Verify the DER/base64 ECDSA P-256 signature.
§ VI

File Inventory

For each fileInventory record, confirm the file exists in the bundle root, compute its file size and SHA-256, then compare both values. bundle-manifest.json is excluded from the inventory because it contains the signature over the inventory.

§ VII

Bundle Content Seal

Schema 3 bundles include bundleContentSHA256, a signed seal over the inventory.

  1. Sort fileInventory records by fileName using bytewise ascending string order.
  2. For each record, emit one row:
<fileName>\t<fileSizeBytes>\t<sha256-lowercase>
  1. Join rows with a single newline character.
  2. Hash the UTF-8 bytes with SHA-256 lowercase hex.
  3. Compare the result to bundleContentSHA256.
§ VIII

Audit Sidecar

audit-session.jsonl contains one JSON audit entry per line. Each entry hash is computed from:

<timestamp>
<sessionIdentifier>
<eventType>
<details sorted as key=value and joined by |>
<previousHash or empty string>

Each entry signature is verified by clearing its signature field, re-encoding JSON with sorted keys, and checking the ECDSA P-256 signature.

§ IX

External Timestamping

When present, CaseLedger stores RFC 3161 timestamp request and response sidecars and records their hashes in the signed manifest. The verifier checks token structure, message imprint, nonce when available, and Apple's timestamping certificate policy.

§ X

Local File Locks

CaseLedger can mark finalized local evidence files read-only and user-immutable on the recording Mac. File locks are useful local tamper friction, but signed hashes, signatures, audit chain, and the content seal are the portable checks.

§ XI

Result Rules

Verified

All required files, hashes, signatures, signer match, public identity, inventory, content seal, and audit checks pass.

Needs Review

Optional or contextual checks need human review.

Failed

Any required file, hash, signature, signer match, audit chain, or content seal check fails.