summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaan De Meyer <daan.j.demeyer@gmail.com>2024-11-05 13:43:02 +0100
committerDaan De Meyer <daan.j.demeyer@gmail.com>2024-11-06 14:01:09 +0100
commit8cbd9d8328d58a69414b3ce845b29476da155f57 (patch)
treed318ad1809d1ac0fc008ace9db2ce909b1242df6
parentIntroduce systemd-sbsign to do secure boot signing (diff)
downloadsystemd-8cbd9d8328d58a69414b3ce845b29476da155f57.tar.xz
systemd-8cbd9d8328d58a69414b3ce845b29476da155f57.zip
sbsign: Add validate-key verb
This verb checks that we can load the specified private key.
-rw-r--r--man/systemd-sbsign.xml16
-rw-r--r--src/boot/sbsign.c39
-rwxr-xr-xtest/units/TEST-74-AUX-UTILS.sbsign.sh4
3 files changed, 57 insertions, 2 deletions
diff --git a/man/systemd-sbsign.xml b/man/systemd-sbsign.xml
index d7095e821c..cd7d06d79f 100644
--- a/man/systemd-sbsign.xml
+++ b/man/systemd-sbsign.xml
@@ -49,6 +49,22 @@
<xi:include href="version-info.xml" xpointer="v257"/>
</listitem>
</varlistentry>
+
+ <varlistentry>
+ <term><option>validate-key</option></term>
+
+ <listitem><para>Checks that we can load the private key specified with
+ <option>--private-key=</option>. </para>
+
+ <para>As a side effect, if the private key is loaded from a PIN-protected hardware token, this
+ command can be used to cache the PIN in the kernel keyring. The
+ <varname>$SYSTEMD_ASK_PASSWORD_KEYRING_TIMEOUT_SEC</varname> and
+ <varname>$SYSTEMD_ASK_PASSWORD_KEYRING_TYPE</varname> environment variables can be used to control
+ how long and in which kernel keyring the PIN is cached.</para>
+
+ <xi:include href="version-info.xml" xpointer="v257"/>
+ </listitem>
+ </varlistentry>
</variablelist>
</refsect1>
diff --git a/src/boot/sbsign.c b/src/boot/sbsign.c
index 2cddc62905..7dc2cc86af 100644
--- a/src/boot/sbsign.c
+++ b/src/boot/sbsign.c
@@ -42,6 +42,7 @@ static int help(int argc, char *argv[], void *userdata) {
"\n%5$sSign binaries for EFI Secure Boot%6$s\n"
"\n%3$sCommands:%4$s\n"
" sign EXEFILE Sign the given binary for EFI Secure Boot\n"
+ " validate-key Load and validate the given private key\n"
"\n%3$sOptions:%4$s\n"
" -h --help Show this help\n"
" --version Print version\n"
@@ -468,10 +469,44 @@ static int verb_sign(int argc, char *argv[], void *userdata) {
return 0;
}
+static int verb_validate_key(int argc, char *argv[], void *userdata) {
+ _cleanup_(openssl_ask_password_ui_freep) OpenSSLAskPasswordUI *ui = NULL;
+ _cleanup_(EVP_PKEY_freep) EVP_PKEY *private_key = NULL;
+ int r;
+
+ if (!arg_private_key)
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+ "No private key specified, use --private-key=.");
+
+ if (arg_private_key_source_type == OPENSSL_KEY_SOURCE_FILE) {
+ r = parse_path_argument(arg_private_key, /* suppress_root= */ false, &arg_private_key);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse private key path %s: %m", arg_private_key);
+ }
+
+ r = openssl_load_private_key(
+ arg_private_key_source_type,
+ arg_private_key_source,
+ arg_private_key,
+ &(AskPasswordRequest) {
+ .id = "sbsign-private-key-pin",
+ .keyring = arg_private_key,
+ .credential = "sbsign.private-key-pin",
+ },
+ &private_key,
+ &ui);
+ if (r < 0)
+ return log_error_errno(r, "Failed to load private key from %s: %m", arg_private_key);
+
+ puts("OK");
+ return 0;
+}
+
static int run(int argc, char *argv[]) {
static const Verb verbs[] = {
- { "help", VERB_ANY, VERB_ANY, 0, help },
- { "sign", 2, 2, 0, verb_sign },
+ { "help", VERB_ANY, VERB_ANY, 0, help },
+ { "sign", 2, 2, 0, verb_sign },
+ { "validate-key", VERB_ANY, 1, 0, verb_validate_key },
{}
};
int r;
diff --git a/test/units/TEST-74-AUX-UTILS.sbsign.sh b/test/units/TEST-74-AUX-UTILS.sbsign.sh
index fc186517d1..891a2ae8af 100755
--- a/test/units/TEST-74-AUX-UTILS.sbsign.sh
+++ b/test/units/TEST-74-AUX-UTILS.sbsign.sh
@@ -53,4 +53,8 @@ testcase_sign_systemd_boot() {
sbverify --cert /tmp/sb.crt /tmp/sdboot
}
+testcase_validate_key() {
+ /usr/lib/systemd/systemd-sbsign validate-key --certificate /tmp/sb.crt --private-key /tmp/sb.key
+}
+
run_testcases