tests/test_key_ring.py
1.5 KB · 53 lines · python Raw
1 """Tests for KeyRing."""
2
3 from __future__ import annotations
4
5 import pytest
6
7 from pqc_bootloader.errors import UnknownKeyError
8 from pqc_bootloader.key_ring import KeyRing
9
10
11 def _fake_pk_hex(byte: int = 0xAB) -> str:
12 return (bytes([byte]) * 32).hex()
13
14
15 def test_add_assigns_fingerprint() -> None:
16 ring = KeyRing()
17 entry = ring.add(_fake_pk_hex(0x11), "ML-DSA-65", "Acme Inc.")
18 assert entry.key_id == KeyRing.fingerprint(_fake_pk_hex(0x11))
19 assert entry.manufacturer == "Acme Inc."
20 assert entry.revoked is False
21
22
23 def test_fingerprint_deterministic_and_is_trusted_true_after_add() -> None:
24 pk = _fake_pk_hex(0x22)
25 assert KeyRing.fingerprint(pk) == KeyRing.fingerprint(pk)
26
27 ring = KeyRing()
28 entry = ring.add(pk, "ML-DSA-65", "Acme Inc.")
29 assert ring.is_trusted(entry.key_id) is True
30 assert len(ring) == 1
31
32
33 def test_revoke_marks_entry_and_is_trusted_false() -> None:
34 ring = KeyRing()
35 entry = ring.add(_fake_pk_hex(0x33), "ML-DSA-65", "Acme Inc.")
36 ring.revoke(entry.key_id, reason="key compromised in 2030 breach")
37 fetched = ring.get(entry.key_id)
38 assert fetched.revoked is True
39 assert "compromised" in fetched.revocation_reason
40 assert ring.is_trusted(entry.key_id) is False
41
42
43 def test_get_missing_raises_unknown_key_error() -> None:
44 ring = KeyRing()
45 with pytest.raises(UnknownKeyError):
46 ring.get("nonexistent-key-id")
47
48
49 def test_revoke_missing_raises_unknown_key_error() -> None:
50 ring = KeyRing()
51 with pytest.raises(UnknownKeyError):
52 ring.revoke("nonexistent-key-id", reason="n/a")
53