"""Tests for M9.5 supply chain attestation.""" from cmdforge.attestation import ( Attestation, generate_keypair, sign_tool, verify_attestation, verify_content_hash, verify_trusted_attestation, ) from cmdforge.tool import Tool class TestSignTool: def test_creates_attestation(self): private, public = generate_keypair() att = sign_tool("mytool", "1.0.0", "abc123", "alice", private) assert att.tool_name == "mytool" assert att.version == "1.0.0" assert att.content_hash == "abc123" assert att.signer == "alice" assert len(att.signature) == 88 assert att.algorithm == "ed25519" assert verify_attestation(att, public) def test_different_keys_different_signatures(self): key1, _ = generate_keypair() key2, _ = generate_keypair() att1 = sign_tool("tool", "1.0.0", "hash", "alice", key1) att2 = sign_tool("tool", "1.0.0", "hash", "alice", key2) assert att1.signature != att2.signature class TestVerifyAttestation: def test_valid_signature(self): private, public = generate_keypair() att = sign_tool("mytool", "1.0.0", "abc123", "alice", private) assert verify_attestation(att, public) def test_wrong_key_fails(self): private, _ = generate_keypair() _, wrong_public = generate_keypair() att = sign_tool("mytool", "1.0.0", "abc123", "alice", private) assert not verify_attestation(att, wrong_public) def test_tampered_content_fails(self): from dataclasses import replace private, public = generate_keypair() att = sign_tool("mytool", "1.0.0", "abc123", "alice", private) att = replace(att, content_hash="tampered") assert not verify_attestation(att, public) def test_tampered_signer_fails(self): from dataclasses import replace private, public = generate_keypair() att = sign_tool("mytool", "1.0.0", "abc123", "alice", private) att = replace(att, signer="eve") assert not verify_attestation(att, public) def test_timestamp_and_algorithm_are_signed(self): from dataclasses import replace private, public = generate_keypair() att = sign_tool("tool", "1.0.0", "hash", "alice", private) assert not verify_attestation(replace(att, signed_at="tomorrow"), public) assert not verify_attestation(replace(att, algorithm="hmac-sha256"), public) def test_requires_trusted_publisher_mapping(self): private, public = generate_keypair() att = sign_tool("tool", "1.0.0", "hash", "alice", private) assert verify_trusted_attestation(att, {"alice": public}) assert not verify_trusted_attestation(att, {"mallory": public})