Dogfood cryptography: pacta verifies signatures through the PROVEN code path

"Eat your own dogfood": pacta consumes certificates about a verified
Ed25519 implementation while checking those certificates' signatures
with OpenSSL. Now it can use the object of its own evidence:

- dogfood/pacta-verified-verify: a ~90-line Rust binary built against
  the PINNED proven source workspace (saymrwulf/curve25519-dalek-source
  at the exact commit the dalek certificates pin - the build records it:
  aa0f6ab...) with the serial backend pinned via RUSTFLAGS exactly as
  the verified extraction pins it. Cargo.toml is committed as a template
  ({{SOURCE}} placeholder) so no machine path is hardcoded; the rendered
  file, target/, and the built binary are gitignored.
- pacta dogfood-build --source <workspace>: renders, builds, installs
  to dogfood/state/, and writes a provenance sidecar (source commit,
  backend cfg, rustc, and an honest coverage note: the certificates
  cover verify_sha512, the extraction-refactored image of this verify
  path; SHA-512 and the wire glue remain the theorems' documented
  boundary). pacta dogfood-status reports the active backend.
- signing.verify_payload_ed25519_detailed: dispatch - the dogfood
  binary when present (backend "verified-dalek-serial"), OpenSSL
  fallback otherwise, and the backend that ACTUALLY ran is recorded in
  receipt signature statuses and attestation evidence. Fallback is
  never silent.
- --require-verified-verifier (receipt-verify + agent): policy fails
  closed when verification did not run on the certificate-covered
  path.
- ML-DSA is deliberately unchanged: no proven implementation exists,
  so the slot stays fail-closed "unavailable" - the honest hybrid-PQC
  posture is one proven-classical signature plus one required-but-
  unproven PQC slot, never a pretend backend.

Validated live: receipt verification through the proven verifier
(backend recorded), a corrupted signature bit rejected BY the proven
binary, tampered attestations rejected, and the policy failing closed
when the binary is absent. 49/49 tests green (incl. PEM-SPKI raw-key
cross-check against openssl, dispatch/backend recording with a stub,
and a real-binary roundtrip that skips gracefully where unbuilt).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
mrwulf 2026-07-06 10:13:48 +02:00
parent 7c717d03fc
commit d331ba17d9
9 changed files with 444 additions and 11 deletions

4
.gitignore vendored
View file

@ -14,3 +14,7 @@ __pycache__/
.lake/
*.olean
*.ilean
dogfood/state/
dogfood/pacta-verified-verify/target/
dogfood/pacta-verified-verify/Cargo.toml
dogfood/pacta-verified-verify/Cargo.lock

View file

@ -0,0 +1,14 @@
# Rendered by `pacta dogfood-build` - the {{SOURCE}} placeholder is replaced
# with the local checkout of the PINNED proven source workspace
# (saymrwulf/curve25519-dalek-source). Committed as a template so the repo
# never hardcodes a machine-specific path.
[package]
name = "pacta-verified-verify"
version = "0.1.0"
edition = "2021"
publish = false
[dependencies]
ed25519-dalek = { path = "{{SOURCE}}/ed25519-dalek", default-features = false, features = ["fast", "zeroize"] }
[workspace]

View file

