2021-10-31 11:53:20 -06:00
|
|
|
from pathlib import Path
|
2021-11-04 12:26:11 -06:00
|
|
|
from typing import List
|
|
|
|
from unittest.mock import Mock
|
|
|
|
from unittest.mock import patch
|
|
|
|
|
|
|
|
from pytest import mark
|
|
|
|
from pytest import raises
|
2021-10-31 11:53:20 -06:00
|
|
|
|
|
|
|
from libkeyringctl.trust import certificate_trust
|
2021-11-04 12:26:11 -06:00
|
|
|
from libkeyringctl.trust import certificate_trust_from_paths
|
|
|
|
from libkeyringctl.trust import format_trust_label
|
|
|
|
from libkeyringctl.trust import trust_color
|
|
|
|
from libkeyringctl.trust import trust_icon
|
|
|
|
from libkeyringctl.types import Color
|
|
|
|
from libkeyringctl.types import Fingerprint
|
2021-10-31 11:53:20 -06:00
|
|
|
from libkeyringctl.types import Trust
|
|
|
|
from libkeyringctl.types import Uid
|
|
|
|
from libkeyringctl.types import Username
|
|
|
|
|
|
|
|
from .conftest import create_certificate
|
2021-11-03 13:38:29 -06:00
|
|
|
from .conftest import create_key_revocation
|
2021-11-04 12:26:11 -06:00
|
|
|
from .conftest import create_signature_revocation
|
2021-10-31 11:53:20 -06:00
|
|
|
from .conftest import create_uid_certification
|
2021-11-04 12:26:11 -06:00
|
|
|
from .conftest import test_all_fingerprints
|
2021-10-31 11:53:20 -06:00
|
|
|
from .conftest import test_keyring_certificates
|
|
|
|
from .conftest import test_main_fingerprints
|
|
|
|
|
|
|
|
|
2021-11-04 12:26:11 -06:00
|
|
|
@mark.parametrize(
|
|
|
|
"sources",
|
|
|
|
[
|
|
|
|
([Path("foobar")]),
|
|
|
|
([Path("foobar"), Path("quxdoo")]),
|
|
|
|
],
|
|
|
|
)
|
|
|
|
@patch("libkeyringctl.trust.certificate_trust")
|
|
|
|
def test_certificate_trust_from_paths(
|
|
|
|
certificate_trust_mock: Mock,
|
|
|
|
sources: List[Path],
|
2021-11-07 15:51:33 -06:00
|
|
|
working_dir: Path,
|
2021-11-04 12:26:11 -06:00
|
|
|
) -> None:
|
|
|
|
certificate_trust_mock.return_value = Trust.full
|
|
|
|
for source in sources:
|
|
|
|
source.mkdir(parents=True, exist_ok=True)
|
|
|
|
cert = source / "foo.asc"
|
|
|
|
cert.touch()
|
|
|
|
|
|
|
|
trusts = certificate_trust_from_paths(
|
|
|
|
sources=sources, main_keys=test_main_fingerprints, all_fingerprints=test_all_fingerprints
|
|
|
|
)
|
|
|
|
for i, source in enumerate(sources):
|
|
|
|
name, args, kwargs = certificate_trust_mock.mock_calls[i]
|
|
|
|
assert kwargs["certificate"] == source
|
|
|
|
assert kwargs["main_keys"] == test_main_fingerprints
|
|
|
|
assert kwargs["all_fingerprints"] == test_all_fingerprints
|
|
|
|
fingerprint = Fingerprint(source.name)
|
|
|
|
assert Trust.full == trusts[fingerprint]
|
|
|
|
assert len(trusts) == len(sources)
|
|
|
|
|
|
|
|
|
2021-10-31 11:53:20 -06:00
|
|
|
@create_certificate(username=Username("foobar"), uids=[Uid("foobar <foo@bar.xyz>")], keyring_type="main")
|
2021-11-01 11:37:00 -06:00
|
|
|
def test_certificate_trust_main_key_has_full_trust(working_dir: Path, keyring_dir: Path) -> None:
|
2021-10-31 11:53:20 -06:00
|
|
|
trust = certificate_trust(
|
|
|
|
test_keyring_certificates[Username("foobar")][0],
|
|
|
|
test_main_fingerprints,
|
2021-11-04 12:26:11 -06:00
|
|
|
test_all_fingerprints,
|
2021-10-31 11:53:20 -06:00
|
|
|
)
|
|
|
|
assert Trust.full == trust
|
|
|
|
|
|
|
|
|
2021-11-03 13:38:29 -06:00
|
|
|
@create_certificate(username=Username("foobar"), uids=[Uid("foobar <foo@bar.xyz>")], keyring_type="main")
|
|
|
|
@create_key_revocation(username=Username("foobar"), keyring_type="main")
|
|
|
|
def test_certificate_trust_main_key_revoked(working_dir: Path, keyring_dir: Path) -> None:
|
|
|
|
trust = certificate_trust(
|
|
|
|
test_keyring_certificates[Username("foobar")][0],
|
|
|
|
test_main_fingerprints,
|
2021-11-04 12:26:11 -06:00
|
|
|
test_all_fingerprints,
|
2021-11-03 13:38:29 -06:00
|
|
|
)
|
|
|
|
assert Trust.revoked == trust
|
|
|
|
|
|
|
|
|
2021-11-04 12:26:11 -06:00
|
|
|
@create_certificate(username=Username("foobar"), uids=[Uid("foobar <foo@bar.xyz>")], keyring_type="main")
|
|
|
|
@create_key_revocation(username=Username("foobar"), keyring_type="main")
|
|
|
|
def test_certificate_trust_main_key_revoked_unknown_fingerprint_lookup(working_dir: Path, keyring_dir: Path) -> None:
|
|
|
|
fingerprint = Fingerprint(test_keyring_certificates[Username("foobar")][0].name)
|
|
|
|
revocation = list((keyring_dir / "main" / "foobar" / fingerprint / "revocation").iterdir())[0]
|
|
|
|
revocation.rename(revocation.parent / "12341234.asc")
|
|
|
|
with raises(Exception):
|
|
|
|
certificate_trust(
|
|
|
|
test_keyring_certificates[Username("foobar")][0],
|
|
|
|
test_main_fingerprints,
|
|
|
|
{Fingerprint("12341234")},
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@create_certificate(username=Username("foobar"), uids=[Uid("foobar <foo@bar.xyz>")], keyring_type="main")
|
|
|
|
@create_key_revocation(username=Username("foobar"), keyring_type="main")
|
|
|
|
def test_certificate_trust_main_key_revoked_unknown_self_revocation(working_dir: Path, keyring_dir: Path) -> None:
|
|
|
|
fingerprint = Fingerprint(test_keyring_certificates[Username("foobar")][0].name)
|
|
|
|
revocation = list((keyring_dir / "main" / "foobar" / fingerprint / "revocation").iterdir())[0]
|
|
|
|
revocation.rename(revocation.parent / "12341234.asc")
|
|
|
|
with raises(Exception):
|
|
|
|
certificate_trust(
|
|
|
|
test_keyring_certificates[Username("foobar")][0],
|
|
|
|
test_main_fingerprints,
|
|
|
|
set(),
|
|
|
|
)
|
|
|
|
|
|
|
|
|
2021-10-31 11:53:20 -06:00
|
|
|
@create_certificate(username=Username("main"), uids=[Uid("main <foo@bar.xyz>")])
|
|
|
|
@create_certificate(username=Username("foobar"), uids=[Uid("foobar <foo@bar.xyz>")])
|
2021-11-01 11:37:00 -06:00
|
|
|
def test_certificate_trust_no_signature_is_unknown(working_dir: Path, keyring_dir: Path) -> None:
|
2021-10-31 11:53:20 -06:00
|
|
|
trust = certificate_trust(
|
|
|
|
test_keyring_certificates[Username("foobar")][0],
|
|
|
|
test_main_fingerprints,
|
2021-11-04 12:26:11 -06:00
|
|
|
test_all_fingerprints,
|
2021-10-31 11:53:20 -06:00
|
|
|
)
|
|
|
|
assert Trust.unknown == trust
|
|
|
|
|
|
|
|
|
|
|
|
@create_certificate(username=Username("main"), uids=[Uid("main <foo@bar.xyz>")], keyring_type="main")
|
|
|
|
@create_certificate(username=Username("foobar"), uids=[Uid("foobar <foo@bar.xyz>")])
|
|
|
|
@create_uid_certification(issuer=Username("main"), certified=Username("foobar"), uid=Uid("foobar <foo@bar.xyz>"))
|
2021-11-01 11:37:00 -06:00
|
|
|
def test_certificate_trust_one_signature_is_marginal(working_dir: Path, keyring_dir: Path) -> None:
|
2021-10-31 11:53:20 -06:00
|
|
|
trust = certificate_trust(
|
|
|
|
test_keyring_certificates[Username("foobar")][0],
|
|
|
|
test_main_fingerprints,
|
2021-11-04 12:26:11 -06:00
|
|
|
test_all_fingerprints,
|
2021-10-31 11:53:20 -06:00
|
|
|
)
|
|
|
|
assert Trust.marginal == trust
|
|
|
|
|
|
|
|
|
|
|
|
@create_certificate(username=Username("main"), uids=[Uid("main <foo@bar.xyz>")], keyring_type="main")
|
|
|
|
@create_certificate(username=Username("not_main"), uids=[Uid("main <foo@bar.xyz>")])
|
|
|
|
@create_certificate(username=Username("foobar"), uids=[Uid("foobar <foo@bar.xyz>")])
|
|
|
|
@create_uid_certification(issuer=Username("not_main"), certified=Username("foobar"), uid=Uid("foobar <foo@bar.xyz>"))
|
2021-11-01 11:37:00 -06:00
|
|
|
def test_certificate_trust_one_none_main_signature_gives_no_trust(working_dir: Path, keyring_dir: Path) -> None:
|
2021-10-31 11:53:20 -06:00
|
|
|
trust = certificate_trust(
|
|
|
|
test_keyring_certificates[Username("foobar")][0],
|
|
|
|
test_main_fingerprints,
|
2021-11-04 12:26:11 -06:00
|
|
|
test_all_fingerprints,
|
2021-10-31 11:53:20 -06:00
|
|
|
)
|
|
|
|
assert Trust.unknown == trust
|
|
|
|
|
|
|
|
|
|
|
|
@create_certificate(username=Username("main1"), uids=[Uid("main1 <foo@bar.xyz>")], keyring_type="main")
|
|
|
|
@create_certificate(username=Username("main2"), uids=[Uid("main2 <foo@bar.xyz>")], keyring_type="main")
|
|
|
|
@create_certificate(username=Username("main3"), uids=[Uid("main3 <foo@bar.xyz>")], keyring_type="main")
|
|
|
|
@create_certificate(username=Username("foobar"), uids=[Uid("foobar <foo@bar.xyz>")])
|
|
|
|
@create_uid_certification(issuer=Username("main1"), certified=Username("foobar"), uid=Uid("foobar <foo@bar.xyz>"))
|
|
|
|
@create_uid_certification(issuer=Username("main2"), certified=Username("foobar"), uid=Uid("foobar <foo@bar.xyz>"))
|
|
|
|
@create_uid_certification(issuer=Username("main3"), certified=Username("foobar"), uid=Uid("foobar <foo@bar.xyz>"))
|
2021-11-01 11:37:00 -06:00
|
|
|
def test_certificate_trust_three_main_signature_gives_full_trust(working_dir: Path, keyring_dir: Path) -> None:
|
2021-10-31 11:53:20 -06:00
|
|
|
trust = certificate_trust(
|
|
|
|
test_keyring_certificates[Username("foobar")][0],
|
|
|
|
test_main_fingerprints,
|
2021-11-04 12:26:11 -06:00
|
|
|
test_all_fingerprints,
|
2021-10-31 11:53:20 -06:00
|
|
|
)
|
|
|
|
assert Trust.full == trust
|
2021-11-03 13:38:29 -06:00
|
|
|
|
|
|
|
|
|
|
|
@create_certificate(username=Username("main"), uids=[Uid("main <foo@bar.xyz>")], keyring_type="main")
|
|
|
|
@create_certificate(username=Username("foobar"), uids=[Uid("foobar <foo@bar.xyz>")])
|
2021-11-04 12:26:11 -06:00
|
|
|
@create_key_revocation(username=Username("foobar"))
|
2021-11-03 13:38:29 -06:00
|
|
|
def test_certificate_trust_revoked_key(working_dir: Path, keyring_dir: Path) -> None:
|
|
|
|
trust = certificate_trust(
|
|
|
|
test_keyring_certificates[Username("foobar")][0],
|
|
|
|
test_main_fingerprints,
|
2021-11-04 12:26:11 -06:00
|
|
|
test_all_fingerprints,
|
|
|
|
)
|
|
|
|
assert Trust.revoked == trust
|
|
|
|
|
|
|
|
|
|
|
|
@create_certificate(username=Username("main"), uids=[Uid("main <foo@bar.xyz>")], keyring_type="main")
|
|
|
|
@create_certificate(username=Username("foobar"), uids=[Uid("foobar <foo@bar.xyz>")])
|
|
|
|
@create_uid_certification(issuer=Username("main"), certified=Username("foobar"), uid=Uid("foobar <foo@bar.xyz>"))
|
|
|
|
@create_signature_revocation(issuer=Username("main"), certified=Username("foobar"), uid=Uid("foobar <foo@bar.xyz>"))
|
|
|
|
def test_certificate_trust_one_signature_revoked(working_dir: Path, keyring_dir: Path) -> None:
|
|
|
|
trust = certificate_trust(
|
|
|
|
test_keyring_certificates[Username("foobar")][0],
|
|
|
|
test_main_fingerprints,
|
|
|
|
test_all_fingerprints,
|
2021-11-03 13:38:29 -06:00
|
|
|
)
|
|
|
|
assert Trust.revoked == trust
|
2021-11-04 12:26:11 -06:00
|
|
|
|
|
|
|
|
|
|
|
@create_certificate(username=Username("main1"), uids=[Uid("main1 <foo@bar.xyz>")], keyring_type="main")
|
|
|
|
@create_certificate(username=Username("main2"), uids=[Uid("main2 <foo@bar.xyz>")], keyring_type="main")
|
|
|
|
@create_certificate(username=Username("main3"), uids=[Uid("main3 <foo@bar.xyz>")], keyring_type="main")
|
|
|
|
@create_certificate(username=Username("foobar"), uids=[Uid("foobar <foo@bar.xyz>")])
|
|
|
|
@create_uid_certification(issuer=Username("main1"), certified=Username("foobar"), uid=Uid("foobar <foo@bar.xyz>"))
|
|
|
|
@create_uid_certification(issuer=Username("main2"), certified=Username("foobar"), uid=Uid("foobar <foo@bar.xyz>"))
|
|
|
|
@create_uid_certification(issuer=Username("main3"), certified=Username("foobar"), uid=Uid("foobar <foo@bar.xyz>"))
|
|
|
|
@create_signature_revocation(issuer=Username("main3"), certified=Username("foobar"), uid=Uid("foobar <foo@bar.xyz>"))
|
|
|
|
def test_certificate_trust_revoked_if_below_full(working_dir: Path, keyring_dir: Path) -> None:
|
|
|
|
trust = certificate_trust(
|
|
|
|
test_keyring_certificates[Username("foobar")][0],
|
|
|
|
test_main_fingerprints,
|
|
|
|
test_all_fingerprints,
|
|
|
|
)
|
|
|
|
assert Trust.revoked == trust
|
|
|
|
|
|
|
|
|
|
|
|
@create_certificate(username=Username("main1"), uids=[Uid("main1 <foo@bar.xyz>")], keyring_type="main")
|
|
|
|
@create_certificate(username=Username("main2"), uids=[Uid("main2 <foo@bar.xyz>")], keyring_type="main")
|
|
|
|
@create_certificate(username=Username("main3"), uids=[Uid("main3 <foo@bar.xyz>")], keyring_type="main")
|
|
|
|
@create_certificate(username=Username("main4"), uids=[Uid("main4 <foo@bar.xyz>")], keyring_type="main")
|
|
|
|
@create_certificate(username=Username("foobar"), uids=[Uid("foobar <foo@bar.xyz>")])
|
|
|
|
@create_uid_certification(issuer=Username("main1"), certified=Username("foobar"), uid=Uid("foobar <foo@bar.xyz>"))
|
|
|
|
@create_uid_certification(issuer=Username("main2"), certified=Username("foobar"), uid=Uid("foobar <foo@bar.xyz>"))
|
|
|
|
@create_uid_certification(issuer=Username("main3"), certified=Username("foobar"), uid=Uid("foobar <foo@bar.xyz>"))
|
|
|
|
@create_uid_certification(issuer=Username("main4"), certified=Username("foobar"), uid=Uid("foobar <foo@bar.xyz>"))
|
|
|
|
@create_signature_revocation(issuer=Username("main4"), certified=Username("foobar"), uid=Uid("foobar <foo@bar.xyz>"))
|
|
|
|
def test_certificate_trust_full_remains_if_enough_sigs_present(working_dir: Path, keyring_dir: Path) -> None:
|
|
|
|
trust = certificate_trust(
|
|
|
|
test_keyring_certificates[Username("foobar")][0],
|
|
|
|
test_main_fingerprints,
|
|
|
|
test_all_fingerprints,
|
|
|
|
)
|
|
|
|
assert Trust.full == trust
|
|
|
|
|
|
|
|
|
|
|
|
@create_certificate(username=Username("main1"), uids=[Uid("main1 <foo@bar.xyz>")], keyring_type="main")
|
|
|
|
@create_certificate(username=Username("main2"), uids=[Uid("main2 <foo@bar.xyz>")], keyring_type="main")
|
|
|
|
@create_certificate(username=Username("main3"), uids=[Uid("main3 <foo@bar.xyz>")], keyring_type="main")
|
|
|
|
@create_certificate(username=Username("foobar"), uids=[Uid("foobar <foo@bar.xyz>"), Uid("old <old@old.old>")])
|
|
|
|
@create_uid_certification(issuer=Username("main1"), certified=Username("foobar"), uid=Uid("foobar <foo@bar.xyz>"))
|
|
|
|
@create_uid_certification(issuer=Username("main2"), certified=Username("foobar"), uid=Uid("foobar <foo@bar.xyz>"))
|
|
|
|
@create_signature_revocation(issuer=Username("foobar"), certified=Username("foobar"), uid=Uid("old <old@old.old>"))
|
|
|
|
def test_certificate_trust_not_revoked_if_only_one_uid_is_self_revoked(working_dir: Path, keyring_dir: Path) -> None:
|
|
|
|
trust = certificate_trust(
|
|
|
|
test_keyring_certificates[Username("foobar")][0],
|
|
|
|
test_main_fingerprints,
|
|
|
|
test_all_fingerprints,
|
|
|
|
)
|
|
|
|
assert Trust.marginal == trust
|
|
|
|
|
|
|
|
|
|
|
|
@create_certificate(username=Username("foobar"), uids=[Uid("foobar <foo@bar.xyz>"), Uid("old <old@old.old>")])
|
|
|
|
@create_signature_revocation(issuer=Username("foobar"), certified=Username("foobar"), uid=Uid("old <old@old.old>"))
|
|
|
|
def test_certificate_trust_unknown_if_only_contains_self_revoked(working_dir: Path, keyring_dir: Path) -> None:
|
|
|
|
trust = certificate_trust(
|
|
|
|
test_keyring_certificates[Username("foobar")][0],
|
|
|
|
test_main_fingerprints,
|
|
|
|
test_all_fingerprints,
|
|
|
|
)
|
|
|
|
assert Trust.unknown == trust
|
|
|
|
|
|
|
|
|
|
|
|
@create_certificate(username=Username("main1"), uids=[Uid("main1 <foo@bar.xyz>")], keyring_type="main")
|
|
|
|
@create_certificate(username=Username("foobar"), uids=[Uid("foobar <foo@bar.xyz>"), Uid("old <old@old.old>")])
|
|
|
|
@create_uid_certification(issuer=Username("main1"), certified=Username("foobar"), uid=Uid("foobar <foo@bar.xyz>"))
|
|
|
|
def test_certificate_trust_missing_signature_fingerprint_lookup(working_dir: Path, keyring_dir: Path) -> None:
|
|
|
|
with raises(Exception):
|
|
|
|
certificate_trust(
|
|
|
|
test_keyring_certificates[Username("foobar")][0],
|
|
|
|
test_main_fingerprints,
|
|
|
|
set(),
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@create_certificate(username=Username("foobar"), uids=[Uid("old <old@old.old>")])
|
|
|
|
@create_signature_revocation(issuer=Username("foobar"), certified=Username("foobar"), uid=Uid("old <old@old.old>"))
|
|
|
|
def test_certificate_trust_missing_revocation_fingerprint_lookup(working_dir: Path, keyring_dir: Path) -> None:
|
|
|
|
with raises(Exception):
|
|
|
|
certificate_trust(
|
|
|
|
test_keyring_certificates[Username("foobar")][0],
|
|
|
|
test_main_fingerprints,
|
|
|
|
set(),
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@create_certificate(username=Username("main1"), uids=[Uid("main1 <foo@bar.xyz>")], keyring_type="main")
|
|
|
|
@create_certificate(username=Username("foobar"), uids=[Uid("foobar <foo@bar.xyz>")])
|
|
|
|
@create_certificate(username=Username("packager"), uids=[Uid("packager <packager@bar.xyz>")])
|
|
|
|
@create_uid_certification(issuer=Username("main1"), certified=Username("foobar"), uid=Uid("foobar <foo@bar.xyz>"))
|
|
|
|
@create_uid_certification(issuer=Username("packager"), certified=Username("foobar"), uid=Uid("foobar <foo@bar.xyz>"))
|
|
|
|
@create_signature_revocation(issuer=Username("packager"), certified=Username("foobar"), uid=Uid("foobar <foo@bar.xyz>"))
|
|
|
|
def test_certificate_trust_ignore_3rd_party_revocation(working_dir: Path, keyring_dir: Path) -> None:
|
|
|
|
trust = certificate_trust(
|
|
|
|
test_keyring_certificates[Username("foobar")][0],
|
|
|
|
test_main_fingerprints,
|
|
|
|
test_all_fingerprints,
|
|
|
|
)
|
|
|
|
assert Trust.marginal == trust
|
|
|
|
|
|
|
|
|
|
|
|
@mark.parametrize(
|
|
|
|
"trust, result",
|
|
|
|
[
|
|
|
|
(Trust.revoked, Color.RED),
|
|
|
|
(Trust.full, Color.GREEN),
|
|
|
|
(Trust.marginal, Color.YELLOW),
|
|
|
|
(Trust.unknown, Color.YELLOW),
|
|
|
|
],
|
|
|
|
)
|
|
|
|
def test_trust_color(trust: Trust, result: Color) -> None:
|
|
|
|
assert trust_color(trust) == result
|
|
|
|
|
|
|
|
|
|
|
|
@mark.parametrize(
|
|
|
|
"trust, result",
|
|
|
|
[
|
|
|
|
(Trust.revoked, "✗"),
|
|
|
|
(Trust.full, "✓"),
|
|
|
|
(Trust.marginal, "~"),
|
|
|
|
(Trust.unknown, "~"),
|
|
|
|
(None, "?"),
|
|
|
|
],
|
|
|
|
)
|
|
|
|
def test_trust_icon(trust: Trust, result: str) -> None:
|
|
|
|
assert trust_icon(trust) == result
|
|
|
|
|
|
|
|
|
|
|
|
@mark.parametrize(
|
|
|
|
"trust",
|
|
|
|
[
|
|
|
|
Trust.revoked,
|
|
|
|
Trust.full,
|
|
|
|
Trust.marginal,
|
|
|
|
Trust.unknown,
|
|
|
|
],
|
|
|
|
)
|
|
|
|
@patch("libkeyringctl.trust.trust_icon")
|
|
|
|
@patch("libkeyringctl.trust.trust_color")
|
|
|
|
def test_format_trust_label(trust_color_mock: Mock, trust_icon_mock: Mock, trust: Trust) -> None:
|
|
|
|
trust_icon_mock.return_value = "ICON"
|
|
|
|
trust_color_mock.return_value = Color.GREEN
|
|
|
|
assert f"{Color.GREEN.value}ICON {trust.name}{Color.RST.value}" == format_trust_label(trust)
|