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 filter_fingerprints_by_trust
|
||||||
from .util import get_cert_paths
|
from .util import get_cert_paths
|
||||||
from .util import system
|
from .util import system
|
||||||
|
from .util import get_fingerprint_from_partial
|
||||||
from .util import transform_fd_to_tmpfile
|
from .util import transform_fd_to_tmpfile
|
||||||
|
|
||||||
|
|
||||||
@ -176,7 +177,13 @@ def convert_certificate( # noqa: ignore=C901
|
|||||||
if not certificate_fingerprint:
|
if not certificate_fingerprint:
|
||||||
raise Exception('missing certificate fingerprint for "{packet.name}"')
|
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")
|
signature_type = packet_dump_field(packet, "Type")
|
||||||
|
|
||||||
if current_packet_mode == "pubkey":
|
if current_packet_mode == "pubkey":
|
||||||
@ -209,6 +216,12 @@ def convert_certificate( # noqa: ignore=C901
|
|||||||
if not current_packet_fingerprint:
|
if not current_packet_fingerprint:
|
||||||
raise Exception('missing current packet fingerprint for "{packet.name}"')
|
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":
|
if signature_type == "SubkeyBinding":
|
||||||
subkey_bindings[current_packet_fingerprint].append(packet)
|
subkey_bindings[current_packet_fingerprint].append(packet)
|
||||||
elif signature_type == "SubkeyRevocation":
|
elif signature_type == "SubkeyRevocation":
|
||||||
@ -260,11 +273,13 @@ def convert_certificate( # noqa: ignore=C901
|
|||||||
persist_subkey_bindings(
|
persist_subkey_bindings(
|
||||||
key_dir=key_dir,
|
key_dir=key_dir,
|
||||||
subkey_bindings=subkey_bindings,
|
subkey_bindings=subkey_bindings,
|
||||||
|
issuer=certificate_fingerprint,
|
||||||
)
|
)
|
||||||
|
|
||||||
persist_subkey_revocations(
|
persist_subkey_revocations(
|
||||||
key_dir=key_dir,
|
key_dir=key_dir,
|
||||||
subkey_revocations=subkey_revocations,
|
subkey_revocations=subkey_revocations,
|
||||||
|
issuer=certificate_fingerprint,
|
||||||
)
|
)
|
||||||
|
|
||||||
persist_uids(
|
persist_uids(
|
||||||
@ -350,6 +365,7 @@ def persist_subkeys(
|
|||||||
def persist_subkey_bindings(
|
def persist_subkey_bindings(
|
||||||
key_dir: Path,
|
key_dir: Path,
|
||||||
subkey_bindings: Dict[Fingerprint, List[Path]],
|
subkey_bindings: Dict[Fingerprint, List[Path]],
|
||||||
|
issuer: Fingerprint,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Persist all SubkeyBinding of a root key file to file(s)
|
"""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
|
key_dir: The root directory below which the basic key material is persisted
|
||||||
subkey_bindings: The SubkeyBinding signatures of a Public-Subkey
|
subkey_bindings: The SubkeyBinding signatures of a Public-Subkey
|
||||||
|
issuer: Fingerprint of the issuer
|
||||||
"""
|
"""
|
||||||
|
|
||||||
for fingerprint, bindings in subkey_bindings.items():
|
for fingerprint, bindings in subkey_bindings.items():
|
||||||
subkey_binding = latest_certification(bindings)
|
subkey_binding = latest_certification(bindings)
|
||||||
issuer = packet_dump_field(subkey_binding, "Issuer")
|
|
||||||
output_file = key_dir / "subkey" / fingerprint / "certification" / f"{issuer}.asc"
|
output_file = key_dir / "subkey" / fingerprint / "certification" / f"{issuer}.asc"
|
||||||
output_file.parent.mkdir(parents=True, exist_ok=True)
|
output_file.parent.mkdir(parents=True, exist_ok=True)
|
||||||
debug(f"Writing file {output_file} from {str(subkey_binding)}")
|
debug(f"Writing file {output_file} from {str(subkey_binding)}")
|
||||||
@ -371,6 +387,7 @@ def persist_subkey_bindings(
|
|||||||
def persist_subkey_revocations(
|
def persist_subkey_revocations(
|
||||||
key_dir: Path,
|
key_dir: Path,
|
||||||
subkey_revocations: Dict[Fingerprint, List[Path]],
|
subkey_revocations: Dict[Fingerprint, List[Path]],
|
||||||
|
issuer: Fingerprint,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Persist the SubkeyRevocations of all Public-Subkeys of a root key to file(s)
|
"""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
|
key_dir: The root directory below which the basic key material is persisted
|
||||||
subkey_revocations: The SubkeyRevocations of PublicSubkeys of a key
|
subkey_revocations: The SubkeyRevocations of PublicSubkeys of a key
|
||||||
|
issuer: Fingerprint of the issuer
|
||||||
"""
|
"""
|
||||||
|
|
||||||
for fingerprint, revocations in subkey_revocations.items():
|
for fingerprint, revocations in subkey_revocations.items():
|
||||||
revocation = latest_certification(revocations)
|
revocation = latest_certification(revocations)
|
||||||
issuer = packet_dump_field(revocation, "Issuer")
|
|
||||||
output_file = key_dir / "subkey" / fingerprint / "revocation" / f"{issuer}.asc"
|
output_file = key_dir / "subkey" / fingerprint / "revocation" / f"{issuer}.asc"
|
||||||
output_file.parent.mkdir(parents=True, exist_ok=True)
|
output_file.parent.mkdir(parents=True, exist_ok=True)
|
||||||
debug(f"Writing file {output_file} from {revocation}")
|
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 convert_certificate
|
||||||
from libkeyringctl.keyring import export
|
from libkeyringctl.keyring import export
|
||||||
|
from libkeyringctl.keyring import get_fingerprints_from_keyring_files
|
||||||
from libkeyringctl.keyring import simplify_user_id
|
from libkeyringctl.keyring import simplify_user_id
|
||||||
from libkeyringctl.sequoia import certify
|
from libkeyringctl.sequoia import certify
|
||||||
from libkeyringctl.sequoia import key_extract_certificate
|
from libkeyringctl.sequoia import key_extract_certificate
|
||||||
@ -86,10 +87,16 @@ def create_certificate(
|
|||||||
|
|
||||||
target_dir = keyring_root / keyring_type
|
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(
|
decomposed_path: Path = convert_certificate(
|
||||||
working_dir=working_dir,
|
working_dir=working_dir,
|
||||||
certificate=certificate_file,
|
certificate=certificate_file,
|
||||||
keyring_dir=keyring_root / keyring_type,
|
keyring_dir=keyring_root / keyring_type,
|
||||||
|
fingerprint_filter=test_all_fingerprints,
|
||||||
)
|
)
|
||||||
user_dir = decomposed_path.parent
|
user_dir = decomposed_path.parent
|
||||||
(target_dir / user_dir.name).mkdir(parents=True, exist_ok=True)
|
(target_dir / user_dir.name).mkdir(parents=True, exist_ok=True)
|
||||||
@ -165,6 +172,7 @@ def create_key_revocation(
|
|||||||
working_dir=working_dir,
|
working_dir=working_dir,
|
||||||
certificate=revocation,
|
certificate=revocation,
|
||||||
keyring_dir=keyring_root / keyring_type,
|
keyring_dir=keyring_root / keyring_type,
|
||||||
|
fingerprint_filter=test_all_fingerprints,
|
||||||
)
|
)
|
||||||
user_dir = decomposed_path.parent
|
user_dir = decomposed_path.parent
|
||||||
(target_dir / user_dir.name).mkdir(parents=True, exist_ok=True)
|
(target_dir / user_dir.name).mkdir(parents=True, exist_ok=True)
|
||||||
@ -254,6 +262,7 @@ def create_signature_revocation(
|
|||||||
working_dir=working_dir,
|
working_dir=working_dir,
|
||||||
certificate=certificate_path,
|
certificate=certificate_path,
|
||||||
keyring_dir=target_dir,
|
keyring_dir=target_dir,
|
||||||
|
fingerprint_filter=test_all_fingerprints,
|
||||||
)
|
)
|
||||||
user_dir = decomposed_path.parent
|
user_dir = decomposed_path.parent
|
||||||
(target_dir / user_dir.name).mkdir(parents=True, exist_ok=True)
|
(target_dir / user_dir.name).mkdir(parents=True, exist_ok=True)
|
||||||
|
Loading…
Reference in New Issue
Block a user