mirror of
https://github.com/systemd/systemd.git
synced 2025-03-21 02:50:18 +03:00
sbsign: Add sign-secure-boot-database
sign-secure-boot-database generates and signs UEFI secure boot signature databases to be used for Secure Boot auto-enrollment. Compared to bootctl install --secure-boot-auto-enroll=yes, sign-secure-boot-database only generates and signs a single signature database, doesn't write the signed database to the ESP and allows for offline signing using the existing options that are already in systemd-sbsign.
This commit is contained in:
parent
ace1e54c34
commit
244efe9cef
@ -49,6 +49,17 @@
|
||||
<xi:include href="version-info.xml" xpointer="v257"/>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>sign-secure-boot-database</option></term>
|
||||
|
||||
<listitem><para>Generates and signs a secure boot signature database. The signed secure boot
|
||||
signature database will be written to the path specified with <option>--output=</option>. The secure
|
||||
boot database identifier should be specified with the <option>--secure-boot-database=</option>
|
||||
option.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v258"/>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
@ -60,8 +71,9 @@
|
||||
<varlistentry>
|
||||
<term><option>--output=<replaceable>PATH</replaceable></option></term>
|
||||
|
||||
<listitem><para>Specifies the path where to write the signed PE binary or the data to be signed
|
||||
offline when using the <option>--prepare-offline-signing</option> option.</para>
|
||||
<listitem><para>Specifies the path where to write the signed PE binary, signed secure boot signature
|
||||
database or the data to be signed offline when using the <option>--prepare-offline-signing</option>
|
||||
option.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v257"/></listitem>
|
||||
</varlistentry>
|
||||
@ -73,15 +85,16 @@
|
||||
<term><option>--certificate-source=<replaceable>TYPE</replaceable>[:<replaceable>NAME</replaceable>]</option></term>
|
||||
|
||||
<listitem><para>Set the Secure Boot private key and certificate for use with the
|
||||
<command>sign</command>. The <option>--certificate=</option> option takes a path to a PEM encoded
|
||||
X.509 certificate or a URI that's passed to the OpenSSL provider configured with
|
||||
<option>--certificate-source=</option>. The <option>--certificate-source=</option> option takes one
|
||||
of <literal>file</literal> or <literal>provider</literal>, with the latter being followed by a
|
||||
specific provider identifier, separated with a colon, e.g. <literal>provider:pkcs11</literal>. 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 PE binary.</para>
|
||||
<command>sign</command> and <command>sign-secure-boot-database</command> commands. The
|
||||
<option>--certificate=</option> option takes a path to a PEM encoded X.509 certificate or a URI
|
||||
that's passed to the OpenSSL provider configured with <option>--certificate-source=</option>. The
|
||||
<option>--certificate-source=</option> option takes one of <literal>file</literal> or
|
||||
<literal>provider</literal>, with the latter being followed by a specific provider identifier,
|
||||
separated with a colon, e.g. <literal>provider:pkcs11</literal>. 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 PE binary or secure boot signature database.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v257"/></listitem>
|
||||
</varlistentry>
|
||||
@ -91,9 +104,9 @@
|
||||
|
||||
<listitem><para>When this option is specified, the <command>sign</command> command writes the data
|
||||
that should be signed to the path specified with <option>--output=</option> instead of writing the
|
||||
signed PE binary. This data can then be signed out of band after which the signature can be attached
|
||||
to the PE binary using the <option>--signed-data=</option> and
|
||||
<option>--signed-data-signature=</option> options.</para>
|
||||
signed PE binary or signed secure boot signature database. This data can then be signed out of band
|
||||
after which the signature can be attached to the PE binary or secure boot signature database using
|
||||
the <option>--signed-data=</option> and <option>--signed-data-signature=</option> options.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v258"/></listitem>
|
||||
</varlistentry>
|
||||
@ -104,7 +117,19 @@
|
||||
|
||||
<listitem><para>Configure the signed data (as written to the path specified with
|
||||
<option>--output=</option> when using the <option>--prepare-offline-signing</option> option) and
|
||||
corresponding signature for the <command>sign</command> command.</para>
|
||||
corresponding signature for the <command>sign</command> and
|
||||
<command>sign-secure-boot-database</command> commands.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v258"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--secure-boot-database=PK|KEK|db|dbx</option></term>
|
||||
|
||||
<listitem><para>Specify the secure boot signature database that should be generated and signed with
|
||||
the <command>sign-secure-boot-database</command> command. Takes one of the strings
|
||||
<varname>PK</varname>, <varname>KEK</varname>, <varname>db</varname> or <varname>dbx</varname>.
|
||||
</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v258"/></listitem>
|
||||
</varlistentry>
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "build.h"
|
||||
#include "copy.h"
|
||||
#include "efi-fundamental.h"
|
||||
#include "efivars.h"
|
||||
#include "env-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
@ -18,6 +19,7 @@
|
||||
#include "pe-binary.h"
|
||||
#include "pretty-print.h"
|
||||
#include "stat-util.h"
|
||||
#include "strv.h"
|
||||
#include "tmpfile-util.h"
|
||||
#include "verbs.h"
|
||||
|
||||
@ -31,6 +33,7 @@ static char *arg_private_key_source = NULL;
|
||||
static bool arg_prepare_offline_signing = false;
|
||||
static char *arg_signed_data = NULL;
|
||||
static char *arg_signed_data_signature = NULL;
|
||||
static char *arg_secure_boot_database = NULL;
|
||||
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_output, freep);
|
||||
STATIC_DESTRUCTOR_REGISTER(arg_certificate, freep);
|
||||
@ -175,6 +178,9 @@ 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"
|
||||
" sign-secure-boot-database\n"
|
||||
" Generate and sign a UEFI Secure Boot database\n"
|
||||
" for Secure Boot auto-enrollment\n"
|
||||
"\n%3$sOptions:%4$s\n"
|
||||
" -h --help Show this help\n"
|
||||
" --version Print version\n"
|
||||
@ -195,6 +201,8 @@ static int help(int argc, char *argv[], void *userdata) {
|
||||
" --signed-data=PATH Path to the data that was signed offline\n"
|
||||
" --signed-data-signature=PATH\n"
|
||||
" Path to the raw signature of the data that was signed offline\n"
|
||||
" --secure-boot-database=PK|KEK|db|dbx\n"
|
||||
" Which UEFI Secure Boot database to generate and sign\n"
|
||||
"\nSee the %2$s for details.\n",
|
||||
program_invocation_short_name,
|
||||
link,
|
||||
@ -217,6 +225,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
ARG_PREPARE_OFFLINE_SIGNING,
|
||||
ARG_SIGNED_DATA,
|
||||
ARG_SIGNED_DATA_SIGNATURE,
|
||||
ARG_SECURE_BOOT_DATABASE,
|
||||
};
|
||||
|
||||
static const struct option options[] = {
|
||||
@ -230,6 +239,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
{ "prepare-offline-signing", no_argument, NULL, ARG_PREPARE_OFFLINE_SIGNING },
|
||||
{ "signed-data", required_argument, NULL, ARG_SIGNED_DATA },
|
||||
{ "signed-data-signature", required_argument, NULL, ARG_SIGNED_DATA_SIGNATURE },
|
||||
{ "secure-boot-database", required_argument, NULL, ARG_SECURE_BOOT_DATABASE },
|
||||
{}
|
||||
};
|
||||
|
||||
@ -305,6 +315,12 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
|
||||
break;
|
||||
|
||||
case ARG_SECURE_BOOT_DATABASE:
|
||||
r = free_and_strdup(&arg_secure_boot_database, optarg);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
break;
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
|
||||
@ -801,10 +817,267 @@ static int verb_sign(int argc, char *argv[], void *userdata) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 < 0 && 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;
|
||||
}
|
||||
|
||||
static int populate_secure_boot_database_bio(
|
||||
const char16_t *db,
|
||||
const EFI_GUID *guid,
|
||||
uint32_t attrs,
|
||||
const EFI_TIME *timestamp,
|
||||
const EFI_SIGNATURE_LIST *siglist,
|
||||
size_t siglistsz,
|
||||
BIO **ret) {
|
||||
|
||||
assert(db);
|
||||
assert(guid);
|
||||
assert(timestamp);
|
||||
assert(siglist);
|
||||
assert(ret);
|
||||
|
||||
_cleanup_(BIO_freep) BIO *bio = NULL;
|
||||
bio = BIO_new(BIO_s_mem());
|
||||
if (!bio)
|
||||
return log_oom();
|
||||
|
||||
/* Don't count the trailing NUL terminator. */
|
||||
if (BIO_write(bio, db, char16_strsize(db) - sizeof(char16_t)) < 0)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to write variable name to bio");
|
||||
|
||||
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");
|
||||
|
||||
*ret = TAKE_PTR(bio);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int verb_sign_secure_boot_database(int argc, char *argv[], void *userdata) {
|
||||
static const uint32_t attrs =
|
||||
EFI_VARIABLE_NON_VOLATILE|
|
||||
EFI_VARIABLE_BOOTSERVICE_ACCESS|
|
||||
EFI_VARIABLE_RUNTIME_ACCESS|
|
||||
EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
|
||||
_cleanup_(context_done) Context ctx = CONTEXT_NULL;
|
||||
_cleanup_(iovec_done) struct iovec signed_data = {};
|
||||
_cleanup_(iovec_done) struct iovec signed_data_signature = {};
|
||||
int r;
|
||||
|
||||
if (!arg_private_key && !arg_signed_data_signature && !arg_prepare_offline_signing)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"No private key or signed data signature specified, use --private-key= or --signed-data-signature=.");
|
||||
|
||||
if (!arg_output)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "No output specified, use --output=");
|
||||
|
||||
|
||||
if (!arg_secure_boot_database)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"No secure boot database identifier specified, use --secure-boot-database=");
|
||||
|
||||
if (!STR_IN_SET(arg_secure_boot_database, "PK", "KEK", "db", "dbx"))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"Secure Boot database identifier '%s' is not valid", arg_secure_boot_database);
|
||||
|
||||
r = context_populate(argc, argv, &ctx);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (arg_signed_data) {
|
||||
r = read_full_file(arg_signed_data, (char**) &signed_data.iov_base, &signed_data.iov_len);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to read secure boot database signed data file '%s': %m", arg_signed_data);
|
||||
}
|
||||
|
||||
if (arg_signed_data_signature) {
|
||||
r = read_full_file(arg_signed_data_signature, (char**) &signed_data_signature.iov_base, &signed_data_signature.iov_len);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to read secure boot database signature file '%s': %m", arg_signed_data_signature);
|
||||
}
|
||||
|
||||
_cleanup_free_ uint8_t *dercert = NULL;
|
||||
int dercertsz = i2d_X509(ctx.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));
|
||||
|
||||
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);
|
||||
|
||||
_cleanup_free_ char16_t *db16 = utf8_to_utf16(arg_secure_boot_database, SIZE_MAX);
|
||||
if (!db16)
|
||||
return log_oom();
|
||||
|
||||
EFI_TIME timestamp;
|
||||
if (iovec_is_set(&signed_data)) {
|
||||
/* Don't count the trailing NUL terminator. */
|
||||
size_t db16sz = char16_strsize(db16) - sizeof(char16_t);
|
||||
size_t expectedsz = db16sz + sizeof(EFI_GUID) + sizeof(attrs) + sizeof(timestamp) + siglistsz;
|
||||
|
||||
if (signed_data.iov_len != expectedsz)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(ERANGE),
|
||||
"The secure boot database signed data file size does not match the expected size (%s != %s)",
|
||||
FORMAT_BYTES(signed_data.iov_len),
|
||||
FORMAT_BYTES(expectedsz));
|
||||
|
||||
/* The signed data includes a timestamp which also has to go in the EFI variable descriptor
|
||||
* which includes the signature and they have to match, so we extract the timestamp from the
|
||||
* signed data so we can store it in the EFI variable descriptor later. */
|
||||
size_t tsoffset = db16sz + sizeof(EFI_GUID) + sizeof(attrs);
|
||||
memcpy_safe(×tamp, (uint8_t*) signed_data.iov_base + tsoffset, sizeof(timestamp));
|
||||
} else {
|
||||
r = efi_timestamp(×tamp);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
EFI_GUID *guid = STR_IN_SET(arg_secure_boot_database, "PK", "KEK") ? &(EFI_GUID) EFI_GLOBAL_VARIABLE
|
||||
: &(EFI_GUID) EFI_IMAGE_SECURITY_DATABASE_GUID;
|
||||
|
||||
_cleanup_(BIO_freep) BIO *bio = NULL;
|
||||
r = populate_secure_boot_database_bio(db16, guid, attrs, ×tamp, siglist, siglistsz, &bio);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (arg_prepare_offline_signing) {
|
||||
char *buf;
|
||||
long bufsz = BIO_get_mem_data(bio, &buf);
|
||||
|
||||
r = loop_write(ctx.dstfd, buf, bufsz);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to write secure boot database unsigned data blob to temporary file: %m");
|
||||
|
||||
r = link_tmpfile(ctx.dstfd, ctx.tmp, arg_output, LINK_TMPFILE_REPLACE|LINK_TMPFILE_SYNC);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to link temporary file to %s: %m", arg_output);
|
||||
|
||||
log_info("Wrote secure boot database unsigned data blob to %s", arg_output);
|
||||
return 0;
|
||||
}
|
||||
|
||||
_cleanup_(PKCS7_freep) PKCS7 *p7 = NULL;
|
||||
PKCS7_SIGNER_INFO *si = NULL; /* avoid false maybe-uninitialized warning */
|
||||
r = pkcs7_new(ctx.certificate, ctx.private_key, &p7, &si);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to allocate PKCS#7 context: %m");
|
||||
|
||||
if (PKCS7_set_detached(p7, true) == 0)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to set PKCS#7 detached attribute: %s",
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
|
||||
_cleanup_(BIO_free_allp) BIO *p7bio = PKCS7_dataInit(p7, NULL);
|
||||
if (!p7bio)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to create PKCS#7 data bio: %s",
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
|
||||
if (SMIME_crlf_copy(bio, p7bio, PKCS7_BINARY) == 0)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to copy unsigned data to PKCS#7 data bio: %s",
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
|
||||
if (iovec_is_set(&signed_data_signature)) {
|
||||
ASN1_STRING_set0(si->enc_digest,
|
||||
TAKE_PTR(signed_data_signature.iov_base),
|
||||
signed_data_signature.iov_len);
|
||||
|
||||
if (PKCS7_signatureVerify(p7bio, p7, si, ctx.certificate) == 0)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EIO), "PKCS#7 signature validation failed: %s",
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
|
||||
} else if (PKCS7_dataFinal(p7, p7bio) == 0)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to sign PKCS#7 data: %s",
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
|
||||
_cleanup_free_ uint8_t *sig = NULL;
|
||||
int sigsz = i2d_PKCS7(p7, &sig);
|
||||
if (sigsz < 0)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to convert PKCS#7 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);
|
||||
|
||||
r = loop_write(ctx.dstfd, auth, authsz);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to write authentication descriptor to secure boot database file: %m");
|
||||
|
||||
r = loop_write(ctx.dstfd, siglist, siglistsz);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to write signature list to secure boot database file: %m");
|
||||
|
||||
r = link_tmpfile(ctx.dstfd, ctx.tmp, arg_output, LINK_TMPFILE_REPLACE|LINK_TMPFILE_SYNC);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to link temporary file to %s: %m", arg_output);
|
||||
|
||||
log_info("Wrote signed secure boot database to %s", arg_output);
|
||||
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 },
|
||||
{ "sign-secure-boot-database", 1, 1, 0, verb_sign_secure_boot_database },
|
||||
{}
|
||||
};
|
||||
int r;
|
||||
|
@ -98,4 +98,46 @@ testcase_sign_systemd_boot_offline() {
|
||||
cmp /tmp/sdboot-signed-online /tmp/sdboot-signed-offline
|
||||
}
|
||||
|
||||
testcase_sign_secure_boot_database() {
|
||||
/usr/lib/systemd/systemd-sbsign \
|
||||
sign-secure-boot-database \
|
||||
--certificate /tmp/sb.crt \
|
||||
--private-key /tmp/sb.key \
|
||||
--output /tmp/PK.signed \
|
||||
--secure-boot-database PK
|
||||
}
|
||||
|
||||
testcase_sign_secure_boot_database_offline() {
|
||||
export SOURCE_DATE_EPOCH="123"
|
||||
|
||||
/usr/lib/systemd/systemd-sbsign \
|
||||
sign-secure-boot-database \
|
||||
--certificate /tmp/sb.crt \
|
||||
--private-key /tmp/sb.key \
|
||||
--output /tmp/PK.signed-online \
|
||||
--secure-boot-database PK
|
||||
|
||||
/usr/lib/systemd/systemd-sbsign \
|
||||
sign-secure-boot-database \
|
||||
--certificate /tmp/sb.crt \
|
||||
--output /tmp/signed-data.bin \
|
||||
--prepare-offline-signing \
|
||||
--secure-boot-database PK
|
||||
openssl dgst -sha256 -sign /tmp/sb.key -out /tmp/signed-data.sig /tmp/signed-data.bin
|
||||
|
||||
# Make sure systemd-sbsign can't pick up the timestamp from the environment when
|
||||
# attaching the signature.
|
||||
unset SOURCE_DATE_EPOCH
|
||||
|
||||
/usr/lib/systemd/systemd-sbsign \
|
||||
sign-secure-boot-database \
|
||||
--certificate /tmp/sb.crt \
|
||||
--output /tmp/PK.signed-offline \
|
||||
--signed-data /tmp/signed-data.bin \
|
||||
--signed-data-signature /tmp/signed-data.sig \
|
||||
--secure-boot-database PK
|
||||
|
||||
cmp /tmp/PK.signed-offline /tmp/PK.signed-online
|
||||
}
|
||||
|
||||
run_testcases
|
||||
|
Loading…
x
Reference in New Issue
Block a user