ukify: Add --signing-provider= option

This commit is contained in:
Daan De Meyer
2024-11-06 15:18:46 +01:00
parent d835c4476b
commit 65fbf3b194
2 changed files with 53 additions and 18 deletions
+24 -11
View File
@@ -100,10 +100,12 @@
the n-th boot phase path set will be signed by the n-th key. This can be used to build different trust
policies for different phases of the boot. In the config file, <varname>PCRPrivateKey=</varname>,
<varname>PCRPublicKey=</varname>, and <varname>Phases=</varname> are grouped into separate sections,
describing separate boot phases. If <varname>SigningEngine=</varname>/<option>--signing-engine=</option>
is specified, then the private keys arguments will be passed verbatim to OpenSSL as URIs, and the public
key arguments will be loaded as X.509 certificates, so that signing can be performed with an OpenSSL
engine.</para>
describing separate boot phases. If one of
<varname>SigningEngine=</varname>/<option>--signing-engine=</option> or
<varname>SigningProvider=</varname>/<option>--signing-provider=</option> is specified, then the private
key arguments will be passed verbatim to OpenSSL as URIs, and the public key arguments will be loaded
as X.509 certificates, so that signing can be performed with an OpenSSL engine or provider
respectively.</para>
<para>If a SecureBoot signing key is provided via the
<varname>SecureBootPrivateKey=</varname>/<option>--secureboot-private-key=</option> option, the resulting
@@ -452,8 +454,9 @@
<term><option>--secureboot-private-key=<replaceable>SB_KEY</replaceable></option></term>
<listitem><para>A path to a private key to use for signing of the resulting binary. If the
<varname>SigningEngine=</varname>/<option>--signing-engine=</option> option is used, this may also be
an engine-specific designation. This option is required by
<varname>SigningEngine=</varname>/<option>--signing-engine=</option> or
<varname>SigningProvider=</varname>/<option>--signing-provider=</option> option is used, this may
also be an engine or provider specific designation. This option is required by
<varname>SecureBootSigningTool=sbsign</varname>/<option>--signtool=sbsign</option>. </para>
<xi:include href="version-info.xml" xpointer="v253"/></listitem>
@@ -464,8 +467,9 @@
<term><option>--secureboot-certificate=<replaceable>SB_CERT</replaceable></option></term>
<listitem><para>A path to a certificate to use for signing of the resulting binary. If the
<varname>SigningEngine=</varname>/<option>--signing-engine=</option> option is used, this may also
be an engine-specific designation. This option is required by
<varname>SigningEngine=</varname>/<option>--signing-engine=</option> or
<varname>SigningProvider=</varname>/<option>--signing-provider=</option> option is used, this may
also be an engine or provider specific designation. This option is required by
<varname>SecureBootSigningTool=sbsign</varname>/<option>--signtool=sbsign</option>. </para>
<xi:include href="version-info.xml" xpointer="v253"/></listitem>
@@ -506,14 +510,23 @@
<term><varname>SigningEngine=<replaceable>ENGINE</replaceable></varname></term>
<term><option>--signing-engine=<replaceable>ENGINE</replaceable></option></term>
<listitem><para>An "engine" for signing of the resulting binary. This option is currently passed
verbatim to the <option>--engine=</option> option of
<citerefentry project='archlinux'><refentrytitle>sbsign</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
<listitem><para>An OpenSSL engine to be used for signing the resulting binary and PCR measurements.
</para>
<xi:include href="version-info.xml" xpointer="v253"/></listitem>
</varlistentry>
<varlistentry>
<term><varname>SigningProvider=<replaceable>PROVIDER</replaceable></varname></term>
<term><option>--signing-provider=<replaceable>PROVIDER</replaceable></option></term>
<listitem><para>An OpenSSL provider to be used for signing the resulting binary and PCR
measurements. This option can only be used when using <command>systemd-sbsign</command> as the
signing tool.</para>
<xi:include href="version-info.xml" xpointer="v257"/></listitem>
</varlistentry>
<varlistentry>
<term><varname>SignKernel=<replaceable>BOOL</replaceable></varname></term>
<term><option>--sign-kernel</option></term>
+29 -7
View File
@@ -263,6 +263,7 @@ class UkifyConfig:
sections_by_name: dict[str, 'Section']
sign_kernel: bool
signing_engine: Optional[str]
signing_provider: Optional[str]
signtool: Optional[type['SignTool']]
splash: Optional[Path]
stub: Path
@@ -548,6 +549,11 @@ class SystemdSbSign(SignTool):
if opts.signing_engine is not None
else []
),
*(
['--private-key-source', f'provider:{opts.signing_provider}']
if opts.signing_provider is not None
else []
),
input_f,
'--output', output_f,
] # fmt: skip
@@ -745,6 +751,10 @@ def call_systemd_measure(uki: UKI, opts: UkifyConfig, profile_start: int = 0) ->
assert pub_key
extra += [f'--private-key-source=engine:{opts.signing_engine}']
extra += [f'--certificate={pub_key}']
elif opts.signing_provider is not None:
assert pub_key
extra += [f'--private-key-source=provider:{opts.signing_provider}']
extra += [f'--certificate={pub_key}']
elif pub_key:
extra += [f'--public-key={pub_key}']
extra += [f'--phase={phase_path}' for phase_path in group or ()]
@@ -999,9 +1009,9 @@ def make_uki(opts: UkifyConfig) -> None:
if pcrpkey is None:
if opts.pcr_public_keys and len(opts.pcr_public_keys) == 1:
pcrpkey = opts.pcr_public_keys[0]
# If we are getting a certificate when using an engine, we need to convert it to public key
# format
if opts.signing_engine is not None and Path(pcrpkey).exists():
# If we are getting a certificate when using an engine or provider, we need to convert it to
# public key format.
if (opts.signing_engine or opts.signing_provider) and Path(pcrpkey).exists():
from cryptography.hazmat.primitives import serialization
from cryptography.x509 import load_pem_x509_certificate
@@ -1658,6 +1668,12 @@ CONFIG_ITEMS = [
help='OpenSSL engine to use for signing',
config_key='UKI/SigningEngine',
),
ConfigItem(
'--signing-provider',
metavar='PROVIDER',
help='OpenSSL provider to use for signing',
config_key='UKI/SigningProvider',
),
ConfigItem(
'--signtool',
choices=('sbsign', 'pesign', 'systemd-sbsign'),
@@ -1673,7 +1689,7 @@ CONFIG_ITEMS = [
ConfigItem(
'--secureboot-private-key',
dest='sb_key',
help='required by --signtool=sbsign|systemd-sbsign. Path to key file or engine-specific designation for SB signing', # noqa: E501
help='required by --signtool=sbsign|systemd-sbsign. Path to key file or engine/provider designation for SB signing', # noqa: E501
config_key='UKI/SecureBootPrivateKey',
),
ConfigItem(
@@ -1722,7 +1738,7 @@ CONFIG_ITEMS = [
'--pcr-private-key',
dest='pcr_private_keys',
action='append',
help='private part of the keypair or engine-specific designation for signing PCR signatures',
help='private part of the keypair or engine/provider designation for signing PCR signatures',
config_key='PCRSignature:/PCRPrivateKey',
config_push=ConfigItem.config_set_group,
),
@@ -1732,7 +1748,7 @@ CONFIG_ITEMS = [
metavar='PATH',
type=Path,
action='append',
help='public part of the keypair or engine-specific designation for signing PCR signatures',
help='public part of the keypair or engine/provider designation for signing PCR signatures',
config_key='PCRSignature:/PCRPublicKey',
config_push=ConfigItem.config_set_group,
),
@@ -1963,7 +1979,10 @@ def finalize_options(opts: argparse.Namespace) -> None:
else:
opts.stub = Path(f'/usr/lib/systemd/boot/efi/addon{opts.efi_arch}.efi.stub')
if opts.signing_engine is None:
if opts.signing_engine and opts.signing_provider:
raise ValueError('Only one of --signing-engine= and --signing-provider= may be specified')
if opts.signing_engine is None and opts.signing_provider is None:
if opts.sb_key:
opts.sb_key = Path(opts.sb_key)
if opts.sb_cert:
@@ -1990,6 +2009,9 @@ def finalize_options(opts: argparse.Namespace) -> None:
)
opts.signtool = PeSign
if opts.signing_provider and opts.signtool != SystemdSbSign:
raise ValueError('--signing-provider= can only be used with--signtool=systemd-sbsign')
if opts.sign_kernel and not opts.sb_key and not opts.sb_cert_name:
raise ValueError(
'--sign-kernel requires either --secureboot-private-key= and --secureboot-certificate= (for sbsign) or --secureboot-certificate-name= (for pesign) to be specified' # noqa: E501