CaseLedger Public Verification Specification.
This specification lets reviewers verify a CaseLedger
.evidencebundle
without using the paid recorder and without uploading confidential files.
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.
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.jsonpublic-evidence-identity.jsonVERIFY-THIS-EVIDENCE.mdverification-report.jsonaudit-session.jsonlwhen audit logging was enabled- RFC 3161 timestamp request/response files when timestamping was enabled
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.
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.
- Decode the JSON manifest.
- Clear the
signaturefield. - Re-encode UTF-8 JSON using sorted keys and pretty printing.
- Verify the DER/base64 ECDSA P-256 signature with
signingPublicKey.
Bundle Manifest Signature
- Decode
bundle-manifest.json. - Confirm
schemaVersionis3or newer. - Confirm
signingPublicKeymatches the recording manifest signer. - Clear the bundle manifest
signaturefield. - Re-encode UTF-8 JSON using sorted keys and pretty printing.
- Verify the DER/base64 ECDSA P-256 signature.
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.
Bundle Content Seal
Schema 3 bundles include bundleContentSHA256, a signed seal over the inventory.
- Sort
fileInventoryrecords byfileNameusing bytewise ascending string order. - For each record, emit one row:
<fileName>\t<fileSizeBytes>\t<sha256-lowercase>
- Join rows with a single newline character.
- Hash the UTF-8 bytes with SHA-256 lowercase hex.
- Compare the result to
bundleContentSHA256.
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.
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.
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.
Result Rules
All required files, hashes, signatures, signer match, public identity, inventory, content seal, and audit checks pass.
Optional or contextual checks need human review.
Any required file, hash, signature, signer match, audit chain, or content seal check fails.