# ProofSnap evidence verifier (Windows PowerShell)
# Run from the package root:   powershell -ExecutionPolicy Bypass -File verification\verify.ps1
# Requires: PowerShell 5+, openssl in PATH (for the signature step).
$ErrorActionPreference = "Stop"
# Resolve the package root = the parent of this script's directory.
Set-Location -Path (Split-Path -Parent $PSScriptRoot)
$fail = 0

Write-Host "============================================================"
Write-Host " ProofSnap Evidence Verification"
Write-Host "============================================================"

Write-Host ""
Write-Host "[1/5] File integrity - SHA-256 of every file vs manifest.json"
Write-Host "------------------------------------------------------------"
$manifest = Get-Content -Raw manifest.json | ConvertFrom-Json
$allOk = $true
foreach ($prop in $manifest.PSObject.Properties) {
  $name = $prop.Name
  if ($name -eq "evidence_id" -or $name -eq "manifest.json") { continue }
  if (-not (Test-Path -LiteralPath $name)) {
    Write-Host "  MISSING  $name"; $allOk = $false; continue
  }
  $actual = (Get-FileHash -LiteralPath $name -Algorithm SHA256).Hash.ToLower()
  if ($actual -eq $prop.Value.ToLower()) {
    Write-Host "  OK       $name"
  } else {
    Write-Host "  MISMATCH $name"; $allOk = $false
  }
}
Write-Host ""
if ($allOk) { Write-Host "  RESULT: all files match" } else { Write-Host "  RESULT: ONE OR MORE FILES FAILED"; $fail = 1 }

Write-Host ""
Write-Host "[2/5] Manifest signature - RSA over manifest.json"
Write-Host "------------------------------------------------------------"
try {
  & openssl dgst -sha256 -verify publickey.pem -signature manifest.sig manifest.json
  if ($LASTEXITCODE -eq 0) { Write-Host "  Signature OK - manifest.json is authentic and untampered" }
  else { Write-Host "  Signature FAILED"; $fail = 1 }
} catch {
  Write-Host "  openssl not available - run: openssl dgst -sha256 -verify publickey.pem -signature manifest.sig manifest.json"
}

Write-Host ""
Write-Host "[3/5] Forensic hash chain - recompute over forensic_log.json"
Write-Host "------------------------------------------------------------"
if (Test-Path forensic_log.json) {
  $pyExe = (Get-Command python3 -ErrorAction SilentlyContinue)
  if (-not $pyExe) { $pyExe = (Get-Command python -ErrorAction SilentlyContinue) }
  if ($pyExe) {
    $chainSrc = @'
import json, hashlib, os, sys
root = sys.argv[1]
def sha(s):
    return hashlib.sha256(s.encode("utf-8")).hexdigest()
log = json.load(open(os.path.join(root, "forensic_log.json")))
try:
    coc = json.load(open(os.path.join(root, "chain_of_custody.json")))
except Exception:
    coc = {}
hc = log.get("hash_chain", {}) or {}
genesis = hc.get("genesis_hash")
ops = log.get("operations", []) or []
ORDER = ["operation_id","operation_type","sequence_number","timestamp_local","timestamp_ntp","ntp_offset_ms","duration_ms","result","hash_before","hash_after","details","error_message"]
def entry_hash(op):
    obj = {}
    for k in ORDER:
        if k in op:
            obj[k] = op[k]
    return sha(json.dumps(obj, separators=(",", ":"), ensure_ascii=False))
ok = True
prev = genesis
cumulative = genesis
for i, op in enumerate(ops):
    seq = op.get("sequence_number")
    if op.get("previous_entry_hash") != prev:
        print("  CHAIN BREAK at op #%d (seq %s): previous_entry_hash mismatch" % (i + 1, seq)); ok = False
    eh = entry_hash(op)
    cumulative = sha(cumulative + eh)
    if op.get("cumulative_hash") != cumulative:
        print("  CHAIN BREAK at op #%d (seq %s): cumulative_hash mismatch" % (i + 1, seq)); ok = False
    prev = eh
print("")
if cumulative == hc.get("final_hash"):
    print("  Final hash matches forensic_log.hash_chain.final_hash")
else:
    print("  Final hash does NOT match forensic_log.hash_chain.final_hash"); ok = False
coc_final = coc.get("forensic_log_final_chain_hash")
if coc_final is None and isinstance(coc.get("integrity"), dict):
    coc_final = coc["integrity"].get("forensic_log_final_chain_hash")
if coc_final is not None:
    if cumulative == coc_final:
        print("  Final hash matches chain_of_custody.forensic_log_final_chain_hash")
    else:
        print("  Final hash does NOT match chain_of_custody reference"); ok = False
print("")
print("  RESULT: " + ("hash chain intact (%d operations)" % len(ops) if ok else "HASH CHAIN FAILED"))
sys.exit(0 if ok else 1)
'@
    $chainSrc | & $pyExe.Source - "$($PWD.Path)"
    if ($LASTEXITCODE -ne 0) { $fail = 1 }
  } else {
    Write-Host "  python not found - deep chain check skipped. Run verify.sh or verify online."
  }
} else { Write-Host "  forensic_log.json not present - skipped." }

Write-Host ""
Write-Host "[4/5] eIDAS RFC 3161 qualified timestamp"
Write-Host "------------------------------------------------------------"
if (Test-Path manifest.json.tsr) {
  Write-Host "  manifest.json.tsr present. Deep verify (needs the TSA root cert):"
  Write-Host "    openssl ts -verify -in manifest.json.tsr -data manifest.json -CAfile <tsa-root>.pem"
  Write-Host "  Certificate chain + OCSP/CRL are in eidas_validation.json."
} else { Write-Host "  Not present (package was not eIDAS-stamped)." }

Write-Host ""
Write-Host "[5/5] Bitcoin OpenTimestamps anchor"
Write-Host "------------------------------------------------------------"
if (Test-Path manifest.json.ots) {
  Write-Host "  manifest.json.ots present. Deep verify (needs the ots client):"
  Write-Host "    ots verify manifest.json.ots -f manifest.json"
} else { Write-Host "  Not present (package was not OTS-stamped)." }

Write-Host ""
Write-Host "============================================================"
if ($fail -eq 0) { Write-Host " RESULT: PASS - integrity and signature verified." }
else { Write-Host " RESULT: FAIL - see the failed step(s) above." }
Write-Host "============================================================"
exit $fail
