bootctl: Add --secure-boot-auto-enroll

When specified, bootctl install will also set up secure boot
auto-enrollment. For now, We sign all variables using the same
certificate and key pair.
This commit is contained in:
Daan De Meyer
2024-11-03 10:46:17 +01:00
parent eac5336c27
commit a07864a4fe
11 changed files with 396 additions and 4 deletions
+25
View File
@@ -526,6 +526,31 @@
<xi:include href="version-info.xml" xpointer="v253"/></listitem>
</varlistentry>
<varlistentry>
<term><option>--secure-boot-auto-enroll=yes|no</option></term>
<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>Configure the ESP for secure boot auto-enrollment when invoking the
<command>install</command> command. Takes a boolean argument. Disabled by default. Enabling this
option will make <command>bootctl</command> populate the ESP with signed <literal>PK</literal>,
<literal>KEK</literal> and <literal>db</literal> signature databases, each containing the given
certificate in <literal>DER</literal> format as their only entry. These secure boot signature
databases will be picked up and enrolled by <command>systemd-boot</command> if secure boot is in
setup mode and secure boot auto-enrollment is enabled.</para>
<para>When specifying this option, a certificate and private key have to be provided as well using
the <option>--certificate=</option> and <option>--private-key=</option> options. The
<option>--certificate=</option> option takes a path to a PEM encoded X.509 certificate. The
<option>--private-key=</option> 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
<literal>type:name</literal> tuple, such as <literal>engine:pkcs11</literal>. The specified OpenSSL
signing engine or provider will be used to sign the EFI signature lists.</para>
<xi:include href="version-info.xml" xpointer="v257"/></listitem>
</varlistentry>
<xi:include href="standard-options.xml" xpointer="no-pager"/>
<xi:include href="standard-options.xml" xpointer="json" />
<xi:include href="standard-options.xml" xpointer="help"/>
+4 -3
View File
@@ -23,9 +23,10 @@
#define EFI_VENDOR_SYSTEMD SD_ID128_MAKE(8c,f2,64,4b,4b,0b,42,8f,93,87,6d,87,60,50,dc,67)
#define EFI_VENDOR_SYSTEMD_STR SD_ID128_MAKE_UUID_STR(8c,f2,64,4b,4b,0b,42,8f,93,87,6d,87,60,50,dc,67)
#define EFI_VARIABLE_NON_VOLATILE UINT32_C(0x00000001)
#define EFI_VARIABLE_BOOTSERVICE_ACCESS UINT32_C(0x00000002)
#define EFI_VARIABLE_RUNTIME_ACCESS UINT32_C(0x00000004)
#define EFI_VARIABLE_NON_VOLATILE UINT32_C(0x00000001)
#define EFI_VARIABLE_BOOTSERVICE_ACCESS UINT32_C(0x00000002)
#define EFI_VARIABLE_RUNTIME_ACCESS UINT32_C(0x00000004)
#define EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS UINT32_C(0x00000020)
/* Note that the <lowercaseuuid>-<varname> naming scheme is an efivarfs convention, i.e. part of the Linux
* API file system implementation for EFI. EFI itself processes UIDS in binary form.
+4
View File
@@ -504,6 +504,10 @@ size_t char16_strlen(const char16_t *s) {
return n;
}
size_t char16_strsize(const char16_t *s) {
return s ? (char16_strlen(s) + 1) * sizeof(*s) : 0;
}
/* expected size used to encode one unicode char */
static int utf8_unichar_to_encoded_len(char32_t unichar) {
+1
View File
@@ -42,6 +42,7 @@ char* utf16_to_utf8(const char16_t *s, size_t length /* bytes! */);
char16_t *utf8_to_utf16(const char *s, size_t length);
size_t char16_strlen(const char16_t *s); /* returns the number of 16-bit words in the string (not bytes!) */
size_t char16_strsize(const char16_t *s);
int utf8_encoded_valid_unichar(const char *str, size_t length);
int utf8_encoded_to_unichar(const char *str, char32_t *ret_unichar);
+202
View File
@@ -8,14 +8,17 @@
#include "copy.h"
#include "dirent-util.h"
#include "efi-api.h"
#include "efi-fundamental.h"
#include "env-file.h"
#include "fd-util.h"
#include "fileio.h"
#include "fs-util.h"
#include "glyph-util.h"
#include "id128-util.h"
#include "io-util.h"
#include "kernel-config.h"
#include "os-util.h"
#include "parse-argument.h"
#include "path-util.h"
#include "rm-rf.h"
#include "stat-util.h"
@@ -295,6 +298,8 @@ static const char *const esp_subdirs[] = {
"EFI/systemd",
"EFI/BOOT",
"loader",
"loader/keys",
"loader/keys/auto",
NULL
};
@@ -569,6 +574,164 @@ static int install_entry_token(void) {
return 0;
}
#if HAVE_OPENSSL
static int efi_timestamp(EFI_TIME *ret) {
uint64_t epoch = UINT64_MAX;
struct tm tm = {};
int r;
assert(ret);
r = secure_getenv_uint64("SOURCE_DATE_EPOCH", &epoch);
if (r != -ENXIO)
log_debug_errno(r, "Failed to parse $SOURCE_DATE_EPOCH, ignoring: %m");
r = localtime_or_gmtime_usec(epoch != UINT64_MAX ? epoch : now(CLOCK_REALTIME), /*utc=*/ true, &tm);
if (r < 0)
return log_error_errno(r, "Failed to convert timestamp to calendar time: %m");
*ret = (EFI_TIME) {
.Year = 1900 + tm.tm_year,
/* tm_mon starts at 0, EFI_TIME months start at 1. */
.Month = tm.tm_mon + 1,
.Day = tm.tm_mday,
.Hour = tm.tm_hour,
.Minute = tm.tm_min,
.Second = tm.tm_sec,
};
return 0;
}
#endif
static int install_secure_boot_auto_enroll(const char *esp, X509 *certificate, EVP_PKEY *private_key) {
#if HAVE_OPENSSL
int r;
_cleanup_free_ uint8_t *dercert = NULL;
int dercertsz;
dercertsz = i2d_X509(certificate, &dercert);
if (dercertsz < 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to convert X.509 certificate to DER: %s",
ERR_error_string(ERR_get_error(), NULL));
_cleanup_close_ int keys_fd = chase_and_open("loader/keys/auto", esp, CHASE_PREFIX_ROOT|CHASE_PROHIBIT_SYMLINKS, O_DIRECTORY, NULL);
if (keys_fd < 0)
return log_error_errno(keys_fd, "Failed to chase loader/keys/auto in the ESP: %m");
uint32_t siglistsz = offsetof(EFI_SIGNATURE_LIST, Signatures) + offsetof(EFI_SIGNATURE_DATA, SignatureData) + dercertsz;
/* We use malloc0() to zero-initialize the SignatureOwner field of Signatures[0]. */
_cleanup_free_ EFI_SIGNATURE_LIST *siglist = malloc0(siglistsz);
if (!siglist)
return log_oom();
*siglist = (EFI_SIGNATURE_LIST) {
.SignatureType = EFI_CERT_X509_GUID,
.SignatureListSize = siglistsz,
.SignatureSize = offsetof(EFI_SIGNATURE_DATA, SignatureData) + dercertsz,
};
memcpy(siglist->Signatures[0].SignatureData, dercert, dercertsz);
EFI_TIME timestamp;
r = efi_timestamp(&timestamp);
if (r < 0)
return r;
uint32_t attrs =
EFI_VARIABLE_NON_VOLATILE|
EFI_VARIABLE_BOOTSERVICE_ACCESS|
EFI_VARIABLE_RUNTIME_ACCESS|
EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
FOREACH_STRING(db, "PK", "KEK", "db") {
_cleanup_(BIO_freep) BIO *bio = NULL;
bio = BIO_new(BIO_s_mem());
if (!bio)
return log_oom();
_cleanup_free_ char16_t *db16 = utf8_to_utf16(db, SIZE_MAX);
if (!db16)
return log_oom();
/* Don't count the trailing NUL terminator. */
if (BIO_write(bio, db16, char16_strsize(db16) - sizeof(char16_t)) < 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write variable name to bio");
EFI_GUID *guid = STR_IN_SET(db, "PK", "KEK") ? &(EFI_GUID) EFI_GLOBAL_VARIABLE : &(EFI_GUID) EFI_IMAGE_SECURITY_DATABASE_GUID;
if (BIO_write(bio, guid, sizeof(*guid)) < 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write variable GUID to bio");
if (BIO_write(bio, &attrs, sizeof(attrs)) < 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write variable attributes to bio");
if (BIO_write(bio, &timestamp, sizeof(timestamp)) < 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write timestamp to bio");
if (BIO_write(bio, siglist, siglistsz) < 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write signature list to bio");
_cleanup_(PKCS7_freep) PKCS7 *p7 = NULL;
p7 = PKCS7_sign(certificate, private_key, /*certs=*/ NULL, bio, PKCS7_DETACHED|PKCS7_NOATTR|PKCS7_BINARY|PKCS7_NOSMIMECAP);
if (!p7)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to calculate PKCS7 signature: %s",
ERR_error_string(ERR_get_error(), NULL));
_cleanup_free_ uint8_t *sig = NULL;
int sigsz = i2d_PKCS7_SIGNED(p7->d.sign, &sig);
if (sigsz < 0)
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to convert PKCS7 signature to DER: %s",
ERR_error_string(ERR_get_error(), NULL));
size_t authsz = offsetof(EFI_VARIABLE_AUTHENTICATION_2, AuthInfo.CertData) + sigsz;
_cleanup_free_ EFI_VARIABLE_AUTHENTICATION_2 *auth = malloc(authsz);
if (!auth)
return log_oom();
*auth = (EFI_VARIABLE_AUTHENTICATION_2) {
.TimeStamp = timestamp,
.AuthInfo = {
.Hdr = {
.dwLength = offsetof(WIN_CERTIFICATE_UEFI_GUID, CertData) + sigsz,
.wRevision = 0x0200,
.wCertificateType = 0x0EF1, /* WIN_CERT_TYPE_EFI_GUID */
},
.CertType = EFI_CERT_TYPE_PKCS7_GUID,
}
};
memcpy(auth->AuthInfo.CertData, sig, sigsz);
_cleanup_free_ char *filename = strjoin(db, ".auth");
if (!filename)
return log_oom();
_cleanup_close_ int fd = openat(keys_fd, filename, O_CREAT|O_EXCL|O_NOFOLLOW|O_NOCTTY|O_WRONLY|O_CLOEXEC, 0600);
if (fd < 0)
return log_error_errno(fd, "Failed to open secure boot auto-enrollment file for writing: %m");
r = loop_write(fd, auth, authsz);
if (r < 0)
return log_error_errno(r, "Failed to write authentication descriptor to secure boot auto-enrollment file: %m");
r = loop_write(fd, siglist, siglistsz);
if (r < 0)
return log_error_errno(r, "Failed to write signature list to secure boot auto-enrollment file: %m");
if (fsync(fd) < 0 || fsync(keys_fd) < 0)
return log_error_errno(errno, "Failed to sync secure boot auto-enrollment file: %m");
log_info("Secure boot auto-enrollment file %s/loader/keys/auto/%s successfully written.", esp, filename);
}
return 0;
#else
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "OpenSSL is not supported, cannot set up secure boot auto-enrollment.");
#endif
}
static bool same_entry(uint16_t id, sd_id128_t uuid, const char *path) {
_cleanup_free_ char *opath = NULL;
sd_id128_t ouuid;
@@ -778,6 +941,9 @@ static int are_we_installed(const char *esp_path) {
}
int verb_install(int argc, char *argv[], void *userdata) {
_cleanup_(X509_freep) X509 *certificate = NULL;
_cleanup_(openssl_ask_password_ui_freep) OpenSSLAskPasswordUI *ui = NULL;
_cleanup_(EVP_PKEY_freep) EVP_PKEY *private_key = NULL;
sd_id128_t uuid = SD_ID128_NULL;
uint64_t pstart = 0, psize = 0;
uint32_t part = 0;
@@ -789,6 +955,26 @@ int verb_install(int argc, char *argv[], void *userdata) {
install = streq(argv[0], "install");
graceful = !install && arg_graceful; /* support graceful mode for updates */
if (arg_secure_boot_auto_enroll) {
r = openssl_load_x509_certificate(arg_certificate, &certificate);
if (r < 0)
return log_error_errno(r, "Failed to load X.509 certificate from %s: %m", arg_certificate);
r = openssl_load_private_key(
arg_private_key_source_type,
arg_private_key_source,
arg_private_key,
&(AskPasswordRequest) {
.id = "bootctl-private-key-pin",
.keyring = arg_private_key,
.credential = "bootctl.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);
}
r = acquire_esp(/* unprivileged_mode= */ false, graceful, &part, &pstart, &psize, &uuid, NULL);
if (graceful && r == -ENOKEY)
return 0; /* If --graceful is specified and we can't find an ESP, handle this cleanly */
@@ -852,6 +1038,12 @@ int verb_install(int argc, char *argv[], void *userdata) {
if (r < 0)
return r;
}
if (arg_secure_boot_auto_enroll) {
r = install_secure_boot_auto_enroll(arg_esp_path, certificate, private_key);
if (r < 0)
return r;
}
}
r = install_loader_specification(arg_dollar_boot_path());
@@ -1069,6 +1261,16 @@ int verb_remove(int argc, char *argv[], void *userdata) {
if (q < 0 && r >= 0)
r = q;
FOREACH_STRING(db, "PK.auth", "KEK.auth", "db.auth") {
_cleanup_free_ char *p = path_join("/loader/keys/auto", db);
if (!p)
return log_oom();
q = remove_file(arg_esp_path, p);
if (q < 0 && r >= 0)
r = q;
}
q = remove_subdirs(arg_esp_path, esp_subdirs);
if (q < 0 && r >= 0)
r = q;
+64
View File
@@ -62,6 +62,11 @@ char *arg_efi_boot_option_description = NULL;
bool arg_dry_run = false;
ImagePolicy *arg_image_policy = NULL;
bool arg_varlink = false;
bool arg_secure_boot_auto_enroll = false;
char *arg_certificate = NULL;
char *arg_private_key = NULL;
KeySourceType arg_private_key_source_type = OPENSSL_KEY_SOURCE_FILE;
char *arg_private_key_source = NULL;
STATIC_DESTRUCTOR_REGISTER(arg_esp_path, freep);
STATIC_DESTRUCTOR_REGISTER(arg_xbootldr_path, freep);
@@ -71,6 +76,9 @@ STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
STATIC_DESTRUCTOR_REGISTER(arg_image, freep);
STATIC_DESTRUCTOR_REGISTER(arg_efi_boot_option_description, freep);
STATIC_DESTRUCTOR_REGISTER(arg_image_policy, image_policy_freep);
STATIC_DESTRUCTOR_REGISTER(arg_certificate, freep);
STATIC_DESTRUCTOR_REGISTER(arg_private_key, freep);
STATIC_DESTRUCTOR_REGISTER(arg_private_key_source, freep);
int acquire_esp(
int unprivileged_mode,
@@ -277,6 +285,19 @@ static int help(int argc, char *argv[], void *userdata) {
" --efi-boot-option-description=DESCRIPTION\n"
" Description of the entry in the boot option list\n"
" --dry-run Dry run (unlink and cleanup)\n"
" --secure-boot-auto-enroll\n"
" Set up secure boot auto-enrollment\n"
" --private-key=PATH|URI\n"
" Private key to use when setting up secure boot\n"
" auto-enrollment 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 KEY for --private-key=. Allows\n"
" an OpenSSL engine/provider to be used when setting\n"
" up secure boot auto-enrollment\n"
" --certificate=PATH\n"
" PEM certificate to use when setting up secure boot\n"
" auto-enrollment\n"
"\nSee the %2$s for details.\n",
program_invocation_short_name,
link,
@@ -309,6 +330,10 @@ static int parse_argv(int argc, char *argv[]) {
ARG_DRY_RUN,
ARG_PRINT_LOADER_PATH,
ARG_PRINT_STUB_PATH,
ARG_SECURE_BOOT_AUTO_ENROLL,
ARG_CERTIFICATE,
ARG_PRIVATE_KEY,
ARG_PRIVATE_KEY_SOURCE,
};
static const struct option options[] = {
@@ -339,6 +364,10 @@ static int parse_argv(int argc, char *argv[]) {
{ "all-architectures", no_argument, NULL, ARG_ARCH_ALL },
{ "efi-boot-option-description", required_argument, NULL, ARG_EFI_BOOT_OPTION_DESCRIPTION },
{ "dry-run", no_argument, NULL, ARG_DRY_RUN },
{ "secure-boot-auto-enroll", required_argument, NULL, ARG_SECURE_BOOT_AUTO_ENROLL },
{ "certificate", required_argument, NULL, ARG_CERTIFICATE },
{ "private-key", required_argument, NULL, ARG_PRIVATE_KEY },
{ "private-key-source", required_argument, NULL, ARG_PRIVATE_KEY_SOURCE },
{}
};
@@ -491,6 +520,35 @@ static int parse_argv(int argc, char *argv[]) {
arg_dry_run = true;
break;
case ARG_SECURE_BOOT_AUTO_ENROLL:
r = parse_boolean_argument("--secure-boot-auto-enroll=", optarg, &arg_secure_boot_auto_enroll);
if (r < 0)
return r;
break;
case ARG_CERTIFICATE: {
r = parse_path_argument(optarg, /*suppress_root=*/ false, &arg_certificate);
if (r < 0)
return r;
break;
}
case 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)
return r;
break;
case '?':
return -EINVAL;
@@ -517,6 +575,12 @@ static int parse_argv(int argc, char *argv[]) {
if (arg_dry_run && argv[optind] && !STR_IN_SET(argv[optind], "unlink", "cleanup"))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "--dry is only supported with --unlink or --cleanup");
if (arg_secure_boot_auto_enroll && !arg_certificate)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Secure boot auto-enrollment requested but no certificate provided");
if (arg_secure_boot_auto_enroll && !arg_private_key)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Secure boot auto-enrollment requested but no private key provided");
r = sd_varlink_invocation(SD_VARLINK_ALLOW_ACCEPT);
if (r < 0)
return log_error_errno(r, "Failed to check if invoked in Varlink mode: %m");
+6
View File
@@ -6,6 +6,7 @@
#include "boot-entry.h"
#include "image-policy.h"
#include "openssl-util.h"
#include "pager.h"
typedef enum InstallSource {
@@ -38,6 +39,11 @@ extern char *arg_efi_boot_option_description;
extern bool arg_dry_run;
extern ImagePolicy *arg_image_policy;
extern bool arg_varlink;
extern bool arg_secure_boot_auto_enroll;
extern char *arg_certificate;
extern char *arg_private_key;
extern KeySourceType arg_private_key_source_type;
extern char *arg_private_key_source;
static inline const char* arg_dollar_boot_path(void) {
/* $BOOT shall be the XBOOTLDR partition if it exists, and otherwise the ESP */
+1 -1
View File
@@ -30,7 +30,7 @@ executables += [
],
'sources' : bootctl_sources,
'link_with' : boot_link_with,
'dependencies' : libblkid,
'dependencies' : [libblkid, libopenssl],
},
libexec_template + {
'name' : 'systemd-bless-boot',
+61
View File
@@ -10,4 +10,65 @@ typedef struct {
uint16_t Data3;
uint8_t Data4[8];
} EFI_GUID;
typedef struct {
EFI_GUID SignatureOwner;
uint8_t SignatureData[];
} EFI_SIGNATURE_DATA;
typedef struct {
EFI_GUID SignatureType;
uint32_t SignatureListSize;
uint32_t SignatureHeaderSize;
uint32_t SignatureSize;
EFI_SIGNATURE_DATA Signatures[];
} EFI_SIGNATURE_LIST;
typedef struct {
uint32_t dwLength;
uint16_t wRevision;
uint16_t wCertificateType;
uint8_t bCertificate[];
} WIN_CERTIFICATE;
typedef struct {
WIN_CERTIFICATE Hdr;
EFI_GUID CertType;
uint8_t CertData[];
} WIN_CERTIFICATE_UEFI_GUID;
typedef struct {
uint16_t Year;
uint8_t Month;
uint8_t Day;
uint8_t Hour;
uint8_t Minute;
uint8_t Second;
uint8_t Pad1;
uint32_t Nanosecond;
int16_t TimeZone;
uint8_t Daylight;
uint8_t Pad2;
} EFI_TIME;
typedef struct {
EFI_TIME TimeStamp;
WIN_CERTIFICATE_UEFI_GUID AuthInfo;
} EFI_VARIABLE_AUTHENTICATION_2;
#define GUID_DEF(d1, d2, d3, d4_1, d4_2, d4_3, d4_4, d4_5, d4_6, d4_7, d4_8) \
{ d1, d2, d3, { d4_1, d4_2, d4_3, d4_4, d4_5, d4_6, d4_7, d4_8 } }
#define MAKE_GUID_PTR(name) ((EFI_GUID *) &(const EFI_GUID) name##_GUID)
#define EFI_GLOBAL_VARIABLE \
GUID_DEF(0x8be4df61, 0x93ca, 0x11d2, 0xaa, 0x0d, 0x00, 0xe0, 0x98, 0x03, 0x2b, 0x8c)
#define EFI_IMAGE_SECURITY_DATABASE_GUID \
GUID_DEF(0xd719b2cb, 0x3d3a, 0x4596, 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f)
#define EFI_CERT_X509_GUID \
GUID_DEF(0xa5c059a1, 0x94e4, 0x4aa7, 0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72)
#define EFI_CERT_TYPE_PKCS7_GUID \
GUID_DEF(0x4aafd29d, 0x68df, 0x49ee, 0x8a, 0xa9, 0x34, 0x7d, 0x37, 0x56, 0x65, 0xa7)
#endif
+1
View File
@@ -38,6 +38,7 @@ test_append_files() {
instmods vmw_vsock_vmci_transport
inst_binary gcc
generate_module_dependencies
inst_binary openssl
}
do_test "$@"
+27
View File
@@ -276,4 +276,31 @@ testcase_bootctl_varlink() {
SYSTEMD_LOG_TARGET=console varlinkctl call --json=short /run/systemd/io.systemd.BootControl io.systemd.BootControl.SetRebootToFirmware '{"state":false}' --graceful=io.systemd.BootControl.RebootToFirmwareNotSupported
}
testcase_bootctl_secure_boot_auto_enroll() {
cat >/tmp/openssl.conf <<EOF
[ req ]
prompt = no
distinguished_name = req_distinguished_name
[ req_distinguished_name ]
C = DE
ST = Test State
L = Test Locality
O = Org Name
OU = Org Unit Name
CN = Common Name
emailAddress = test@email.com
EOF
openssl req -config /tmp/openssl.conf -subj="/CN=waldo" \
-x509 -sha256 -nodes -days 365 -newkey rsa:4096 \
-keyout /tmp/sb.key -out /tmp/sb.crt
bootctl install --make-entry-directory=yes --secure-boot-auto-enroll=yes --certificate /tmp/sb.crt --private-key /tmp/sb.key
for var in PK KEK db; do
test -f "$(bootctl --print-esp-path)/loader/keys/auto/$var.auth"
done
bootctl remove
}
run_testcases