audit-labs/evidence-seal

Tamper-evident seals and chain of custody for audit evidence.

clone: git clone https://gitbay.org/audit-labs/evidence-seal.git

main: tests/test_signing.py · raw

 1"""Tests for optional ed25519 signing (skipped if cryptography is absent)."""
 2
 3import pytest
 4
 5pytest.importorskip("cryptography")
 6
 7from evidence_seal.manifest import build_manifest
 8from evidence_seal.signing import (
 9    generate_keypair,
10    load_public_hex,
11    sign_manifest,
12    verify_signature,
13)
14
15
16@pytest.fixture
17def sealed(tmp_path):
18    d = tmp_path / "pkg"
19    d.mkdir()
20    (d / "a.csv").write_text("x\n", encoding="utf-8")
21    return build_manifest(d)
22
23
24@pytest.fixture
25def keys(tmp_path):
26    priv, pub = tmp_path / "k.key", tmp_path / "k.pub"
27    generate_keypair(priv, pub)
28    return priv, pub
29
30
31def test_sign_then_verify(sealed, keys):
32    priv, pub = keys
33    signed = sign_manifest(sealed, priv)
34    ok, _ = verify_signature(signed)
35    assert ok
36    # And the embedded key matches the PEM public key.
37    ok_matched, _ = verify_signature(signed, load_public_hex(pub))
38    assert ok_matched
39
40
41def test_unsigned_manifest_reports_clearly(sealed):
42    ok, message = verify_signature(sealed)
43    assert not ok
44    assert "not signed" in message
45
46
47def test_tampered_manifest_fails_signature(sealed, keys):
48    priv, _ = keys
49    signed = sign_manifest(sealed, priv)
50    # Alter a hash after signing; the signature no longer covers it.
51    signed["files"][0]["sha256"] = "0" * 64
52    ok, _ = verify_signature(signed)
53    assert not ok
54
55
56def test_wrong_expected_key_rejected(sealed, tmp_path, keys):
57    priv, _ = keys
58    signed = sign_manifest(sealed, priv)
59    other_priv, other_pub = tmp_path / "o.key", tmp_path / "o.pub"
60    generate_keypair(other_priv, other_pub)
61    ok, message = verify_signature(signed, load_public_hex(other_pub))
62    assert not ok
63    assert "does not match" in message