Some checks failed
Deploy to Phoenix / deploy (push) Has been cancelled
- Add OMNL/CBK Indonesia submission and audit binder docs, manifests, attestations - Add scripts/omnl transaction-package pipeline, LEI/PvP helpers, jq/lib fixtures - Update entity master data, MASTER_INDEX, TODOS, dbis-rail docs and rulebook - Add proof_package/regulatory skeleton and transaction package zip + snapshot JSON - validate-omnl-rail workflow, forge-verification-proxy tweak, .gitignore hygiene - Bump smom-dbis-138 (cronos verify docs/scripts) and explorer-monorepo (SPA + env report) Made-with: Cursor
89 lines
2.7 KiB
Python
Executable File
89 lines
2.7 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
"""Recompute content commitment vs 00_Cover/HASH_NOTARIZATION_ANCHOR.txt (matches build-transaction-package-zip.sh)."""
|
|
from __future__ import annotations
|
|
|
|
import hashlib
|
|
import os
|
|
import re
|
|
import sys
|
|
|
|
EXCLUDED_EXACT = frozenset(
|
|
{
|
|
"./00_Cover/HASH_NOTARIZATION_ANCHOR.txt",
|
|
"./00_Cover/audit_and_hashes.txt",
|
|
"./00_Cover/audit_manifest.json",
|
|
}
|
|
)
|
|
EXCLUDED_BASENAMES = frozenset(
|
|
{
|
|
"TSA_RFC3161_REQUEST.tsq",
|
|
"TSA_RFC3161_RESPONSE.tsr",
|
|
"TSA_RFC3161_RESPONSE.txt",
|
|
"TSA_RFC3161_VERIFY.txt",
|
|
"QES_CMS_ANCHOR_DETACHED.p7s",
|
|
"QES_CMS_VERIFY_LOG.txt",
|
|
}
|
|
)
|
|
|
|
|
|
def posix_rel(package_root: str, full_path: str) -> str:
|
|
rel = os.path.relpath(full_path, package_root).replace(os.sep, "/")
|
|
return rel if rel.startswith("./") else "./" + rel
|
|
|
|
|
|
def excluded(rel_posix: str) -> bool:
|
|
if rel_posix in EXCLUDED_EXACT:
|
|
return True
|
|
return os.path.basename(rel_posix) in EXCLUDED_BASENAMES
|
|
|
|
|
|
def recompute(package_root: str) -> str:
|
|
lines: list[str] = []
|
|
for dirpath, dirnames, filenames in os.walk(package_root):
|
|
dirnames.sort()
|
|
filenames.sort()
|
|
for fn in filenames:
|
|
if fn == ".DS_Store":
|
|
continue
|
|
full = os.path.join(dirpath, fn)
|
|
if not os.path.isfile(full):
|
|
continue
|
|
rel = posix_rel(package_root, full)
|
|
if excluded(rel):
|
|
continue
|
|
h = hashlib.sha256()
|
|
with open(full, "rb") as f:
|
|
for chunk in iter(lambda: f.read(1 << 20), b""):
|
|
h.update(chunk)
|
|
lines.append(f"{h.hexdigest().lower()}\t{rel}")
|
|
lines.sort(key=lambda s: s.encode("utf-8"))
|
|
return hashlib.sha256(("\n".join(lines) + "\n").encode("utf-8")).hexdigest().lower()
|
|
|
|
|
|
def main() -> int:
|
|
if len(sys.argv) != 2:
|
|
print("Usage: verify-transaction-package-commitment.py <unzipped-root>", file=sys.stderr)
|
|
return 2
|
|
root = os.path.abspath(sys.argv[1])
|
|
anchor = os.path.join(root, "00_Cover", "HASH_NOTARIZATION_ANCHOR.txt")
|
|
if not os.path.isfile(anchor):
|
|
print(f"ERROR: missing {anchor}", file=sys.stderr)
|
|
return 1
|
|
text = open(anchor, encoding="utf-8").read()
|
|
m = re.search(r"CONTENT COMMITMENT \(SHA-256, hex\):\s*([0-9a-fA-F]{64})", text)
|
|
if not m:
|
|
print("ERROR: bad anchor", file=sys.stderr)
|
|
return 1
|
|
exp = m.group(1).lower()
|
|
got = recompute(root)
|
|
if exp != got:
|
|
print(f"MISMATCH anchor={exp}\n actual={got}", file=sys.stderr)
|
|
return 1
|
|
print(f"OK: {got}")
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|