mirror of
https://github.com/systemd/systemd
synced 2024-10-15 04:24:19 +00:00
Merge pull request #31274 from bluca/measure_engine
repart/measure/ukify: add support for OpenSSL engines/providers
This commit is contained in:
commit
5db99d6651
|
@ -129,14 +129,6 @@ All tools:
|
||||||
* `$SYSTEMD_VERITY_SHARING=0` — if set, sharing dm-verity devices by
|
* `$SYSTEMD_VERITY_SHARING=0` — if set, sharing dm-verity devices by
|
||||||
using a stable `<ROOTHASH>-verity` device mapper name will be disabled.
|
using a stable `<ROOTHASH>-verity` device mapper name will be disabled.
|
||||||
|
|
||||||
* `$SYSTEMD_OPENSSL_KEY_LOADER`— when using OpenSSL to load a key via an engine
|
|
||||||
or a provider, can be used to force the usage of one or the other interface.
|
|
||||||
Set to 'engine' to force the usage of the old engine API, and to 'provider'
|
|
||||||
force the usage of the new provider API. If unset, the provider will be tried
|
|
||||||
first and the engine as a fallback if that fails. Providers are the new OpenSSL
|
|
||||||
3 API, but there are very few if any in a production-ready state, so engines
|
|
||||||
are still needed.
|
|
||||||
|
|
||||||
`systemctl`:
|
`systemctl`:
|
||||||
|
|
||||||
* `$SYSTEMCTL_FORCE_BUS=1` — if set, do not connect to PID 1's private D-Bus
|
* `$SYSTEMCTL_FORCE_BUS=1` — if set, do not connect to PID 1's private D-Bus
|
||||||
|
|
|
@ -158,6 +158,7 @@
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>--private-key=<replaceable>PATH</replaceable></option></term>
|
<term><option>--private-key=<replaceable>PATH</replaceable></option></term>
|
||||||
<term><option>--public-key=<replaceable>PATH</replaceable></option></term>
|
<term><option>--public-key=<replaceable>PATH</replaceable></option></term>
|
||||||
|
<term><option>--certificate=<replaceable>PATH</replaceable></option></term>
|
||||||
|
|
||||||
<listitem><para>These switches take paths to a pair of PEM encoded RSA key files, for use with
|
<listitem><para>These switches take paths to a pair of PEM encoded RSA key files, for use with
|
||||||
the <command>sign</command> command.</para>
|
the <command>sign</command> command.</para>
|
||||||
|
@ -172,9 +173,26 @@
|
||||||
<para>If the <option>--public-key=</option> is not specified but <option>--private-key=</option> is
|
<para>If the <option>--public-key=</option> is not specified but <option>--private-key=</option> is
|
||||||
specified the public key is automatically derived from the private key.</para>
|
specified the public key is automatically derived from the private key.</para>
|
||||||
|
|
||||||
|
<para><option>--certificate=</option> can be used to specify an X.509 certificate as an alternative
|
||||||
|
to <option>--public-key=</option> since v256.</para>
|
||||||
|
|
||||||
<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=<replaceable>PATH/URI</replaceable></option></term>
|
||||||
|
<term><option>--private-key-source=<replaceable>TYPE[:NAME]</replaceable></option></term>
|
||||||
|
<term><option>--certificate=<replaceable>PATH</replaceable></option></term>
|
||||||
|
|
||||||
|
<listitem><para>As an alternative to <option>--public-key=</option> for the
|
||||||
|
<command>sign</command> command, these switches can be used to sign with an hardware token. The
|
||||||
|
private key option can take a path or a URI that will be passed to the OpenSSL engine or
|
||||||
|
provider, as specified by <option>--private-key-source=</option> as a type:name tuple, such as
|
||||||
|
engine:pkcs11. The specified OpenSSL signing engine or provider will be used to sign.</para>
|
||||||
|
|
||||||
|
<xi:include href="version-info.xml" xpointer="v256"/></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>--tpm2-device=</option><replaceable>PATH</replaceable></term>
|
<term><option>--tpm2-device=</option><replaceable>PATH</replaceable></term>
|
||||||
|
|
||||||
|
|
|
@ -355,11 +355,13 @@
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>--private-key-uri=</option></term>
|
<term><option>--private-key-source=</option></term>
|
||||||
|
|
||||||
<listitem><para>Takes a URI-like string referring to a private key, that will be passed to OpenSSL's
|
<listitem><para>Takes one of <literal>file</literal>, <literal>engine</literal> or
|
||||||
"engine" or "provider" logic. Configures the signing key to use when creating verity signature
|
<literal>provider</literal>. In the latter two cases, it is followed by the name of a provider or
|
||||||
partitions with the <varname>Verity=signature</varname> setting in partition files.</para>
|
engine, separated by colon, that will be passed to OpenSSL's "engine" or "provider" logic.
|
||||||
|
Configures the signing mechanism 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>
|
<xi:include href="version-info.xml" xpointer="v256"/></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
@ -662,7 +664,7 @@ VERSION_ID=38
|
||||||
IMAGE_ID=my-foo
|
IMAGE_ID=my-foo
|
||||||
IMAGE_VERSION=7
|
IMAGE_VERSION=7
|
||||||
EOF
|
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-repart --make-ddi=sysext --private-key-source=engine:pkcs11 --private-key="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>
|
systemd-sysext refresh</programlisting>
|
||||||
|
|
||||||
<para>The DDI generated that way may be applied to the system with
|
<para>The DDI generated that way may be applied to the system with
|
||||||
|
|
|
@ -99,7 +99,10 @@
|
||||||
the n-th boot phase path set will be signed by the n-th key. This can be used to build different trust
|
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>,
|
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,
|
<varname>PCRPublicKey=</varname>, and <varname>Phases=</varname> are grouped into separate sections,
|
||||||
describing separate boot phases.</para>
|
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 perfomed with an OpenSSL
|
||||||
|
engine.</para>
|
||||||
|
|
||||||
<para>If a SecureBoot signing key is provided via the
|
<para>If a SecureBoot signing key is provided via the
|
||||||
<varname>SecureBootPrivateKey=</varname>/<option>--secureboot-private-key=</option> option, the resulting
|
<varname>SecureBootPrivateKey=</varname>/<option>--secureboot-private-key=</option> option, the resulting
|
||||||
|
|
|
@ -30,7 +30,10 @@ static char *arg_sections[_UNIFIED_SECTION_MAX] = {};
|
||||||
static char **arg_banks = NULL;
|
static char **arg_banks = NULL;
|
||||||
static char *arg_tpm2_device = NULL;
|
static char *arg_tpm2_device = NULL;
|
||||||
static char *arg_private_key = NULL;
|
static char *arg_private_key = NULL;
|
||||||
|
static KeySourceType arg_private_key_source_type = OPENSSL_KEY_SOURCE_FILE;
|
||||||
|
static char *arg_private_key_source = NULL;
|
||||||
static char *arg_public_key = NULL;
|
static char *arg_public_key = NULL;
|
||||||
|
static char *arg_certificate = NULL;
|
||||||
static JsonFormatFlags arg_json_format_flags = JSON_FORMAT_PRETTY_AUTO|JSON_FORMAT_COLOR_AUTO|JSON_FORMAT_OFF;
|
static JsonFormatFlags arg_json_format_flags = JSON_FORMAT_PRETTY_AUTO|JSON_FORMAT_COLOR_AUTO|JSON_FORMAT_OFF;
|
||||||
static PagerFlags arg_pager_flags = 0;
|
static PagerFlags arg_pager_flags = 0;
|
||||||
static bool arg_current = false;
|
static bool arg_current = false;
|
||||||
|
@ -40,7 +43,9 @@ static char *arg_append = NULL;
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_banks, strv_freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_banks, strv_freep);
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_tpm2_device, freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_tpm2_device, freep);
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_private_key, freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_private_key, freep);
|
||||||
|
STATIC_DESTRUCTOR_REGISTER(arg_private_key_source, freep);
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_public_key, freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_public_key, freep);
|
||||||
|
STATIC_DESTRUCTOR_REGISTER(arg_certificate, freep);
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_phase, strv_freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_phase, strv_freep);
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_append, freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_append, freep);
|
||||||
|
|
||||||
|
@ -74,7 +79,11 @@ static int help(int argc, char *argv[], void *userdata) {
|
||||||
" --bank=DIGEST Select TPM bank (SHA1, SHA256, SHA384, SHA512)\n"
|
" --bank=DIGEST Select TPM bank (SHA1, SHA256, SHA384, SHA512)\n"
|
||||||
" --tpm2-device=PATH Use specified TPM2 device\n"
|
" --tpm2-device=PATH Use specified TPM2 device\n"
|
||||||
" --private-key=KEY Private key (PEM) to sign with\n"
|
" --private-key=KEY Private key (PEM) to sign with\n"
|
||||||
|
" --private-key-source=file|provider:PROVIDER|engine:ENGINE\n"
|
||||||
|
" Specify how to use the --private-key=. Allows to use\n"
|
||||||
|
" an OpenSSL engine/provider when signing\n"
|
||||||
" --public-key=KEY Public key (PEM) to validate against\n"
|
" --public-key=KEY Public key (PEM) to validate against\n"
|
||||||
|
" --certificate=PATH PEM certificate to use when signing with a URI\n"
|
||||||
" --json=MODE Output as JSON\n"
|
" --json=MODE Output as JSON\n"
|
||||||
" -j Same as --json=pretty on tty, --json=short otherwise\n"
|
" -j Same as --json=pretty on tty, --json=short otherwise\n"
|
||||||
" --append=PATH Load specified JSON signature, and append new signature to it\n"
|
" --append=PATH Load specified JSON signature, and append new signature to it\n"
|
||||||
|
@ -133,7 +142,9 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
ARG_PCRPKEY = _ARG_SECTION_LAST,
|
ARG_PCRPKEY = _ARG_SECTION_LAST,
|
||||||
ARG_BANK,
|
ARG_BANK,
|
||||||
ARG_PRIVATE_KEY,
|
ARG_PRIVATE_KEY,
|
||||||
|
ARG_PRIVATE_KEY_SOURCE,
|
||||||
ARG_PUBLIC_KEY,
|
ARG_PUBLIC_KEY,
|
||||||
|
ARG_CERTIFICATE,
|
||||||
ARG_TPM2_DEVICE,
|
ARG_TPM2_DEVICE,
|
||||||
ARG_JSON,
|
ARG_JSON,
|
||||||
ARG_PHASE,
|
ARG_PHASE,
|
||||||
|
@ -141,26 +152,28 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct option options[] = {
|
static const struct option options[] = {
|
||||||
{ "help", no_argument, NULL, 'h' },
|
{ "help", no_argument, NULL, 'h' },
|
||||||
{ "no-pager", no_argument, NULL, ARG_NO_PAGER },
|
{ "no-pager", no_argument, NULL, ARG_NO_PAGER },
|
||||||
{ "version", no_argument, NULL, ARG_VERSION },
|
{ "version", no_argument, NULL, ARG_VERSION },
|
||||||
{ "linux", required_argument, NULL, ARG_LINUX },
|
{ "linux", required_argument, NULL, ARG_LINUX },
|
||||||
{ "osrel", required_argument, NULL, ARG_OSREL },
|
{ "osrel", required_argument, NULL, ARG_OSREL },
|
||||||
{ "cmdline", required_argument, NULL, ARG_CMDLINE },
|
{ "cmdline", required_argument, NULL, ARG_CMDLINE },
|
||||||
{ "initrd", required_argument, NULL, ARG_INITRD },
|
{ "initrd", required_argument, NULL, ARG_INITRD },
|
||||||
{ "splash", required_argument, NULL, ARG_SPLASH },
|
{ "splash", required_argument, NULL, ARG_SPLASH },
|
||||||
{ "dtb", required_argument, NULL, ARG_DTB },
|
{ "dtb", required_argument, NULL, ARG_DTB },
|
||||||
{ "uname", required_argument, NULL, ARG_UNAME },
|
{ "uname", required_argument, NULL, ARG_UNAME },
|
||||||
{ "sbat", required_argument, NULL, ARG_SBAT },
|
{ "sbat", required_argument, NULL, ARG_SBAT },
|
||||||
{ "pcrpkey", required_argument, NULL, ARG_PCRPKEY },
|
{ "pcrpkey", required_argument, NULL, ARG_PCRPKEY },
|
||||||
{ "current", no_argument, NULL, 'c' },
|
{ "current", no_argument, NULL, 'c' },
|
||||||
{ "bank", required_argument, NULL, ARG_BANK },
|
{ "bank", required_argument, NULL, ARG_BANK },
|
||||||
{ "tpm2-device", required_argument, NULL, ARG_TPM2_DEVICE },
|
{ "tpm2-device", required_argument, NULL, ARG_TPM2_DEVICE },
|
||||||
{ "private-key", required_argument, NULL, ARG_PRIVATE_KEY },
|
{ "private-key", required_argument, NULL, ARG_PRIVATE_KEY },
|
||||||
{ "public-key", required_argument, NULL, ARG_PUBLIC_KEY },
|
{ "private-key-source", required_argument, NULL, ARG_PRIVATE_KEY_SOURCE },
|
||||||
{ "json", required_argument, NULL, ARG_JSON },
|
{ "public-key", required_argument, NULL, ARG_PUBLIC_KEY },
|
||||||
{ "phase", required_argument, NULL, ARG_PHASE },
|
{ "certificate", required_argument, NULL, ARG_CERTIFICATE },
|
||||||
{ "append", required_argument, NULL, ARG_APPEND },
|
{ "json", required_argument, NULL, ARG_JSON },
|
||||||
|
{ "phase", required_argument, NULL, ARG_PHASE },
|
||||||
|
{ "append", required_argument, NULL, ARG_APPEND },
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -213,7 +226,17 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
case ARG_PRIVATE_KEY:
|
case ARG_PRIVATE_KEY:
|
||||||
r = parse_path_argument(optarg, /* suppress_root= */ false, &arg_private_key);
|
r = free_and_strdup_warn(&arg_private_key, optarg);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ARG_PRIVATE_KEY_SOURCE:
|
||||||
|
r = parse_openssl_key_source_argument(
|
||||||
|
optarg,
|
||||||
|
&arg_private_key_source,
|
||||||
|
&arg_private_key_source_type);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
@ -226,6 +249,13 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ARG_CERTIFICATE:
|
||||||
|
r = parse_path_argument(optarg, /* suppress_root= */ false, &arg_certificate);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
case ARG_TPM2_DEVICE: {
|
case ARG_TPM2_DEVICE: {
|
||||||
_cleanup_free_ char *device = NULL;
|
_cleanup_free_ char *device = NULL;
|
||||||
|
|
||||||
|
@ -281,6 +311,12 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
assert_not_reached();
|
assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (arg_public_key && arg_certificate)
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Both --public-key= and --certificate= specified, refusing.");
|
||||||
|
|
||||||
|
if (arg_private_key_source && !arg_certificate)
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "When using --private-key-source=, --certificate= must be specified.");
|
||||||
|
|
||||||
if (strv_isempty(arg_banks)) {
|
if (strv_isempty(arg_banks)) {
|
||||||
/* If no banks are specifically selected, pick all known banks */
|
/* If no banks are specifically selected, pick all known banks */
|
||||||
arg_banks = strv_new("SHA1", "SHA256", "SHA384", "SHA512");
|
arg_banks = strv_new("SHA1", "SHA256", "SHA384", "SHA512");
|
||||||
|
@ -731,7 +767,7 @@ static int verb_sign(int argc, char *argv[], void *userdata) {
|
||||||
_cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
|
_cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
|
||||||
_cleanup_(pcr_state_free_all) PcrState *pcr_states = NULL;
|
_cleanup_(pcr_state_free_all) PcrState *pcr_states = NULL;
|
||||||
_cleanup_(EVP_PKEY_freep) EVP_PKEY *privkey = NULL, *pubkey = NULL;
|
_cleanup_(EVP_PKEY_freep) EVP_PKEY *privkey = NULL, *pubkey = NULL;
|
||||||
_cleanup_fclose_ FILE *privkeyf = NULL;
|
_cleanup_(X509_freep) X509 *certificate = NULL;
|
||||||
size_t n;
|
size_t n;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
@ -759,13 +795,57 @@ static int verb_sign(int argc, char *argv[], void *userdata) {
|
||||||
/* When signing we only support JSON output */
|
/* When signing we only support JSON output */
|
||||||
arg_json_format_flags &= ~JSON_FORMAT_OFF;
|
arg_json_format_flags &= ~JSON_FORMAT_OFF;
|
||||||
|
|
||||||
privkeyf = fopen(arg_private_key, "re");
|
/* This must be done before openssl_load_key_from_token() otherwise it will get stuck */
|
||||||
if (!privkeyf)
|
if (arg_certificate) {
|
||||||
return log_error_errno(errno, "Failed to open private key file '%s': %m", arg_private_key);
|
_cleanup_(BIO_freep) BIO *cb = NULL;
|
||||||
|
_cleanup_free_ char *crt = NULL;
|
||||||
|
|
||||||
privkey = PEM_read_PrivateKey(privkeyf, NULL, NULL, NULL);
|
r = read_full_file_full(
|
||||||
if (!privkey)
|
AT_FDCWD, arg_certificate, UINT64_MAX, SIZE_MAX,
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to parse private key '%s'.", arg_private_key);
|
READ_FULL_FILE_CONNECT_SOCKET,
|
||||||
|
/* bind_name= */ NULL,
|
||||||
|
&crt, &n);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to read certificate file '%s': %m", arg_certificate);
|
||||||
|
|
||||||
|
cb = BIO_new_mem_buf(crt, n);
|
||||||
|
if (!cb)
|
||||||
|
return log_oom();
|
||||||
|
|
||||||
|
certificate = PEM_read_bio_X509(cb, NULL, NULL, NULL);
|
||||||
|
if (!certificate)
|
||||||
|
return log_error_errno(
|
||||||
|
SYNTHETIC_ERRNO(EBADMSG),
|
||||||
|
"Failed to parse X.509 certificate: %s",
|
||||||
|
ERR_error_string(ERR_get_error(), NULL));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arg_private_key_source_type == OPENSSL_KEY_SOURCE_FILE) {
|
||||||
|
_cleanup_fclose_ FILE *privkeyf = NULL;
|
||||||
|
_cleanup_free_ char *resolved_pkey = NULL;
|
||||||
|
|
||||||
|
r = parse_path_argument(arg_private_key, /* suppress_root= */ false, &resolved_pkey);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to parse private key path %s: %m", arg_private_key);
|
||||||
|
|
||||||
|
privkeyf = fopen(resolved_pkey, "re");
|
||||||
|
if (!privkeyf)
|
||||||
|
return log_error_errno(errno, "Failed to open private key file '%s': %m", resolved_pkey);
|
||||||
|
|
||||||
|
privkey = PEM_read_PrivateKey(privkeyf, NULL, NULL, NULL);
|
||||||
|
if (!privkey)
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to parse private key '%s'.", resolved_pkey);
|
||||||
|
} else if (arg_private_key_source &&
|
||||||
|
IN_SET(arg_private_key_source_type, OPENSSL_KEY_SOURCE_ENGINE, OPENSSL_KEY_SOURCE_PROVIDER)) {
|
||||||
|
r = openssl_load_key_from_token(
|
||||||
|
arg_private_key_source_type, arg_private_key_source, arg_private_key, &privkey);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(
|
||||||
|
r,
|
||||||
|
"Failed to load key '%s' from OpenSSL key source %s: %m",
|
||||||
|
arg_private_key,
|
||||||
|
arg_private_key_source);
|
||||||
|
}
|
||||||
|
|
||||||
if (arg_public_key) {
|
if (arg_public_key) {
|
||||||
_cleanup_fclose_ FILE *pubkeyf = NULL;
|
_cleanup_fclose_ FILE *pubkeyf = NULL;
|
||||||
|
@ -777,6 +857,13 @@ static int verb_sign(int argc, char *argv[], void *userdata) {
|
||||||
pubkey = PEM_read_PUBKEY(pubkeyf, NULL, NULL, NULL);
|
pubkey = PEM_read_PUBKEY(pubkeyf, NULL, NULL, NULL);
|
||||||
if (!pubkey)
|
if (!pubkey)
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to parse public key '%s'.", arg_public_key);
|
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to parse public key '%s'.", arg_public_key);
|
||||||
|
} else if (certificate) {
|
||||||
|
pubkey = X509_get_pubkey(certificate);
|
||||||
|
if (!pubkey)
|
||||||
|
return log_error_errno(
|
||||||
|
SYNTHETIC_ERRNO(EIO),
|
||||||
|
"Failed to extract public key from certificate %s.",
|
||||||
|
arg_certificate);
|
||||||
} else {
|
} else {
|
||||||
_cleanup_(memstream_done) MemStream m = {};
|
_cleanup_(memstream_done) MemStream m = {};
|
||||||
FILE *tf;
|
FILE *tf;
|
||||||
|
|
|
@ -146,6 +146,8 @@ static bool arg_legend = true;
|
||||||
static void *arg_key = NULL;
|
static void *arg_key = NULL;
|
||||||
static size_t arg_key_size = 0;
|
static size_t arg_key_size = 0;
|
||||||
static EVP_PKEY *arg_private_key = NULL;
|
static EVP_PKEY *arg_private_key = NULL;
|
||||||
|
static KeySourceType arg_private_key_source_type = OPENSSL_KEY_SOURCE_FILE;
|
||||||
|
static char *arg_private_key_source = NULL;
|
||||||
static X509 *arg_certificate = NULL;
|
static X509 *arg_certificate = NULL;
|
||||||
static char *arg_tpm2_device = NULL;
|
static char *arg_tpm2_device = NULL;
|
||||||
static uint32_t arg_tpm2_seal_key_handle = 0;
|
static uint32_t arg_tpm2_seal_key_handle = 0;
|
||||||
|
@ -177,6 +179,7 @@ STATIC_DESTRUCTOR_REGISTER(arg_image, freep);
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_definitions, strv_freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_definitions, strv_freep);
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_key, erase_and_freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_key, erase_and_freep);
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_private_key, EVP_PKEY_freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_private_key, EVP_PKEY_freep);
|
||||||
|
STATIC_DESTRUCTOR_REGISTER(arg_private_key_source, freep);
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_certificate, X509_freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_certificate, X509_freep);
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_tpm2_device, freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_tpm2_device, freep);
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_tpm2_device_key, freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_tpm2_device_key, freep);
|
||||||
|
@ -6806,8 +6809,14 @@ static int help(void) {
|
||||||
" Specify disk image dissection policy\n"
|
" Specify disk image dissection policy\n"
|
||||||
" --definitions=DIR Find partition definitions in specified directory\n"
|
" --definitions=DIR Find partition definitions in specified directory\n"
|
||||||
" --key-file=PATH Key to use when encrypting partitions\n"
|
" --key-file=PATH Key to use when encrypting partitions\n"
|
||||||
" --private-key=PATH Private key to use when generating verity roothash\n"
|
" --private-key=PATH|URI\n"
|
||||||
" signatures\n"
|
" Private key to use when generating verity roothash\n"
|
||||||
|
" signatures, or an engine or provider specific\n"
|
||||||
|
" designation if --private-key-source= is used.\n"
|
||||||
|
" --private-key-source=file|provider:PROVIDER|engine:ENGINE\n"
|
||||||
|
" Specify how to use the --private-key=. Allows to use\n"
|
||||||
|
" an OpenSSL engine/provider when generating verity\n"
|
||||||
|
" roothash signatures\n"
|
||||||
" --certificate=PATH PEM certificate to use when generating verity\n"
|
" --certificate=PATH PEM certificate to use when generating verity\n"
|
||||||
" roothash signatures\n"
|
" roothash signatures\n"
|
||||||
" --tpm2-device=PATH Path to TPM2 device node to use\n"
|
" --tpm2-device=PATH Path to TPM2 device node to use\n"
|
||||||
|
@ -6857,7 +6866,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;
|
_cleanup_free_ char *private_key = NULL;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
ARG_VERSION = 0x100,
|
ARG_VERSION = 0x100,
|
||||||
|
@ -6878,7 +6887,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_PRIVATE_KEY_SOURCE,
|
||||||
ARG_CERTIFICATE,
|
ARG_CERTIFICATE,
|
||||||
ARG_TPM2_DEVICE,
|
ARG_TPM2_DEVICE,
|
||||||
ARG_TPM2_DEVICE_KEY,
|
ARG_TPM2_DEVICE_KEY,
|
||||||
|
@ -6921,7 +6930,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 },
|
{ "private-key-source", required_argument, NULL, ARG_PRIVATE_KEY_SOURCE },
|
||||||
{ "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 },
|
||||||
|
@ -7115,12 +7124,14 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ARG_PRIVATE_KEY_URI: {
|
case ARG_PRIVATE_KEY_SOURCE:
|
||||||
r = free_and_strdup_warn(&private_key_uri, optarg);
|
r = parse_openssl_key_source_argument(
|
||||||
|
optarg,
|
||||||
|
&arg_private_key_source,
|
||||||
|
&arg_private_key_source_type);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case ARG_CERTIFICATE: {
|
case ARG_CERTIFICATE: {
|
||||||
_cleanup_free_ char *cert = NULL;
|
_cleanup_free_ char *cert = NULL;
|
||||||
|
@ -7465,12 +7476,7 @@ 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)
|
if (private_key && arg_private_key_source_type == OPENSSL_KEY_SOURCE_FILE) {
|
||||||
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;
|
_cleanup_(erase_and_freep) char *k = NULL;
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
|
|
||||||
|
@ -7485,16 +7491,22 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
r = parse_private_key(k, n, &arg_private_key);
|
r = parse_private_key(k, n, &arg_private_key);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
} else if (private_key_uri) {
|
} else if (private_key &&
|
||||||
|
IN_SET(arg_private_key_source_type, OPENSSL_KEY_SOURCE_ENGINE, OPENSSL_KEY_SOURCE_PROVIDER)) {
|
||||||
/* This must happen after parse_x509_certificate() is called above, otherwise
|
/* 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
|
* 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. */
|
* certificate, so this block cannot be inline in ARG_PRIVATE_KEY. */
|
||||||
r = openssl_load_key_from_token(private_key_uri, &arg_private_key);
|
r = openssl_load_key_from_token(
|
||||||
|
arg_private_key_source_type,
|
||||||
|
arg_private_key_source,
|
||||||
|
private_key,
|
||||||
|
&arg_private_key);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(
|
return log_error_errno(
|
||||||
r,
|
r,
|
||||||
"Failed to load key '%s' from OpenSSL provider: %m",
|
"Failed to load key '%s' from OpenSSL private key source %s: %m",
|
||||||
private_key);
|
private_key,
|
||||||
|
arg_private_key_source);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -1366,38 +1366,25 @@ static int load_key_from_engine(const char *engine, const char *private_key_uri,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int openssl_load_key_from_token(const char *private_key_uri, EVP_PKEY **ret) {
|
int openssl_load_key_from_token(
|
||||||
_cleanup_free_ char *provider = NULL;
|
KeySourceType private_key_source_type,
|
||||||
const char *colon, *e;
|
const char *private_key_source,
|
||||||
int r;
|
const char *private_key,
|
||||||
|
EVP_PKEY **ret) {
|
||||||
|
|
||||||
assert(private_key_uri);
|
assert(IN_SET(private_key_source_type, OPENSSL_KEY_SOURCE_ENGINE, OPENSSL_KEY_SOURCE_PROVIDER));
|
||||||
|
assert(private_key_source);
|
||||||
|
assert(private_key);
|
||||||
|
|
||||||
colon = strchr(private_key_uri, ':');
|
switch (private_key_source_type) {
|
||||||
if (!colon)
|
|
||||||
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid URI '%s'", private_key_uri);
|
|
||||||
|
|
||||||
provider = strndup(private_key_uri, colon - private_key_uri);
|
case OPENSSL_KEY_SOURCE_ENGINE:
|
||||||
if (!provider)
|
return load_key_from_engine(private_key_source, private_key, ret);
|
||||||
return log_oom_debug();
|
case OPENSSL_KEY_SOURCE_PROVIDER:
|
||||||
|
return load_key_from_provider(private_key_source, private_key, ret);
|
||||||
e = secure_getenv("SYSTEMD_OPENSSL_KEY_LOADER");
|
default:
|
||||||
if (e) {
|
assert_not_reached();
|
||||||
if (streq(e, "provider"))
|
|
||||||
r = load_key_from_provider(provider, private_key_uri, ret);
|
|
||||||
else if (streq(e, "engine"))
|
|
||||||
r = load_key_from_engine(provider, private_key_uri, ret);
|
|
||||||
else
|
|
||||||
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid value for SYSTEMD_OPENSSL_KEY_LOADER: %s", e);
|
|
||||||
} else {
|
|
||||||
r = load_key_from_provider(provider, private_key_uri, ret);
|
|
||||||
if (r < 0) {
|
|
||||||
log_debug_errno(r, "Failed to load key from provider '%s', falling back to engine", provider);
|
|
||||||
r = load_key_from_engine(provider, private_key_uri, ret);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1418,3 +1405,34 @@ int x509_fingerprint(X509 *cert, uint8_t buffer[static SHA256_DIGEST_SIZE]) {
|
||||||
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "OpenSSL is not supported, cannot calculate X509 fingerprint: %m");
|
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "OpenSSL is not supported, cannot calculate X509 fingerprint: %m");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int parse_openssl_key_source_argument(
|
||||||
|
const char *argument,
|
||||||
|
char **private_key_source,
|
||||||
|
KeySourceType *private_key_source_type) {
|
||||||
|
|
||||||
|
KeySourceType type;
|
||||||
|
const char *e = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(argument);
|
||||||
|
assert(private_key_source);
|
||||||
|
assert(private_key_source_type);
|
||||||
|
|
||||||
|
if (streq(argument, "file"))
|
||||||
|
type = OPENSSL_KEY_SOURCE_FILE;
|
||||||
|
else if ((e = startswith(argument, "engine:")))
|
||||||
|
type = OPENSSL_KEY_SOURCE_ENGINE;
|
||||||
|
else if ((e = startswith(argument, "provider:")))
|
||||||
|
type = OPENSSL_KEY_SOURCE_PROVIDER;
|
||||||
|
else
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid private key source '%s'", argument);
|
||||||
|
|
||||||
|
r = free_and_strdup_warn(private_key_source, e);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
*private_key_source_type = type;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -5,6 +5,16 @@
|
||||||
#include "macro.h"
|
#include "macro.h"
|
||||||
#include "sha256.h"
|
#include "sha256.h"
|
||||||
|
|
||||||
|
typedef enum KeySourceType {
|
||||||
|
OPENSSL_KEY_SOURCE_FILE,
|
||||||
|
OPENSSL_KEY_SOURCE_ENGINE,
|
||||||
|
OPENSSL_KEY_SOURCE_PROVIDER,
|
||||||
|
_OPENSSL_KEY_SOURCE_MAX,
|
||||||
|
_OPENSSL_KEY_SOURCE_INVALID = -EINVAL,
|
||||||
|
} KeySourceType;
|
||||||
|
|
||||||
|
int parse_openssl_key_source_argument(const char *argument, char **private_key_source, KeySourceType *private_key_source_type);
|
||||||
|
|
||||||
#define X509_FINGERPRINT_SIZE SHA256_DIGEST_SIZE
|
#define X509_FINGERPRINT_SIZE SHA256_DIGEST_SIZE
|
||||||
|
|
||||||
#if HAVE_OPENSSL
|
#if HAVE_OPENSSL
|
||||||
|
@ -123,7 +133,7 @@ int pubkey_fingerprint(EVP_PKEY *pk, const EVP_MD *md, void **ret, size_t *ret_s
|
||||||
|
|
||||||
int digest_and_sign(const EVP_MD *md, EVP_PKEY *privkey, const void *data, size_t size, void **ret, size_t *ret_size);
|
int digest_and_sign(const EVP_MD *md, EVP_PKEY *privkey, const void *data, size_t size, void **ret, size_t *ret_size);
|
||||||
|
|
||||||
int openssl_load_key_from_token(const char *private_key_uri, EVP_PKEY **ret);
|
int openssl_load_key_from_token(KeySourceType private_key_source_type, const char *private_key_source, const char *private_key, EVP_PKEY **ret);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
@ -140,7 +150,12 @@ static inline void *EVP_PKEY_free(EVP_PKEY *p) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int openssl_load_key_from_token(const char *private_key_uri, EVP_PKEY **ret) {
|
static inline int openssl_load_key_from_token(
|
||||||
|
KeySourceType private_key_source_type,
|
||||||
|
const char *private_key_source,
|
||||||
|
const char *private_key,
|
||||||
|
EVP_PKEY **ret) {
|
||||||
|
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -120,7 +120,7 @@ def test_apply_config(tmp_path):
|
||||||
assert ns.sign_kernel is False
|
assert ns.sign_kernel is False
|
||||||
|
|
||||||
assert ns._groups == ['NAME']
|
assert ns._groups == ['NAME']
|
||||||
assert ns.pcr_private_keys == [pathlib.Path('some/path7')]
|
assert ns.pcr_private_keys == ['some/path7']
|
||||||
assert ns.pcr_public_keys == [pathlib.Path('some/path8')]
|
assert ns.pcr_public_keys == [pathlib.Path('some/path8')]
|
||||||
assert ns.phase_path_groups == [['enter-initrd:leave-initrd:sysinit:ready:shutdown:final']]
|
assert ns.phase_path_groups == [['enter-initrd:leave-initrd:sysinit:ready:shutdown:final']]
|
||||||
|
|
||||||
|
@ -143,7 +143,7 @@ def test_apply_config(tmp_path):
|
||||||
assert ns.sign_kernel is False
|
assert ns.sign_kernel is False
|
||||||
|
|
||||||
assert ns._groups == ['NAME']
|
assert ns._groups == ['NAME']
|
||||||
assert ns.pcr_private_keys == [pathlib.Path('some/path7')]
|
assert ns.pcr_private_keys == ['some/path7']
|
||||||
assert ns.pcr_public_keys == [pathlib.Path('some/path8')]
|
assert ns.pcr_public_keys == [pathlib.Path('some/path8')]
|
||||||
assert ns.phase_path_groups == [['enter-initrd:leave-initrd:sysinit:ready:shutdown:final']]
|
assert ns.phase_path_groups == [['enter-initrd:leave-initrd:sysinit:ready:shutdown:final']]
|
||||||
|
|
||||||
|
@ -189,7 +189,7 @@ def test_parse_args_many_deprecated():
|
||||||
assert opts.pcrpkey == pathlib.Path('PATH')
|
assert opts.pcrpkey == pathlib.Path('PATH')
|
||||||
assert opts.uname == '1.2.3'
|
assert opts.uname == '1.2.3'
|
||||||
assert opts.stub == pathlib.Path('STUBPATH')
|
assert opts.stub == pathlib.Path('STUBPATH')
|
||||||
assert opts.pcr_private_keys == [pathlib.Path('PKEY1')]
|
assert opts.pcr_private_keys == ['PKEY1']
|
||||||
assert opts.pcr_public_keys == [pathlib.Path('PKEY2')]
|
assert opts.pcr_public_keys == [pathlib.Path('PKEY2')]
|
||||||
assert opts.pcr_banks == ['SHA1', 'SHA256']
|
assert opts.pcr_banks == ['SHA1', 'SHA256']
|
||||||
assert opts.signing_engine == 'ENGINE'
|
assert opts.signing_engine == 'ENGINE'
|
||||||
|
@ -235,7 +235,7 @@ def test_parse_args_many():
|
||||||
assert opts.pcrpkey == pathlib.Path('PATH')
|
assert opts.pcrpkey == pathlib.Path('PATH')
|
||||||
assert opts.uname == '1.2.3'
|
assert opts.uname == '1.2.3'
|
||||||
assert opts.stub == pathlib.Path('STUBPATH')
|
assert opts.stub == pathlib.Path('STUBPATH')
|
||||||
assert opts.pcr_private_keys == [pathlib.Path('PKEY1')]
|
assert opts.pcr_private_keys == ['PKEY1']
|
||||||
assert opts.pcr_public_keys == [pathlib.Path('PKEY2')]
|
assert opts.pcr_public_keys == [pathlib.Path('PKEY2')]
|
||||||
assert opts.pcr_banks == ['SHA1', 'SHA256']
|
assert opts.pcr_banks == ['SHA1', 'SHA256']
|
||||||
assert opts.signing_engine == 'ENGINE'
|
assert opts.signing_engine == 'ENGINE'
|
||||||
|
@ -342,8 +342,7 @@ def test_config_priority(tmp_path):
|
||||||
assert opts.pcrpkey == pathlib.Path('PATH')
|
assert opts.pcrpkey == pathlib.Path('PATH')
|
||||||
assert opts.uname == '1.2.3'
|
assert opts.uname == '1.2.3'
|
||||||
assert opts.stub == pathlib.Path('STUBPATH')
|
assert opts.stub == pathlib.Path('STUBPATH')
|
||||||
assert opts.pcr_private_keys == [pathlib.Path('PKEY1'),
|
assert opts.pcr_private_keys == ['PKEY1', 'some/path7']
|
||||||
pathlib.Path('some/path7')]
|
|
||||||
assert opts.pcr_public_keys == [pathlib.Path('PKEY2'),
|
assert opts.pcr_public_keys == [pathlib.Path('PKEY2'),
|
||||||
pathlib.Path('some/path8')]
|
pathlib.Path('some/path8')]
|
||||||
assert opts.pcr_banks == ['SHA1', 'SHA256']
|
assert opts.pcr_banks == ['SHA1', 'SHA256']
|
||||||
|
|
|
@ -449,7 +449,7 @@ def check_cert_and_keys_nonexistent(opts):
|
||||||
*((priv_key, pub_key)
|
*((priv_key, pub_key)
|
||||||
for priv_key, pub_key, _ in key_path_groups(opts)))
|
for priv_key, pub_key, _ in key_path_groups(opts)))
|
||||||
for path in paths:
|
for path in paths:
|
||||||
if path and path.exists():
|
if path and pathlib.Path(path).exists():
|
||||||
raise ValueError(f'{path} is present')
|
raise ValueError(f'{path} is present')
|
||||||
|
|
||||||
|
|
||||||
|
@ -539,7 +539,11 @@ def call_systemd_measure(uki, linux, opts):
|
||||||
|
|
||||||
for priv_key, pub_key, group in key_path_groups(opts):
|
for priv_key, pub_key, group in key_path_groups(opts):
|
||||||
extra = [f'--private-key={priv_key}']
|
extra = [f'--private-key={priv_key}']
|
||||||
if pub_key:
|
if opts.signing_engine is not None:
|
||||||
|
assert pub_key
|
||||||
|
extra += [f'--private-key-source=engine:{opts.signing_engine}']
|
||||||
|
extra += [f'--certificate={pub_key}']
|
||||||
|
elif pub_key:
|
||||||
extra += [f'--public-key={pub_key}']
|
extra += [f'--public-key={pub_key}']
|
||||||
extra += [f'--phase={phase_path}' for phase_path in group or ()]
|
extra += [f'--phase={phase_path}' for phase_path in group or ()]
|
||||||
|
|
||||||
|
@ -728,11 +732,13 @@ def sbsign_sign(sbsign_tool, input_f, output_f, opts=None):
|
||||||
sbsign_tool,
|
sbsign_tool,
|
||||||
'--key', opts.sb_key,
|
'--key', opts.sb_key,
|
||||||
'--cert', opts.sb_cert,
|
'--cert', opts.sb_cert,
|
||||||
input_f,
|
|
||||||
'--output', output_f,
|
|
||||||
]
|
]
|
||||||
if opts.signing_engine is not None:
|
if opts.signing_engine is not None:
|
||||||
sign_invocation += ['--engine', opts.signing_engine]
|
sign_invocation += ['--engine', opts.signing_engine]
|
||||||
|
sign_invocation += [
|
||||||
|
input_f,
|
||||||
|
'--output', output_f,
|
||||||
|
]
|
||||||
signer_sign(sign_invocation)
|
signer_sign(sign_invocation)
|
||||||
|
|
||||||
def find_pesign(opts=None):
|
def find_pesign(opts=None):
|
||||||
|
@ -820,7 +826,7 @@ def make_uki(opts):
|
||||||
pcrpkey = opts.pcr_public_keys[0]
|
pcrpkey = opts.pcr_public_keys[0]
|
||||||
elif opts.pcr_private_keys and len(opts.pcr_private_keys) == 1:
|
elif opts.pcr_private_keys and len(opts.pcr_private_keys) == 1:
|
||||||
from cryptography.hazmat.primitives import serialization
|
from cryptography.hazmat.primitives import serialization
|
||||||
privkey = serialization.load_pem_private_key(opts.pcr_private_keys[0].read_bytes(), password=None)
|
privkey = serialization.load_pem_private_key(pathlib.Path(opts.pcr_private_keys[0]).read_bytes(), password=None)
|
||||||
pcrpkey = privkey.public_key().public_bytes(
|
pcrpkey = privkey.public_key().public_bytes(
|
||||||
encoding=serialization.Encoding.PEM,
|
encoding=serialization.Encoding.PEM,
|
||||||
format=serialization.PublicFormat.SubjectPublicKeyInfo,
|
format=serialization.PublicFormat.SubjectPublicKeyInfo,
|
||||||
|
@ -1002,7 +1008,7 @@ def generate_keys(opts):
|
||||||
|
|
||||||
print(f'Writing private key for PCR signing to {priv_key}')
|
print(f'Writing private key for PCR signing to {priv_key}')
|
||||||
with temporary_umask(0o077):
|
with temporary_umask(0o077):
|
||||||
priv_key.write_bytes(priv_key_pem)
|
pathlib.Path(priv_key).write_bytes(priv_key_pem)
|
||||||
if pub_key:
|
if pub_key:
|
||||||
print(f'Writing public key for PCR signing to {pub_key}')
|
print(f'Writing public key for PCR signing to {pub_key}')
|
||||||
pub_key.write_bytes(pub_key_pem)
|
pub_key.write_bytes(pub_key_pem)
|
||||||
|
@ -1405,10 +1411,8 @@ CONFIG_ITEMS = [
|
||||||
ConfigItem(
|
ConfigItem(
|
||||||
'--pcr-private-key',
|
'--pcr-private-key',
|
||||||
dest = 'pcr_private_keys',
|
dest = 'pcr_private_keys',
|
||||||
metavar = 'PATH',
|
|
||||||
type = pathlib.Path,
|
|
||||||
action = 'append',
|
action = 'append',
|
||||||
help = 'private part of the keypair for signing PCR signatures',
|
help = 'private part of the keypair or engine-specific designation for signing PCR signatures',
|
||||||
config_key = 'PCRSignature:/PCRPrivateKey',
|
config_key = 'PCRSignature:/PCRPrivateKey',
|
||||||
config_push = ConfigItem.config_set_group,
|
config_push = ConfigItem.config_set_group,
|
||||||
),
|
),
|
||||||
|
@ -1418,7 +1422,7 @@ CONFIG_ITEMS = [
|
||||||
metavar = 'PATH',
|
metavar = 'PATH',
|
||||||
type = pathlib.Path,
|
type = pathlib.Path,
|
||||||
action = 'append',
|
action = 'append',
|
||||||
help = 'public part of the keypair for signing PCR signatures',
|
help = 'public part of the keypair or engine-specific designation for signing PCR signatures',
|
||||||
config_key = 'PCRSignature:/PCRPublicKey',
|
config_key = 'PCRSignature:/PCRPublicKey',
|
||||||
config_push = ConfigItem.config_set_group,
|
config_push = ConfigItem.config_set_group,
|
||||||
),
|
),
|
||||||
|
|
Loading…
Reference in a new issue