@ -0,0 +1,77 @@
//! pacta's dogfood Ed25519 verifier.
//!
//! This binary is built against the PINNED, PROVEN source workspace
//! (saymrwulf/curve25519-dalek-source at the commit named in the build
//! provenance) with the serial backend pinned - the exact code path whose
//! correctness certificates pacta consumes. When pacta checks a provider
//! signature or a signed tree head through this binary, the agent is
//! eating its own dogfood: the arithmetic under the verification is
//! certificate-covered (field, group law, scalars, decompression, and the
//! four-tier signature apex), and the residual trusted base is exactly the
//! theorems' documented boundary (SHA-512 as an oracle, the wire glue).
//!
//! Usage: pacta-verified-verify <pubkey-hex-32B> <sig-hex-64B> <payload-file>
//! Exit 0 = signature valid; exit 1 = invalid; exit 2 = usage/format error.
use ed25519_dalek::{Signature, Verifier, VerifyingKey};
use std::process::ExitCode;
fn hex_decode(s: &str) -> Result<Vec<u8>, String> {
if s.len() % 2 != 0 {
return Err("odd-length hex".into());
}
(0..s.len() / 2)
.map(|i| u8::from_str_radix(&s[2 * i..2 * i + 2], 16).map_err(|e| e.to_string()))
.collect()
}
fn main() -> ExitCode {
let args: Vec<String> = std::env::args().collect();
if args.len() != 4 {
eprintln!("usage: pacta-verified-verify <pubkey-hex> <sig-hex> <payload-file>");
return ExitCode::from(2);
}
let pk_bytes = match hex_decode(&args[1]) {
Ok(b) if b.len() == 32 => b,
_ => {
eprintln!("error: public key must be 32 bytes of hex");
return ExitCode::from(2);
}
};
let sig_bytes = match hex_decode(&args[2]) {
Ok(b) if b.len() == 64 => b,
_ => {
eprintln!("error: signature must be 64 bytes of hex");
return ExitCode::from(2);
}
};
let payload = match std::fs::read(&args[3]) {
Ok(p) => p,
Err(e) => {
eprintln!("error: cannot read payload: {e}");
return ExitCode::from(2);
}
};
let mut pk_array = [0u8; 32];
pk_array.copy_from_slice(&pk_bytes);
let verifying_key = match VerifyingKey::from_bytes(&pk_array) {
Ok(k) => k,
Err(e) => {
eprintln!("error: invalid public key: {e}");
return ExitCode::from(2);
}
};
let mut sig_array = [0u8; 64];
sig_array.copy_from_slice(&sig_bytes);
let signature = Signature::from_bytes(&sig_array);
match verifying_key.verify(&payload, &signature) {
Ok(()) => {
println!("OK");
ExitCode::SUCCESS
}
Err(_) => {
println!("INVALID");
ExitCode::from(1)
}
}
}

View file

