]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
ukify: Add --signing-provider= option 35021/head
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Tue, 5 Nov 2024 21:24:17 +0000 (22:24 +0100)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Wed, 6 Nov 2024 14:18:46 +0000 (15:18 +0100)
man/ukify.xml
src/ukify/ukify.py

index ffc406f6cef65812c4abdd23e3091e5e8ce7be9b..6a697ee6e149ef3194729b5a260cbaf06cfd85dc 100644 (file)
       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
           <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>
           <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>
           <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>
index 60f64dc817f33cba03b3af39a676c26a0b4596ce..ef4e9264c28a5fa7a16c10f9582c484f31b3df3d 100755 (executable)
@@ -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