Skip to content

Commit

Permalink
Drop support for pesign secure boot signtool
Browse files Browse the repository at this point in the history
sbsigntools is packaged in EPEL now and in the future we're looking
to standardize solely on systemd-sbsign so let's already drop support
for pesign which was only really useful on CentOS Stream because it
didn't have sbsigntools which it does have now.
  • Loading branch information
DaanDeMeyer committed Dec 23, 2024
1 parent b163238 commit 7e406bb
Show file tree
Hide file tree
Showing 9 changed files with 35 additions and 166 deletions.
71 changes: 30 additions & 41 deletions mkosi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,13 @@

from mkosi.archive import can_extract_tar, extract_tar, make_cpio, make_tar
from mkosi.bootloader import (
certificate_common_name,
efi_boot_binary,
extract_pe_section,
gen_kernel_images,
grub_bios_setup,
install_grub,
install_shim,
install_systemd_boot,
pesign_prepare,
prepare_grub_config,
python_binary,
run_systemd_sign_tool,
Expand Down Expand Up @@ -1506,51 +1504,42 @@ def run_ukify(
assert context.config.secure_boot_key
assert context.config.secure_boot_certificate

if context.config.secure_boot_sign_tool != SecureBootSignTool.pesign:
cmd += [
"--signtool", (
"sbsign"
if context.config.secure_boot_sign_tool == SecureBootSignTool.sbsign
or not context.config.find_binary("systemd-sbsign", "/usr/lib/systemd/systemd-sbsign")
else "systemd-sbsign"
),
] # fmt: skip
cmd += [
"--signtool", (
"sbsign"
if context.config.secure_boot_sign_tool == SecureBootSignTool.sbsign
or not context.config.find_binary("systemd-sbsign", "/usr/lib/systemd/systemd-sbsign")
else "systemd-sbsign"
),
] # fmt: skip

if (
context.config.secure_boot_key_source.type != KeySourceType.file
or context.config.secure_boot_certificate_source.type != CertificateSourceType.file
):
opt += ["--bind", "/run", "/run"]
if (
context.config.secure_boot_key_source.type != KeySourceType.file
or context.config.secure_boot_certificate_source.type != CertificateSourceType.file
):
opt += ["--bind", "/run", "/run"]

if context.config.secure_boot_key_source.type == KeySourceType.engine:
cmd += ["--signing-engine", context.config.secure_boot_key_source.source]
elif context.config.secure_boot_key_source.type == KeySourceType.provider:
cmd += ["--signing-provider", context.config.secure_boot_key_source.source]
if context.config.secure_boot_key_source.type == KeySourceType.engine:
cmd += ["--signing-engine", context.config.secure_boot_key_source.source]
elif context.config.secure_boot_key_source.type == KeySourceType.provider:
cmd += ["--signing-provider", context.config.secure_boot_key_source.source]

if context.config.secure_boot_key.exists():
cmd += ["--secureboot-private-key", workdir(context.config.secure_boot_key)]
opt += ["--ro-bind", context.config.secure_boot_key, workdir(context.config.secure_boot_key)]
else:
cmd += ["--secureboot-private-key", context.config.secure_boot_key]
if context.config.secure_boot_key.exists():
cmd += ["--secureboot-private-key", workdir(context.config.secure_boot_key)]
opt += ["--ro-bind", context.config.secure_boot_key, workdir(context.config.secure_boot_key)]
else:
cmd += ["--secureboot-private-key", context.config.secure_boot_key]

if context.config.secure_boot_certificate_source.type == CertificateSourceType.provider:
cmd += ["--certificate-provider", context.config.secure_boot_certificate_source.source]
if context.config.secure_boot_certificate_source.type == CertificateSourceType.provider:
cmd += ["--certificate-provider", context.config.secure_boot_certificate_source.source]

if context.config.secure_boot_certificate.exists():
cmd += ["--secureboot-certificate", workdir(context.config.secure_boot_certificate)]
opt += [
"--ro-bind", context.config.secure_boot_certificate, workdir(context.config.secure_boot_certificate), # noqa: E501
] # fmt: skip
else:
cmd += ["--secureboot-certificate", context.config.secure_boot_certificate]
else:
pesign_prepare(context)
cmd += [
"--signtool", "pesign",
"--secureboot-certificate-dir", workdir(context.workspace / "pesign"),
"--secureboot-certificate-name", certificate_common_name(context, context.config.secure_boot_certificate), # noqa: E501
if context.config.secure_boot_certificate.exists():
cmd += ["--secureboot-certificate", workdir(context.config.secure_boot_certificate)]
opt += [
"--ro-bind", context.config.secure_boot_certificate, workdir(context.config.secure_boot_certificate), # noqa: E501
] # fmt: skip
opt += ["--ro-bind", context.workspace / "pesign", workdir(context.workspace / "pesign")]
else:
cmd += ["--secureboot-certificate", context.config.secure_boot_certificate]

run(
cmd,
Expand Down
116 changes: 1 addition & 115 deletions mkosi/bootloader.py
Original file line number Diff line number Diff line change
Expand Up @@ -408,33 +408,6 @@ def shim_second_stage_binary(context: Context) -> Path:
return Path(f"efi/EFI/BOOT/grub{arch}.EFI")


def certificate_common_name(context: Context, certificate: Path) -> str:
output = run(
[
"openssl",
"x509",
"-noout",
"-subject",
"-nameopt", "multiline",
"-in", workdir(certificate),
],
stdout=subprocess.PIPE,
sandbox=context.sandbox(options=["--ro-bind", certificate, workdir(certificate)]),
).stdout # fmt: skip

for line in output.splitlines():
if not line.strip().startswith("commonName"):
continue

_, sep, value = line.partition("=")
if not sep:
die("Missing '=' delimiter in openssl output")

return value.strip()

die(f"Certificate {certificate} is missing Common Name")


def run_systemd_sign_tool(
config: Config,
*,
Expand Down Expand Up @@ -499,60 +472,6 @@ def run_systemd_sign_tool(
)


def pesign_prepare(context: Context) -> None:
assert context.config.secure_boot_key
assert context.config.secure_boot_certificate

if (context.workspace / "pesign").exists():
return

(context.workspace / "pesign").mkdir()

# pesign takes a certificate directory and a certificate common name as input arguments, so we have
# to transform our input key and cert into that format. Adapted from
# https://www.mankier.com/1/pesign#Examples-Signing_with_the_certificate_and_private_key_in_individual_files
with open(context.workspace / "secure-boot.p12", "wb") as f:
run(
[
"openssl",
"pkcs12",
"-export",
# Arcane incantation to create a pkcs12 certificate without a password.
"-keypbe", "NONE",
"-certpbe", "NONE",
"-nomaciter",
"-passout", "pass:",
"-inkey", workdir(context.config.secure_boot_key),
"-in", workdir(context.config.secure_boot_certificate),
],
stdout=f,
sandbox=context.sandbox(
options=[
"--ro-bind", context.config.secure_boot_key, workdir(context.config.secure_boot_key),
"--ro-bind", context.config.secure_boot_certificate, workdir(context.config.secure_boot_certificate), # noqa: E501
],
),
) # fmt: skip

(context.workspace / "pesign").mkdir(exist_ok=True)

run(
[
"pk12util",
"-K", "",
"-W", "",
"-i", workdir(context.workspace / "secure-boot.p12"),
"-d", workdir(context.workspace / "pesign"),
],
sandbox=context.sandbox(
options=[
"--ro-bind", context.workspace / "secure-boot.p12", workdir(context.workspace / "secure-boot.p12"), # noqa: E501
"--ro-bind", context.workspace / "pesign", workdir(context.workspace / "pesign"),
],
),
) # fmt: skip


def sign_efi_binary(context: Context, input: Path, output: Path) -> Path:
assert context.config.secure_boot_key
assert context.config.secure_boot_certificate
Expand Down Expand Up @@ -618,41 +537,8 @@ def sign_efi_binary(context: Context, input: Path, output: Path) -> Path:
devices=context.config.secure_boot_key_source.type != KeySourceType.file,
),
)
elif (
context.config.secure_boot_sign_tool == SecureBootSignTool.pesign
or context.config.secure_boot_sign_tool == SecureBootSignTool.auto
and context.config.find_binary("pesign") is not None
):
if context.config.secure_boot_certificate_source.type != CertificateSourceType.file:
die("Secure boot certificate source must be 'file' when using pesign as the signing tool")

pesign_prepare(context)
run(
[
"pesign",
"--certdir", workdir(context.workspace / "pesign"),
"--certificate", certificate_common_name(context, context.config.secure_boot_certificate),
"--sign",
"--force",
"--in", workdir(input),
"--out", workdir(output),
],
stdin=(
sys.stdin
if context.config.secure_boot_key_source.type != KeySourceType.file
else subprocess.DEVNULL
),
env=context.config.environment,
sandbox=context.sandbox(
options=[
"--ro-bind", context.workspace / "pesign", workdir(context.workspace / "pesign"),
"--ro-bind", input, workdir(input),
"--bind", output.parent, workdir(output),
]
),
) # fmt: skip
else:
die("One of sbsign or pesign is required to use SecureBoot=")
die("One of systemd-sbsign or sbsign is required to use SecureBoot=")

return output

Expand Down
1 change: 0 additions & 1 deletion mkosi/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,6 @@ def format(cls, cid: int) -> str:
class SecureBootSignTool(StrEnum):
auto = enum.auto()
sbsign = enum.auto()
pesign = enum.auto()
systemd_sbsign = enum.auto()


Expand Down
5 changes: 2 additions & 3 deletions mkosi/resources/man/mkosi.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -1138,8 +1138,8 @@ boolean argument: either `1`, `yes`, or `true` to enable, or `0`, `no`,
UEFI kernel image, if `SecureBoot=` is used.

`SecureBootSignTool=`, `--secure-boot-sign-tool`
: Tool to use to sign secure boot PE binaries. Takes one of `systemd-sbsign`, `sbsign`, `pesign` or `auto`.
Defaults to `auto`. If set to `auto`, either `systemd-sbsign`, `sbsign` or `pesign` are used if
: Tool to use to sign secure boot PE binaries. Takes one of `systemd-sbsign`, `sbsign` or `auto`.
Defaults to `auto`. If set to `auto`, either `systemd-sbsign` or `sbsign` are used if
available, with `systemd-sbsign` being preferred.

`Verity=`, `--verity=`
Expand Down Expand Up @@ -1288,7 +1288,6 @@ boolean argument: either `1`, `yes`, or `true` to enable, or `0`, `no`,
| `pkcs11-provider` | ✓ | | ✓ | ✓ | ✓ | ✓ | ✓ |
| `sed` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| `pacman` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | |
| `pesign` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| `policycoreutils` | ✓ | ✓ | ✓ | ✓ | ✓ | | ✓ |
| `qemu` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| `sbsigntools` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
Expand Down
1 change: 0 additions & 1 deletion mkosi/resources/mkosi-tools/mkosi.conf.d/10-arch.conf
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ Packages=
libseccomp
openssh
pacman
pesign
pipewire
pipewire-audio
pkcs11-provider
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,3 @@ HostArchitecture=|arm64
[Content]
Packages=
edk2-ovmf
pesign
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ Packages=
openssh-client
ovmf
pacman-package-manager
pesign
policycoreutils
python3-cryptography
python3-pefile
Expand Down
1 change: 0 additions & 1 deletion mkosi/resources/mkosi-tools/mkosi.conf.d/10-opensuse.conf
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ Packages=
openssh-clients
ovmf
patterns-base-minimal_base
pesign
pkcs11-provider
policycoreutils
python3-cryptography
Expand Down
4 changes: 2 additions & 2 deletions tests/test_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ def test_config() -> None:
"Source": "",
"Type": "file"
},
"SecureBootSignTool": "pesign",
"SecureBootSignTool": "systemd-sbsign",
"Seed": "7496d7d8-7f08-4a2b-96c6-ec8c43791b60",
"ShimBootloader": "none",
"Sign": false,
Expand Down Expand Up @@ -538,7 +538,7 @@ def test_config() -> None:
secure_boot_certificate_source=CertificateSource(type=CertificateSourceType.file),
secure_boot_key=Path("/path/to/keyfile"),
secure_boot_key_source=KeySource(type=KeySourceType.file),
secure_boot_sign_tool=SecureBootSignTool.pesign,
secure_boot_sign_tool=SecureBootSignTool.systemd_sbsign,
seed=uuid.UUID("7496d7d8-7f08-4a2b-96c6-ec8c43791b60"),
selinux_relabel=ConfigFeature.disabled,
shim_bootloader=ShimBootloader.none,
Expand Down

0 comments on commit 7e406bb

Please sign in to comment.