feature(keyringctl): write all packet files with full issuer fingerprint
This avoids collision between same issuer using key-id and full fingerprint in different versions of a packet, like signature.
This commit is contained in:
parent
279765b22a
commit
d9e9453d84
@ -35,6 +35,7 @@ from .types import Username
|
||||
from .util import filter_fingerprints_by_trust
|
||||
from .util import get_cert_paths
|
||||
from .util import system
|
||||
from .util import get_fingerprint_from_partial
|
||||
from .util import transform_fd_to_tmpfile
|
||||
|
||||
|
||||
@ -176,7 +177,13 @@ def convert_certificate( # noqa: ignore=C901
|
||||
if not certificate_fingerprint:
|
||||
raise Exception('missing certificate fingerprint for "{packet.name}"')
|
||||
|
||||
issuer: Fingerprint = Fingerprint(packet_dump_field(packet, "Issuer"))
|
||||
issuer = get_fingerprint_from_partial(
|
||||
fingerprint_filter or set(), Fingerprint(packet_dump_field(packet, "Issuer"))
|
||||
)
|
||||
if not issuer:
|
||||
debug(f"failed to resolve partial fingerprint {issuer}, skipping packet")
|
||||
continue
|
||||
|
||||
signature_type = packet_dump_field(packet, "Type")
|
||||
|
||||
if current_packet_mode == "pubkey":
|
||||
@ -209,6 +216,12 @@ def convert_certificate( # noqa: ignore=C901
|
||||
if not current_packet_fingerprint:
|
||||
raise Exception('missing current packet fingerprint for "{packet.name}"')
|
||||
|
||||
issuer = get_fingerprint_from_partial(
|
||||
fingerprint_filter or set(), Fingerprint(packet_dump_field(packet, "Issuer"))
|
||||
)
|
||||
if issuer != certificate_fingerprint:
|
||||
raise Exception(f"subkey packet does not belong to {certificate_fingerprint}, issuer: {issuer}")
|
||||
|
||||
if signature_type == "SubkeyBinding":
|
||||
subkey_bindings[current_packet_fingerprint].append(packet)
|
||||
elif signature_type == "SubkeyRevocation":
|
||||
@ -260,11 +273,13 @@ def convert_certificate( # noqa: ignore=C901
|
||||
persist_subkey_bindings(
|
||||
key_dir=key_dir,
|
||||
subkey_bindings=subkey_bindings,
|
||||
issuer=certificate_fingerprint,
|
||||
)
|
||||
|
||||
persist_subkey_revocations(
|
||||
key_dir=key_dir,
|
||||
subkey_revocations=subkey_revocations,
|
||||
issuer=certificate_fingerprint,
|
||||
)
|
||||
|
||||
persist_uids(
|
||||
@ -350,6 +365,7 @@ def persist_subkeys(
|
||||
def persist_subkey_bindings(
|
||||
key_dir: Path,
|
||||
subkey_bindings: Dict[Fingerprint, List[Path]],
|
||||
issuer: Fingerprint,
|
||||
) -> None:
|
||||
"""Persist all SubkeyBinding of a root key file to file(s)
|
||||
|
||||
@ -357,11 +373,11 @@ def persist_subkey_bindings(
|
||||
----------
|
||||
key_dir: The root directory below which the basic key material is persisted
|
||||
subkey_bindings: The SubkeyBinding signatures of a Public-Subkey
|
||||
issuer: Fingerprint of the issuer
|
||||
"""
|
||||
|
||||
for fingerprint, bindings in subkey_bindings.items():
|
||||
subkey_binding = latest_certification(bindings)
|
||||
issuer = packet_dump_field(subkey_binding, "Issuer")
|
||||
output_file = key_dir / "subkey" / fingerprint / "certification" / f"{issuer}.asc"
|
||||
output_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
debug(f"Writing file {output_file} from {str(subkey_binding)}")
|
||||
@ -371,6 +387,7 @@ def persist_subkey_bindings(
|
||||
def persist_subkey_revocations(
|
||||
key_dir: Path,
|
||||
subkey_revocations: Dict[Fingerprint, List[Path]],
|
||||
issuer: Fingerprint,
|
||||
) -> None:
|
||||
"""Persist the SubkeyRevocations of all Public-Subkeys of a root key to file(s)
|
||||
|
||||
@ -378,11 +395,11 @@ def persist_subkey_revocations(
|
||||
----------
|
||||
key_dir: The root directory below which the basic key material is persisted
|
||||
subkey_revocations: The SubkeyRevocations of PublicSubkeys of a key
|
||||
issuer: Fingerprint of the issuer
|
||||
"""
|
||||
|
||||
for fingerprint, revocations in subkey_revocations.items():
|
||||
revocation = latest_certification(revocations)
|
||||
issuer = packet_dump_field(revocation, "Issuer")
|
||||
output_file = key_dir / "subkey" / fingerprint / "revocation" / f"{issuer}.asc"
|
||||
output_file.parent.mkdir(parents=True, exist_ok=True)
|
||||
debug(f"Writing file {output_file} from {revocation}")
|
||||
|
@ -18,6 +18,7 @@ from pytest import fixture
|
||||
|
||||
from libkeyringctl.keyring import convert_certificate
|
||||
from libkeyringctl.keyring import export
|
||||
from libkeyringctl.keyring import get_fingerprints_from_keyring_files
|
||||
from libkeyringctl.keyring import simplify_user_id
|
||||
from libkeyringctl.sequoia import certify
|
||||
from libkeyringctl.sequoia import key_extract_certificate
|
||||
@ -86,10 +87,16 @@ def create_certificate(
|
||||
|
||||
target_dir = keyring_root / keyring_type
|
||||
|
||||
for fingerprint in get_fingerprints_from_keyring_files(
|
||||
working_dir=working_dir, source=[certificate_file]
|
||||
).keys():
|
||||
test_all_fingerprints.add(fingerprint)
|
||||
|
||||
decomposed_path: Path = convert_certificate(
|
||||
working_dir=working_dir,
|
||||
certificate=certificate_file,
|
||||
keyring_dir=keyring_root / keyring_type,
|
||||
fingerprint_filter=test_all_fingerprints,
|
||||
)
|
||||
user_dir = decomposed_path.parent
|
||||
(target_dir / user_dir.name).mkdir(parents=True, exist_ok=True)
|
||||
@ -165,6 +172,7 @@ def create_key_revocation(
|
||||
working_dir=working_dir,
|
||||
certificate=revocation,
|
||||
keyring_dir=keyring_root / keyring_type,
|
||||
fingerprint_filter=test_all_fingerprints,
|
||||
)
|
||||
user_dir = decomposed_path.parent
|
||||
(target_dir / user_dir.name).mkdir(parents=True, exist_ok=True)
|
||||
@ -254,6 +262,7 @@ def create_signature_revocation(
|
||||
working_dir=working_dir,
|
||||
certificate=certificate_path,
|
||||
keyring_dir=target_dir,
|
||||
fingerprint_filter=test_all_fingerprints,
|
||||
)
|
||||
user_dir = decomposed_path.parent
|
||||
(target_dir / user_dir.name).mkdir(parents=True, exist_ok=True)
|
||||
|
Loading…
Reference in New Issue
Block a user