keyringctl: Deal with multi-certificate per user files
keyringctl: Add `sanitize_certificate_file()` to potentially split per-user input files that contain more than one certificate. Change `packet_split()` to add documentation and rename the key parameter to certificate, as it is more generic. Change `convert_certificate()` to use named parameters when calling `packet_split()`. Change `convert()` to call `convert_certificate()` on a list of sanitized certificates (generated using `sanitized_certificate_file()`) to be able to deal with multi-certificate files per user.
This commit is contained in:
parent
cb8e827112
commit
7f7c2f13f0
69
keyringctl
69
keyringctl
@ -125,7 +125,7 @@ def convert_certificate(working_dir: Path, certificate: Path, name_override: Opt
|
|||||||
|
|
||||||
debug(f'Processing certificate {certificate}')
|
debug(f'Processing certificate {certificate}')
|
||||||
|
|
||||||
for packet in packet_split(working_dir, certificate):
|
for packet in packet_split(working_dir=working_dir, certificate=certificate):
|
||||||
debug(f'Processing packet {packet.name}')
|
debug(f'Processing packet {packet.name}')
|
||||||
if packet.name.endswith('--PublicKey'):
|
if packet.name.endswith('--PublicKey'):
|
||||||
pubkey = packet
|
pubkey = packet
|
||||||
@ -432,10 +432,67 @@ def packet_dump_field(packet: Path, field: str) -> str:
|
|||||||
return lines[0].split(maxsplit=1)[1]
|
return lines[0].split(maxsplit=1)[1]
|
||||||
|
|
||||||
|
|
||||||
def packet_split(working_dir: Path, key: Path) -> Iterable[Path]:
|
def sanitize_certificate_file(working_dir: Path, certificate: Path) -> List[Path]:
|
||||||
|
"""Sanitize a certificate file, potentially containing several certificates
|
||||||
|
|
||||||
|
If the input file holds several certificates, they are split into respective files below working_dir and their
|
||||||
|
paths are returned. Else the path to the input certificate file is returned.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
working_dir: Path
|
||||||
|
The path of the working directory below which to create split certificates
|
||||||
|
certificate: Path
|
||||||
|
The absolute path of a file containing one or several PGP certificates
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
List[Path]
|
||||||
|
A list of paths that either contain the input certificate or several split certificates
|
||||||
|
"""
|
||||||
|
|
||||||
|
begin_cert = "-----BEGIN PGP PUBLIC KEY BLOCK-----"
|
||||||
|
end_cert = "-----END PGP PUBLIC KEY BLOCK-----"
|
||||||
|
certificate_list: List[Path] = []
|
||||||
|
|
||||||
|
with open(file=certificate, mode="r") as certificate_file:
|
||||||
|
file = certificate_file.read()
|
||||||
|
if file.count(begin_cert) > 1 and file.count(end_cert) > 1:
|
||||||
|
debug(f"Several public keys detected in file: {certificate}")
|
||||||
|
for split_cert in [f"{cert}{end_cert}\n" for cert in list(filter(None, file.split(f"{end_cert}\n")))]:
|
||||||
|
split_cert_dir = Path(mkdtemp(dir=working_dir)).absolute()
|
||||||
|
split_cert_path = split_cert_dir / certificate.name
|
||||||
|
with open(file=split_cert_path, mode="w") as split_cert_file:
|
||||||
|
split_cert_file.write(split_cert)
|
||||||
|
debug(f"Writing split cert to file: {split_cert_path}")
|
||||||
|
certificate_list.append(split_cert_path)
|
||||||
|
return certificate_list
|
||||||
|
else:
|
||||||
|
return [certificate]
|
||||||
|
|
||||||
|
|
||||||
|
def packet_split(working_dir: Path, certificate: Path) -> Iterable[Path]:
|
||||||
|
"""Split a file containing a PGP certificate into separate packet files
|
||||||
|
|
||||||
|
The files are split using sq
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
working_dir: Path
|
||||||
|
The path of the working directory below which to create the output files
|
||||||
|
certificate: Path
|
||||||
|
The absolute path of a file containing one PGP certificate
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
Iterable[Path]
|
||||||
|
An iterable over the naturally sorted list of packet files derived from certificate
|
||||||
|
"""
|
||||||
|
|
||||||
packet_dir = Path(mkdtemp(dir=working_dir)).absolute()
|
packet_dir = Path(mkdtemp(dir=working_dir)).absolute()
|
||||||
|
|
||||||
with cwd(packet_dir):
|
with cwd(packet_dir):
|
||||||
system(['sq', 'packet', 'split', '--prefix', '', str(key)])
|
system(['sq', 'packet', 'split', '--prefix', '', str(certificate)])
|
||||||
return natural_sort_path(packet_dir.iterdir())
|
return natural_sort_path(packet_dir.iterdir())
|
||||||
|
|
||||||
|
|
||||||
@ -463,12 +520,14 @@ def convert(
|
|||||||
directories: List[Path] = []
|
directories: List[Path] = []
|
||||||
if source.is_dir():
|
if source.is_dir():
|
||||||
for key in source.iterdir():
|
for key in source.iterdir():
|
||||||
|
for sane_cert in sanitize_certificate_file(working_dir=working_dir, certificate=key):
|
||||||
directories.append(
|
directories.append(
|
||||||
convert_certificate(working_dir=working_dir, certificate=key, name_override=name_override)
|
convert_certificate(working_dir=working_dir, certificate=sane_cert, name_override=name_override)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
for sane_cert in sanitize_certificate_file(working_dir=working_dir, certificate=source):
|
||||||
directories.append(
|
directories.append(
|
||||||
convert_certificate(working_dir=working_dir, certificate=source, name_override=name_override)
|
convert_certificate(working_dir=working_dir, certificate=sane_cert, name_override=name_override)
|
||||||
)
|
)
|
||||||
|
|
||||||
for path in directories:
|
for path in directories:
|
||||||
|
Loading…
Reference in New Issue
Block a user