Some checks failed
LNM Migration CI / build-runner (push) Has been cancelled
Ledger OpenAPI CI / deprecation-check (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
Airgap Sealed CI Smoke / sealed-smoke (push) Has been cancelled
Ledger Packs CI / build-pack (push) Has been cancelled
Export Center CI / export-ci (push) Has been cancelled
Ledger OpenAPI CI / validate-oas (push) Has been cancelled
Ledger OpenAPI CI / check-wellknown (push) Has been cancelled
Ledger Packs CI / verify-pack (push) Has been cancelled
LNM Migration CI / validate-metrics (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
74 lines
3.5 KiB
Bash
74 lines
3.5 KiB
Bash
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
ROOT="$(cd "$(dirname "$0")" && pwd)"
|
|
MODULE_ROOT="${ROOT}/.."
|
|
cd "$MODULE_ROOT"
|
|
export MODULE_ROOT
|
|
|
|
command -v sha256sum >/dev/null || { echo "sha256sum required" >&2; exit 1; }
|
|
command -v python >/dev/null || { echo "python required" >&2; exit 1; }
|
|
|
|
sha256sum --check SHA256SUMS
|
|
|
|
python - <<'PY'
|
|
import base64, json, os, sys
|
|
from pathlib import Path
|
|
|
|
try:
|
|
from cryptography.hazmat.primitives.asymmetric import ed25519
|
|
except Exception as exc:
|
|
raise SystemExit(f"cryptography package required for DSSE verification: {exc}")
|
|
|
|
root = Path(os.environ['MODULE_ROOT']).resolve()
|
|
pub_b64 = (root / "kit" / "ed25519.pub").read_text().strip()
|
|
pub = base64.urlsafe_b64decode(pub_b64 + "==")
|
|
verifier = ed25519.Ed25519PublicKey.from_public_bytes(pub)
|
|
|
|
def pae(payload_type: bytes, payload: bytes) -> bytes:
|
|
parts = [b"DSSEv1", str(len(payload_type)).encode(), payload_type, str(len(payload)).encode(), payload]
|
|
return b" ".join(parts)
|
|
|
|
def verify(name: str, payload_path: Path, envelope_path: Path, payload_type: str):
|
|
payload = payload_path.read_bytes()
|
|
envelope = json.loads(envelope_path.read_text())
|
|
if envelope.get("payloadType") != payload_type:
|
|
raise SystemExit(f"{name}: payloadType mismatch ({envelope.get('payloadType')} != {payload_type})")
|
|
if not envelope.get("signatures"):
|
|
raise SystemExit(f"{name}: missing signatures")
|
|
sig_entry = envelope["signatures"][0]
|
|
sig = base64.urlsafe_b64decode(sig_entry["sig"] + "==")
|
|
decoded_payload = base64.urlsafe_b64decode(envelope["payload"] + "==")
|
|
if decoded_payload != payload:
|
|
raise SystemExit(f"{name}: payload body mismatch vs envelope")
|
|
verifier.verify(sig, pae(payload_type.encode(), payload))
|
|
print(f"OK: {name}")
|
|
|
|
targets = [
|
|
("observer schema", root / "schemas" / "observer_event.schema.json", root / "schemas" / "observer_event.schema.json.dsse", "application/vnd.stellaops.zastava.schema+json;name=observer_event;version=1"),
|
|
("webhook schema", root / "schemas" / "webhook_admission.schema.json", root / "schemas" / "webhook_admission.schema.json.dsse", "application/vnd.stellaops.zastava.schema+json;name=webhook_admission;version=1"),
|
|
("thresholds", root / "thresholds.yaml", root / "thresholds.yaml.dsse", "application/vnd.stellaops.zastava.thresholds+yaml;version=1"),
|
|
("observer exports", root / "exports" / "observer_events.ndjson", root / "exports" / "observer_events.ndjson.dsse", "application/vnd.stellaops.zastava.observer-events+ndjson;version=1"),
|
|
("webhook exports", root / "exports" / "webhook_admissions.ndjson", root / "exports" / "webhook_admissions.ndjson.dsse", "application/vnd.stellaops.zastava.webhook-admissions+ndjson;version=1"),
|
|
]
|
|
|
|
# Combined runtime format (optional - may not exist in all kits)
|
|
combined_targets = [
|
|
("combined runtime", root / "exports" / "combined.runtime.ndjson", root / "exports" / "combined.runtime.ndjson.dsse", "application/vnd.stellaops.combined.runtime+ndjson;version=1"),
|
|
]
|
|
|
|
for name, payload_path, envelope_path, ptype in targets:
|
|
verify(name, payload_path, envelope_path, ptype)
|
|
|
|
# Verify combined format if present
|
|
for name, payload_path, envelope_path, ptype in combined_targets:
|
|
if payload_path.exists() and envelope_path.exists():
|
|
verify(name, payload_path, envelope_path, ptype)
|
|
elif payload_path.exists() or envelope_path.exists():
|
|
print(f"WARNING: {name} - incomplete (payload and envelope must both exist)")
|
|
else:
|
|
print(f"SKIP: {name} (not present)")
|
|
PY
|
|
|
|
echo "OK: SHA256 + DSSE signatures verified"
|