mirror of
https://github.com/systemd/systemd.git
synced 2024-12-22 17:35:35 +03:00
repart: support OpenSSL engines/providers for signing
The provider API which is new requires providers, which are not widely available and don't work very well yet, so also use a fallback with the legacy engine API.
This commit is contained in:
parent
dba0afa14e
commit
0a8264080a
@ -354,6 +354,16 @@
|
|||||||
<xi:include href="version-info.xml" xpointer="v252"/></listitem>
|
<xi:include href="version-info.xml" xpointer="v252"/></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--private-key-uri=</option></term>
|
||||||
|
|
||||||
|
<listitem><para>Takes a URI-like string referring to a private key, that will be passed to OpenSSL's
|
||||||
|
"engine" or "provider" logic. Configures the signing key to use when creating verity signature
|
||||||
|
partitions with the <varname>Verity=signature</varname> setting in partition files.</para>
|
||||||
|
|
||||||
|
<xi:include href="version-info.xml" xpointer="v256"/></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>--certificate=</option></term>
|
<term><option>--certificate=</option></term>
|
||||||
|
|
||||||
@ -616,6 +626,27 @@ systemd-confext refresh</programlisting>
|
|||||||
<citerefentry><refentrytitle>systemd-confext</refentrytitle><manvolnum>1</manvolnum></citerefentry>.</para>
|
<citerefentry><refentrytitle>systemd-confext</refentrytitle><manvolnum>1</manvolnum></citerefentry>.</para>
|
||||||
</example>
|
</example>
|
||||||
|
|
||||||
|
<example>
|
||||||
|
<title>Generate a system extension image and sign it via PKCS11</title>
|
||||||
|
|
||||||
|
<para>The following creates a system extension DDI (sysext) for an
|
||||||
|
<filename>/usr/foo</filename> update and signs it with a hardware token via PKCS11.</para>
|
||||||
|
|
||||||
|
<programlisting>mkdir tree tree/usr tree/usr/lib/extension-release.d
|
||||||
|
echo "Hello World" > tree/usr/foo
|
||||||
|
cat > tree/usr/lib/extension-release.d/extension-release.my-foo <<EOF
|
||||||
|
ID=fedora
|
||||||
|
VERSION_ID=38
|
||||||
|
IMAGE_ID=my-foo
|
||||||
|
IMAGE_VERSION=7
|
||||||
|
EOF
|
||||||
|
systemd-repart --make-ddi=sysext --private-key-uri="pkcs11:model=PKCS%2315%20emulated;manufacturer=piv_II;serial=0123456789abcdef;token=Some%20Cert" --certificate=cert.crt -s tree/ /var/lib/extensions/my-foo.sysext.raw
|
||||||
|
systemd-sysext refresh</programlisting>
|
||||||
|
|
||||||
|
<para>The DDI generated that way may be applied to the system with
|
||||||
|
<citerefentry><refentrytitle>systemd-sysext</refentrytitle><manvolnum>1</manvolnum></citerefentry>.</para>
|
||||||
|
</example>
|
||||||
|
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
<refsect1>
|
<refsect1>
|
||||||
|
@ -6506,6 +6506,7 @@ static int help(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int parse_argv(int argc, char *argv[]) {
|
static int parse_argv(int argc, char *argv[]) {
|
||||||
|
_cleanup_free_ char *private_key = NULL, *private_key_uri = NULL;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
ARG_VERSION = 0x100,
|
ARG_VERSION = 0x100,
|
||||||
@ -6526,6 +6527,7 @@ static int parse_argv(int argc, char *argv[]) {
|
|||||||
ARG_JSON,
|
ARG_JSON,
|
||||||
ARG_KEY_FILE,
|
ARG_KEY_FILE,
|
||||||
ARG_PRIVATE_KEY,
|
ARG_PRIVATE_KEY,
|
||||||
|
ARG_PRIVATE_KEY_URI,
|
||||||
ARG_CERTIFICATE,
|
ARG_CERTIFICATE,
|
||||||
ARG_TPM2_DEVICE,
|
ARG_TPM2_DEVICE,
|
||||||
ARG_TPM2_DEVICE_KEY,
|
ARG_TPM2_DEVICE_KEY,
|
||||||
@ -6566,6 +6568,7 @@ static int parse_argv(int argc, char *argv[]) {
|
|||||||
{ "json", required_argument, NULL, ARG_JSON },
|
{ "json", required_argument, NULL, ARG_JSON },
|
||||||
{ "key-file", required_argument, NULL, ARG_KEY_FILE },
|
{ "key-file", required_argument, NULL, ARG_KEY_FILE },
|
||||||
{ "private-key", required_argument, NULL, ARG_PRIVATE_KEY },
|
{ "private-key", required_argument, NULL, ARG_PRIVATE_KEY },
|
||||||
|
{ "private-key-uri", required_argument, NULL, ARG_PRIVATE_KEY_URI },
|
||||||
{ "certificate", required_argument, NULL, ARG_CERTIFICATE },
|
{ "certificate", required_argument, NULL, ARG_CERTIFICATE },
|
||||||
{ "tpm2-device", required_argument, NULL, ARG_TPM2_DEVICE },
|
{ "tpm2-device", required_argument, NULL, ARG_TPM2_DEVICE },
|
||||||
{ "tpm2-device-key", required_argument, NULL, ARG_TPM2_DEVICE_KEY },
|
{ "tpm2-device-key", required_argument, NULL, ARG_TPM2_DEVICE_KEY },
|
||||||
@ -6751,20 +6754,14 @@ static int parse_argv(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case ARG_PRIVATE_KEY: {
|
case ARG_PRIVATE_KEY: {
|
||||||
_cleanup_(erase_and_freep) char *k = NULL;
|
r = free_and_strdup_warn(&private_key, optarg);
|
||||||
size_t n = 0;
|
|
||||||
|
|
||||||
r = read_full_file_full(
|
|
||||||
AT_FDCWD, optarg, UINT64_MAX, SIZE_MAX,
|
|
||||||
READ_FULL_FILE_SECURE|READ_FULL_FILE_WARN_WORLD_READABLE|READ_FULL_FILE_CONNECT_SOCKET,
|
|
||||||
NULL,
|
|
||||||
&k, &n);
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to read key file '%s': %m", optarg);
|
return r;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
EVP_PKEY_free(arg_private_key);
|
case ARG_PRIVATE_KEY_URI: {
|
||||||
arg_private_key = NULL;
|
r = free_and_strdup_warn(&private_key_uri, optarg);
|
||||||
r = parse_private_key(k, n, &arg_private_key);
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
break;
|
break;
|
||||||
@ -7101,6 +7098,38 @@ static int parse_argv(int argc, char *argv[]) {
|
|||||||
*p = gpt_partition_type_override_architecture(*p, arg_architecture);
|
*p = gpt_partition_type_override_architecture(*p, arg_architecture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (private_key && private_key_uri)
|
||||||
|
return log_error_errno(
|
||||||
|
SYNTHETIC_ERRNO(EINVAL),
|
||||||
|
"Cannot specify both --private-key= and --private-key-uri=.");
|
||||||
|
|
||||||
|
if (private_key) {
|
||||||
|
_cleanup_(erase_and_freep) char *k = NULL;
|
||||||
|
size_t n = 0;
|
||||||
|
|
||||||
|
r = read_full_file_full(
|
||||||
|
AT_FDCWD, private_key, UINT64_MAX, SIZE_MAX,
|
||||||
|
READ_FULL_FILE_SECURE|READ_FULL_FILE_WARN_WORLD_READABLE|READ_FULL_FILE_CONNECT_SOCKET,
|
||||||
|
NULL,
|
||||||
|
&k, &n);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to read key file '%s': %m", private_key);
|
||||||
|
|
||||||
|
r = parse_private_key(k, n, &arg_private_key);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
} else if (private_key_uri) {
|
||||||
|
/* This must happen after parse_x509_certificate() is called above, otherwise
|
||||||
|
* signing later will get stuck as the parsed private key won't have the
|
||||||
|
* certificate, so this block cannot be inline in ARG_PRIVATE_KEY. */
|
||||||
|
r = openssl_load_key_from_token(private_key_uri, &arg_private_key);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(
|
||||||
|
r,
|
||||||
|
"Failed to load key '%s' from OpenSSL provider: %m",
|
||||||
|
private_key);
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user