@ -6,7 +6,7 @@ from typing import Any
from .config import RepoConfig
from .profiles import get_profile
from .signing import verify_attestation_signature
from .signing import verify_attestation_signature_detailed
from .sthstore import check_sth_against_store, check_sth_freshness
from .transparency import load_receipt, verify_receipt
from .yamlio import load_data
@ -45,6 +45,7 @@ def validate_attestation(
sth_store_path: str | Path | None = None,
consistency_proof_path: str | Path | None = None,
max_sth_age_seconds: int | None = None,
require_verified_verifier: bool = False,
) -> AttestationResult:
provider = raw.get("provider")
subject = raw.get("subject") or {}
@ -82,12 +83,18 @@ def validate_attestation(
signature = raw.get("signature") or {}
environment = raw.get("environment") or {}
signature_status = signature.get("status", "not_checked")
signature_backend = "none"
if public_key_path:
ok, error = verify_attestation_signature(raw, public_key_path)
ok, error, signature_backend = verify_attestation_signature_detailed(raw, public_key_path)
if ok:
signature_status = "verified"
else:
diagnostics.append(f"Attestation signature verification failed: {error}")
if require_verified_verifier and signature_backend != "verified-dalek-serial":
diagnostics.append(
"Policy requires the dogfood (certificate-covered) Ed25519 verifier, but verification ran on "
f"backend '{signature_backend}'. Build it with: pacta dogfood-build --source <pinned-workspace>."
)
elif signature_status == "signed":
diagnostics.append("Signed attestation requires --attestation-public-key.")
elif signature_status == "not_implemented":
@ -142,6 +149,7 @@ def validate_attestation(
"attestation_provider": provider,
"attestation_path": str(path) if path else None,
"attestation_signature_status": signature_status,
"attestation_signature_backend": signature_backend,
"attestation_log_url": raw.get("log_url") or signature.get("log_url"),
"attestation_issued_at": raw.get("issued_at"),
"check_log_path": (raw.get("replay") or {}).get("check_log_path"),

View file

@ -139,8 +139,17 @@ def build_parser() -> argparse.ArgumentParser:
receipt_verify.add_argument("--sth-store", help="Path to the local STH pin store (split-view/rollback defense).")
receipt_verify.add_argument("--consistency-proof", help="File with a hex consistency proof from the pinned tree size (provider: log-consistency).")
receipt_verify.add_argument("--max-sth-age-seconds", type=int, help="Reject signed tree heads older than this (freshness policy).")
receipt_verify.add_argument("--require-verified-verifier", action="store_true", help="Fail closed unless Ed25519 verification ran on the dogfood (certificate-covered) verifier.")
receipt_verify.set_defaults(func=cmd_receipt_verify)
dogfood_build = sub.add_parser("dogfood-build", help="Build the dogfood Ed25519 verifier from the pinned proven source workspace.")
dogfood_build.add_argument("--source", required=True, help="Local checkout of saymrwulf/curve25519-dalek-source (the pinned proven workspace).")
dogfood_build.add_argument("--timeout", type=int, default=900)
dogfood_build.set_defaults(func=cmd_dogfood_build)
dogfood_status = sub.add_parser("dogfood-status", help="Show which Ed25519 verification backend pacta will use, with provenance.")
dogfood_status.set_defaults(func=cmd_dogfood_status)
agent = sub.add_parser("agent", help="Apply a policy-gated consequence to verification evidence.")
agent.add_argument("--claims", help="Existing claim card to act on.")
agent.add_argument("--config", help="Repository config used to generate a claim card.")
@ -169,6 +178,7 @@ def build_parser() -> argparse.ArgumentParser:
agent.add_argument("--sth-store", help="Path to the local STH pin store (split-view/rollback defense).")
agent.add_argument("--consistency-proof", help="File with a hex consistency proof from the pinned tree size.")
agent.add_argument("--max-sth-age-seconds", type=int, help="Reject signed tree heads older than this.")
agent.add_argument("--require-verified-verifier", action="store_true", help="Fail closed unless Ed25519 verification ran on the dogfood (certificate-covered) verifier.")
agent.set_defaults(func=cmd_agent)
return parser
@ -385,6 +395,11 @@ def cmd_receipt_verify(args: argparse.Namespace) -> int:
consistency_proof_path=args.consistency_proof,
max_sth_age_seconds=args.max_sth_age_seconds,
)
if args.require_verified_verifier and result.signatures.get("ed25519_backend") != "verified-dalek-serial":
accountability_diagnostics.append(
"Policy requires the dogfood (certificate-covered) Ed25519 verifier, but verification ran on backend "
f"'{result.signatures.get('ed25519_backend', 'none')}'."
)
if accountability_diagnostics:
result.accepted = False
result.diagnostics.extend(accountability_diagnostics)
@ -402,6 +417,38 @@ def cmd_receipt_verify(args: argparse.Namespace) -> int:
return 0 if result.accepted else 1
def cmd_dogfood_build(args: argparse.Namespace) -> int:
from .dogfood import build_verifier
result = build_verifier(args.source, timeout=args.timeout)
for diagnostic in result.diagnostics:
print(diagnostic)
if not result.built:
print("dogfood verifier NOT built; Ed25519 verification falls back to OpenSSL (recorded as a downgrade).")
return 1
print(f"binary: {result.binary_path}")
for key in ("source_commit", "backend_cfg", "rustc_version"):
print(f"{key}: {result.provenance.get(key)}")
print("coverage: " + str(result.provenance.get("coverage_note")))
return 0
def cmd_dogfood_status(args: argparse.Namespace) -> int:
from .dogfood import BACKEND_OPENSSL, BACKEND_VERIFIED, load_provenance, locate_verifier
binary = locate_verifier()
if binary is None:
print(f"backend: {BACKEND_OPENSSL} (fallback)")
print("dogfood verifier not built. Build with: pacta dogfood-build --source <pinned-workspace>")
return 1
print(f"backend: {BACKEND_VERIFIED}")
print(f"binary: {binary}")
provenance = load_provenance(binary)
for key in ("source_workspace", "source_commit", "backend_cfg", "rustc_version"):
print(f"{key}: {provenance.get(key)}")
return 0
def _log_accountability_checks(
receipt: dict,
sth_store: str | None,
@ -553,4 +600,5 @@ def _attestation_for_args(args: argparse.Namespace, repo: RepoConfig):
sth_store_path=getattr(args, "sth_store", None),
consistency_proof_path=getattr(args, "consistency_proof", None),
max_sth_age_seconds=getattr(args, "max_sth_age_seconds", None),
require_verified_verifier=bool(getattr(args, "require_verified_verifier", False)),
)

184
src/pacta/dogfood.py Normal file
View file

@ -0,0 +1,184 @@
from __future__ import annotations
import base64
import binascii
import json
import os
import shutil
import subprocess
import tempfile
from dataclasses import dataclass, field
from pathlib import Path
from typing import Any
DOGFOOD_ENV = "PACTA_DOGFOOD_VERIFIER"
DEFAULT_STATE_DIR = Path("dogfood") / "state"
BACKEND_VERIFIED = "verified-dalek-serial"
BACKEND_OPENSSL = "openssl"
# Ed25519 SubjectPublicKeyInfo (RFC 8410): a fixed 12-byte DER prefix then
# the raw 32-byte key. Parsing by prefix is exact for this OID, not a
# heuristic.
_ED25519_SPKI_PREFIX = bytes.fromhex("302a300506032b6570032100")
@dataclass(slots=True)
class DogfoodBuildResult:
built: bool
binary_path: Path | None
provenance: dict[str, Any] = field(default_factory=dict)
diagnostics: list[str] = field(default_factory=list)
def pem_public_key_to_raw(public_key_path: str | Path) -> bytes:
"""Extract the raw 32-byte Ed25519 key from an OpenSSL PEM SPKI file."""
text = Path(public_key_path).read_text(encoding="utf-8")
body = "".join(
line.strip()
for line in text.splitlines()
if line.strip() and not line.startswith("-----")
)
try:
der = base64.b64decode(body, validate=True)
except (binascii.Error, ValueError) as exc:
raise ValueError(f"Not a PEM public key: {public_key_path}: {exc}") from exc
if not der.startswith(_ED25519_SPKI_PREFIX) or len(der) != len(_ED25519_SPKI_PREFIX) + 32:
raise ValueError(
f"Not an Ed25519 SubjectPublicKeyInfo: {public_key_path} "
f"(got {len(der)} DER bytes)"
)
return der[len(_ED25519_SPKI_PREFIX):]
def default_binary_path(state_dir: str | Path | None = None) -> Path:
return Path(state_dir or DEFAULT_STATE_DIR) / "pacta-verified-verify"
def locate_verifier(state_dir: str | Path | None = None) -> Path | None:
"""Find the dogfood verifier binary: explicit env var first, then the
default build location. Returns None when unavailable (callers fall
back to OpenSSL and must record the downgrade)."""
env = os.environ.get(DOGFOOD_ENV)
if env:
path = Path(env)
return path if path.exists() else None
path = default_binary_path(state_dir)
return path if path.exists() else None
def load_provenance(binary_path: str | Path) -> dict[str, Any]:
sidecar = Path(binary_path).with_suffix(".provenance.json")
if sidecar.exists():
return json.loads(sidecar.read_text(encoding="utf-8"))
return {}
def build_verifier(
source_workspace: str | Path,
crate_dir: str | Path = Path("dogfood") / "pacta-verified-verify",
state_dir: str | Path | None = None,
timeout: int = 900,
) -> DogfoodBuildResult:
"""Build the dogfood verifier against the pinned proven source workspace.
The serial backend is pinned via RUSTFLAGS exactly as the verified
extraction pins it; provenance (source path, source commit, rustc,
backend cfg) is recorded next to the binary and surfaces in evidence.
"""
source = Path(source_workspace).expanduser().resolve()
crate = Path(crate_dir).resolve()
diagnostics: list[str] = []
cargo = shutil.which("cargo")
if not cargo:
return DogfoodBuildResult(False, None, {}, ["cargo is not available on PATH; cannot build the dogfood verifier."])
if not (source / "ed25519-dalek" / "Cargo.toml").exists():
return DogfoodBuildResult(
False,
None,
{},
[f"{source} does not look like the pinned curve25519-dalek source workspace (no ed25519-dalek/Cargo.toml)."],
)
template = (crate / "Cargo.toml.template").read_text(encoding="utf-8")
(crate / "Cargo.toml").write_text(template.replace("{{SOURCE}}", str(source)), encoding="utf-8")
env = dict(os.environ)
backend_cfg = 'curve25519_dalek_backend="serial"'
env["RUSTFLAGS"] = (env.get("RUSTFLAGS", "") + f" --cfg {backend_cfg}").strip()
completed = subprocess.run(
[cargo, "build", "--release", "--quiet"],
cwd=str(crate),
env=env,
capture_output=True,
text=True,
timeout=timeout,
)
if completed.returncode != 0:
tail = (completed.stderr or completed.stdout or "").strip().splitlines()[-12:]
return DogfoodBuildResult(False, None, {}, ["cargo build failed:"] + tail)
built = crate / "target" / "release" / "pacta-verified-verify"
if not built.exists():
return DogfoodBuildResult(False, None, {}, [f"cargo reported success but {built} does not exist."])
out = default_binary_path(state_dir)
out.parent.mkdir(parents=True, exist_ok=True)
shutil.copy2(built, out)
provenance = {
"type": "pacta.dogfood.verifier_provenance.v1",
"source_workspace": str(source),
"source_commit": _git_commit(source),
"backend_cfg": backend_cfg,
"rustc_version": _tool_version("rustc"),
"cargo_version": _tool_version("cargo"),
"entry_point": "ed25519_dalek::VerifyingKey::verify (pinned workspace)",
"coverage_note": (
"The certificates cover verify_sha512, the extraction-refactored image of this verify path "
"(same internals; the delta is the documented hash-wrapper refactor in the pinned source). "
"Field, group law, scalars, encoding/decompression, and the four apex tiers are certificate-covered; "
"SHA-512 and the ~15 lines of wire glue are the theorems' documented trusted base."
),
}
out.with_suffix(".provenance.json").write_text(json.dumps(provenance, indent=2, sort_keys=True) + "\n", encoding="utf-8")
return DogfoodBuildResult(True, out, provenance, diagnostics)
def verify_payload_dogfood(
payload: bytes,
signature: bytes,
public_key_path: str | Path,
binary: str | Path,
timeout: int = 30,
) -> tuple[bool, str | None]:
try:
raw_key = pem_public_key_to_raw(public_key_path)
except ValueError as exc:
return False, str(exc)
with tempfile.TemporaryDirectory(prefix="pacta-dogfood-") as tmp:
payload_path = Path(tmp) / "payload.bin"
payload_path.write_bytes(payload)
completed = subprocess.run(
[str(binary), raw_key.hex(), signature.hex(), str(payload_path)],
capture_output=True,
text=True,
timeout=timeout,
)
if completed.returncode == 0:
return True, None
if completed.returncode == 1:
return False, "signature invalid (verified-path verifier)"
return False, (completed.stderr or completed.stdout or "dogfood verifier error").strip()
def _git_commit(path: Path) -> str | None:
git = shutil.which("git")
if not git:
return None
completed = subprocess.run(
[git, "rev-parse", "HEAD"], cwd=str(path), capture_output=True, text=True, timeout=15
)
return completed.stdout.strip() if completed.returncode == 0 else None
def _tool_version(tool: str) -> str | None:
path = shutil.which(tool)
if not path:
return None
completed = subprocess.run([path, "--version"], capture_output=True, text=True, timeout=15)
return completed.stdout.strip() if completed.returncode == 0 else None

View file

@ -58,22 +58,27 @@ def sign_attestation(attestation: dict[str, Any], private_key_path: str | Path,
def verify_attestation_signature(attestation: dict[str, Any], public_key_path: str | Path) -> tuple[bool, str | None]:
ok, error, _backend = verify_attestation_signature_detailed(attestation, public_key_path)
return ok, error
def verify_attestation_signature_detailed(attestation: dict[str, Any], public_key_path: str | Path) -> tuple[bool, str | None, str]:
signature = attestation.get("signature") or {}
if signature.get("scheme") != "openssl-ed25519":
return False, f"Unsupported attestation signature scheme: {signature.get('scheme')}"
return False, f"Unsupported attestation signature scheme: {signature.get('scheme')}", "none"
encoded = signature.get("signature_base64")
if not encoded:
return False, "Attestation signature is missing signature_base64."
return False, "Attestation signature is missing signature_base64.", "none"
expected_digest = signature.get("payload_digest_sha256")
actual_digest = payload_digest(attestation)
if expected_digest and expected_digest != actual_digest:
return False, "Attestation payload digest does not match signature metadata."
return False, "Attestation payload digest does not match signature metadata.", "none"
expected_fingerprint = signature.get("public_key_fingerprint_sha256")
if expected_fingerprint:
actual_fingerprint = public_key_fingerprint(public_key_path)
if expected_fingerprint != actual_fingerprint:
return False, "Attestation public key fingerprint does not match signature metadata."
return verify_payload_ed25519(canonical_attestation_payload(attestation), encoded, public_key_path)
return False, "Attestation public key fingerprint does not match signature metadata.", "none"
return verify_payload_ed25519_detailed(canonical_attestation_payload(attestation), encoded, public_key_path)
def sign_payload_ed25519(payload: bytes, private_key_path: str | Path) -> str:
@ -96,11 +101,37 @@ def sign_payload_ed25519(payload: bytes, private_key_path: str | Path) -> str:
def verify_payload_ed25519(payload: bytes, signature_base64: str, public_key_path: str | Path) -> tuple[bool, str | None]:
openssl = _openssl()
ok, error, _backend = verify_payload_ed25519_detailed(payload, signature_base64, public_key_path)
return ok, error
def verify_payload_ed25519_detailed(
payload: bytes,
signature_base64: str,
public_key_path: str | Path,
) -> tuple[bool, str | None, str]:
"""Verify an Ed25519 signature, preferring pacta's DOGFOOD verifier -
a binary built from the pinned, certificate-covered dalek source with
the serial backend pinned - and falling back to OpenSSL when the
dogfood binary is unavailable. The third element names the backend that
actually ran so callers can record (and policies can require) the
verified path."""
from .dogfood import BACKEND_OPENSSL, BACKEND_VERIFIED, locate_verifier, verify_payload_dogfood
try:
signature_bytes = base64.b64decode(signature_base64, validate=True)
except ValueError as exc:
return False, f"Invalid base64 signature: {exc}"
return False, f"Invalid base64 signature: {exc}", "none"
binary = locate_verifier()
if binary is not None:
ok, error = verify_payload_dogfood(payload, signature_bytes, public_key_path, binary)
return ok, error, BACKEND_VERIFIED
ok, error = _verify_payload_openssl(payload, signature_bytes, public_key_path)
return ok, error, BACKEND_OPENSSL
def _verify_payload_openssl(payload: bytes, signature_bytes: bytes, public_key_path: str | Path) -> tuple[bool, str | None]:
openssl = _openssl()
with tempfile.TemporaryDirectory(prefix="pacta-verify-") as tmp:
payload_path = Path(tmp) / "payload.bin"
signature_path = Path(tmp) / "payload.sig"

View file

@ -6,7 +6,7 @@ from pathlib import Path
from typing import Any
from .postquantum import detect_ml_dsa
from .signing import canonical_json, public_key_fingerprint, sign_payload_ed25519, verify_payload_ed25519
from .signing import canonical_json, public_key_fingerprint, sign_payload_ed25519, verify_payload_ed25519_detailed
from .yamlio import load_data
HASH_ALGORITHM = "RFC9162_SHA256"
@ -206,8 +206,9 @@ def verify_signed_tree_head(
diagnostics.append("Signed tree head Ed25519 public-key fingerprint mismatch.")
statuses["ed25519"] = "key_mismatch"
else:
ok, error = verify_payload_ed25519(payload, str(ed25519.get("signature_base64") or ""), public_key_path)
ok, error, backend = verify_payload_ed25519_detailed(payload, str(ed25519.get("signature_base64") or ""), public_key_path)
statuses["ed25519"] = "verified" if ok else "failed"
statuses["ed25519_backend"] = backend
if not ok:
diagnostics.append(f"Signed tree head Ed25519 verification failed: {error}")

66
tests/test_dogfood.py Normal file
View file

@ -0,0 +1,66 @@
import os
import stat
import subprocess
from pacta.dogfood import BACKEND_VERIFIED, locate_verifier, pem_public_key_to_raw
from pacta.signing import generate_ed25519_keypair, sign_payload_ed25519, verify_payload_ed25519_detailed
def test_pem_spki_to_raw_roundtrip(tmp_path):
private_key = tmp_path / "k.key"
public_key = tmp_path / "k.pub"
generate_ed25519_keypair(private_key, public_key)
raw = pem_public_key_to_raw(public_key)
assert len(raw) == 32
# cross-check against openssl's own raw dump
dumped = subprocess.run(
["openssl", "pkey", "-pubin", "-in", str(public_key), "-outform", "DER"],
capture_output=True, check=True,
).stdout
assert dumped.endswith(raw)
def test_pem_rejects_non_ed25519(tmp_path):
bogus = tmp_path / "bogus.pub"
bogus.write_text("-----BEGIN PUBLIC KEY-----\nAAAA\n-----END PUBLIC KEY-----\n")
import pytest
with pytest.raises(ValueError):
pem_public_key_to_raw(bogus)
def test_dispatch_prefers_dogfood_binary_and_records_backend(tmp_path, monkeypatch):
# a fake verifier that accepts everything: proves dispatch + backend label
fake = tmp_path / "fake-verify"
fake.write_text("#!/bin/sh\necho OK\nexit 0\n")
fake.chmod(fake.stat().st_mode | stat.S_IEXEC)
private_key = tmp_path / "k.key"
public_key = tmp_path / "k.pub"
generate_ed25519_keypair(private_key, public_key)
payload = b"dogfood dispatch test"
signature = sign_payload_ed25519(payload, private_key)
monkeypatch.setenv("PACTA_DOGFOOD_VERIFIER", str(fake))
ok, error, backend = verify_payload_ed25519_detailed(payload, signature, public_key)
assert ok and backend == BACKEND_VERIFIED
monkeypatch.setenv("PACTA_DOGFOOD_VERIFIER", str(tmp_path / "missing"))
assert locate_verifier() is None
ok, error, backend = verify_payload_ed25519_detailed(payload, signature, public_key)
assert ok and backend == "openssl"
def test_real_dogfood_binary_if_built(tmp_path):
import pytest
binary = locate_verifier()
if binary is None or "fake" in str(binary):
pytest.skip("dogfood verifier not built on this host")
private_key = tmp_path / "k.key"
public_key = tmp_path / "k.pub"
generate_ed25519_keypair(private_key, public_key)
payload = b"the proven path verifies this"
signature = sign_payload_ed25519(payload, private_key)
ok, error, backend = verify_payload_ed25519_detailed(payload, signature, public_key)
assert ok and backend == BACKEND_VERIFIED
# flip one payload byte: the proven path must reject
ok, error, backend = verify_payload_ed25519_detailed(payload + b"x", signature, public_key)
assert not ok and backend == BACKEND_VERIFIED