"""Claim 1: the certificate-chain authority behaves as stated.""" import dataclasses from datetime import timedelta import pytest from capability_licensing import CertificateAuthority, verify_chain from capability_licensing.certificates import parse_iso def test_intact_chain_verifies_to_trusted_root(chain): result = verify_chain(chain.capability, [chain.organisation], [chain.root]) assert result.valid assert result.path == ( chain.capability.serial, chain.organisation.serial, chain.root.serial, ) def test_root_is_self_signed_and_verifies_alone(chain): result = verify_chain(chain.root, [], [chain.root]) assert result.valid def test_tampered_certificate_fails(chain): tampered = dataclasses.replace( chain.capability, claims={**dict(chain.capability.claims), "grant": "unlimited production use"}, ) result = verify_chain(tampered, [chain.organisation], [chain.root]) assert not result.valid assert "does not verify" in result.reason def test_tampered_subject_fails(chain): tampered = dataclasses.replace(chain.capability, subject="renamed-capability") result = verify_chain(tampered, [chain.organisation], [chain.root]) assert not result.valid def test_tampered_intermediate_fails(chain): tampered_org = dataclasses.replace( chain.organisation, subject="Hostile Organisation" ) result = verify_chain(chain.capability, [tampered_org], [chain.root]) assert not result.valid def test_expired_certificate_fails(chain): after_expiry = parse_iso(chain.capability.not_after) + timedelta(days=1) result = verify_chain( chain.capability, [chain.organisation], [chain.root], at=after_expiry ) assert not result.valid assert "expired" in result.reason def test_not_yet_valid_certificate_fails(chain): before_validity = parse_iso(chain.capability.not_before) - timedelta(days=1) result = verify_chain( chain.capability, [chain.organisation], [chain.root], at=before_validity ) assert not result.valid assert "not yet valid" in result.reason def test_chain_to_untrusted_root_fails(chain): other = CertificateAuthority() other_root = other.create_root("Unaccredited Authority") other_org = other.issue_organisation(other_root.serial, "Unaccredited Organisation") other_leaf, _ = other.issue_capability(other_org.serial, "impostor", claims={}) result = verify_chain(other_leaf, [other_org, other_root], [chain.root]) assert not result.valid assert "not in the trust store" in result.reason def test_missing_intermediate_fails(chain): result = verify_chain(chain.capability, [], [chain.root]) assert not result.valid assert "issuer not found" in result.reason def test_capability_may_not_issue_certificates(chain): with pytest.raises(ValueError, match="role violation"): chain.authority._issue( issuer_serial=chain.capability.serial, subject="illicit-sub-capability", role="capability", claims={}, lifetime_days=1, ) def test_authority_does_not_retain_leaf_keys(chain): assert chain.capability.serial not in chain.authority._signing_keys