Commit fcb5667d authored by Richard Hughes's avatar Richard Hughes
Browse files

libfwupdplugin: Subclass FuFirmware in FuEfiSignatureList

This allows us to get fuzzing support 'for free' and also simplifies the code.
parent ac927583
......@@ -137,5 +137,4 @@ There are several automated fuzzing tests in fwupd. These take some time to run:
ninja install
ninja fuzz-firmware
ninja fuzz-smbios
ninja fuzz-efidbx
ninja fuzz-tpm-eventlog
#!/usr/bin/python3
# SPDX-License-Identifier: LGPL-2.1+
import sys
import struct
if __name__ == '__main__':
# SignatureType
buf = b'0' * 16
# SignatureListSize
buf += struct.pack('<I', 16 + 4 + 4 + 4 + 16 + 32)
# SignatureHeaderSize
buf += struct.pack('<I', 0)
# SignatureSize
buf += struct.pack('<I', 16 + 32)
# SignatureOwner
buf += b'1' * 16
# SignatureData
buf += b'2' * 32
with open(sys.argv[1], 'wb') as f:
f.write(buf)
......@@ -18,7 +18,7 @@
#include "fu-efivar.h"
#include "fu-uefi-dbx-common.h"
#include "fu-efi-signature-common.h"
#include "fu-efi-signature-parser.h"
#include "fu-efi-signature.h"
/* custom return code */
#define EXIT_NOTHING_TO_DO 2
......@@ -29,29 +29,30 @@ fu_util_ignore_cb (const gchar *log_domain, GLogLevelFlags log_level,
{
}
static GPtrArray *
static FuFirmware *
fu_dbxtool_get_siglist_system (GError **error)
{
gsize bufsz = 0;
g_autofree guint8 *buf = NULL;
if (!fu_efivar_get_data (FU_EFIVAR_GUID_SECURITY_DATABASE, "dbx",
&buf, &bufsz, NULL, error))
g_autoptr(GBytes) blob = NULL;
g_autoptr(FuFirmware) dbx = fu_efi_signature_list_new ();
blob = fu_efivar_get_data_bytes (FU_EFIVAR_GUID_SECURITY_DATABASE, "dbx", NULL, error);
if (blob == NULL)
return NULL;
return fu_efi_signature_parser_new (buf, bufsz,
FU_EFI_SIGNATURE_PARSER_FLAGS_NONE,
error);
if (!fu_firmware_parse (dbx, blob, FWUPD_INSTALL_FLAG_NO_SEARCH, error))
return NULL;
return g_steal_pointer (&dbx);
}
static GPtrArray *
static FuFirmware *
fu_dbxtool_get_siglist_local (const gchar *filename, GError **error)
{
gsize bufsz = 0;
g_autofree guint8 *buf = NULL;
if (!g_file_get_contents (filename, (gchar **) &buf, &bufsz, error))
g_autoptr(GBytes) blob = NULL;
g_autoptr(FuFirmware) siglist = fu_efi_signature_list_new ();
blob = fu_common_get_contents_bytes (filename, error);
if (blob == NULL)
return NULL;
if (!fu_firmware_parse (siglist, blob, FWUPD_INSTALL_FLAG_NONE, error))
return NULL;
return fu_efi_signature_parser_new (buf, bufsz,
FU_EFI_SIGNATURE_PARSER_FLAGS_IGNORE_HEADER,
error);
return g_steal_pointer (&siglist);
}
int
......@@ -123,7 +124,8 @@ main (int argc, char *argv[])
/* list contents, either of the existing system, or an update */
if (action_list || action_version) {
guint cnt = 1;
g_autoptr(GPtrArray) dbx = NULL;
g_autoptr(FuFirmware) dbx = NULL;
g_autoptr(GPtrArray) sigs = NULL;
if (dbxfile != NULL) {
dbx = fu_dbxtool_get_siglist_local (dbxfile, &error);
if (dbx == NULL) {
......@@ -141,20 +143,21 @@ main (int argc, char *argv[])
}
if (action_version) {
/* TRANSLATORS: the detected version number of the dbx */
g_print ("%s: %u\n", _("Version"), fu_efi_signature_list_array_version (dbx));
g_print ("%s: %s\n", _("Version"), fu_firmware_get_version (dbx));
return EXIT_SUCCESS;
}
for (guint j = 0; j < dbx->len; j++) {
FuEfiSignatureList *siglist = g_ptr_array_index (dbx, j);
GPtrArray *sigs = fu_efi_signature_list_get_all (siglist);
for (guint i = 0; i < sigs->len; i++) {
FuEfiSignature *sig = g_ptr_array_index (sigs, i);
g_print ("%4u: {%s} {%s} %s\n",
cnt++,
fu_efi_signature_guid_to_string (fu_efi_signature_get_owner (sig)),
fu_efi_signature_kind_to_string (fu_efi_signature_get_kind (sig)),
fu_efi_signature_get_checksum (sig));
}
sigs = fu_firmware_get_images (FU_FIRMWARE (dbx));
for (guint i = 0; i < sigs->len; i++) {
FuEfiSignature *sig = g_ptr_array_index (sigs, i);
g_autofree gchar *checksum = NULL;
checksum = fu_firmware_image_get_checksum (FU_FIRMWARE_IMAGE (sig),
G_CHECKSUM_SHA256,
NULL);
g_print ("%4u: {%s} {%s} %s\n",
cnt++,
fu_efi_signature_guid_to_string (fu_efi_signature_get_owner (sig)),
fu_efi_signature_kind_to_string (fu_efi_signature_get_kind (sig)),
checksum);
}
return EXIT_SUCCESS;
}
......@@ -169,10 +172,9 @@ main (int argc, char *argv[])
/* apply update */
if (action_apply) {
gsize bufsz = 0;
g_autofree guint8 *buf = NULL;
g_autoptr(GPtrArray) dbx_system = NULL;
g_autoptr(GPtrArray) dbx_update = NULL;
g_autoptr(FuFirmware) dbx_system = NULL;
g_autoptr(FuFirmware) dbx_update = fu_efi_signature_list_new ();
g_autoptr(GBytes) blob = NULL;
if (dbxfile == NULL) {
/* TRANSLATORS: user did not include a filename parameter */
......@@ -191,27 +193,20 @@ main (int argc, char *argv[])
/* TRANSLATORS: reading new dbx from the update */
g_print ("%s\n", _("Parsing dbx update…"));
if (!g_file_get_contents (dbxfile, (gchar **) &buf, &bufsz, &error)) {
blob = fu_common_get_contents_bytes (dbxfile, &error);
if (blob == NULL) {
/* TRANSLATORS: could not read file */
g_printerr ("%s: %s\n", _("Failed to load local dbx"), error->message);
return EXIT_FAILURE;
}
dbx_update = fu_efi_signature_parser_new (buf, bufsz,
FU_EFI_SIGNATURE_PARSER_FLAGS_IGNORE_HEADER,
&error);
if (dbx_update == NULL) {
if (!fu_firmware_parse (dbx_update, blob, FWUPD_INSTALL_FLAG_NONE, &error)) {
/* TRANSLATORS: could not parse file */
g_printerr ("%s: %s\n", _("Failed to parse local dbx"), error->message);
return EXIT_FAILURE;
}
if (dbx_update->len != 1) {
/* TRANSLATORS: could not parse file */
g_printerr ("%s: %s\n", _("Failed to extract local dbx "), error->message);
return EXIT_FAILURE;
}
/* check this is a newer dbx update */
if (!force && fu_efi_signature_list_array_inclusive (dbx_system, dbx_update)) {
if (!force && fu_efi_signature_list_inclusive (FU_EFI_SIGNATURE_LIST (dbx_system), FU_EFI_SIGNATURE_LIST (dbx_update))) {
/* TRANSLATORS: same or newer update already applied */
g_printerr ("%s\n", _("Cannot apply as dbx update has already been applied."));
return EXIT_FAILURE;
......@@ -228,7 +223,7 @@ main (int argc, char *argv[])
if (!force) {
/* TRANSLATORS: ESP refers to the EFI System Partition */
g_print ("%s\n", _("Validating ESP contents…"));
if (!fu_uefi_dbx_signature_list_validate (dbx_update, &error)) {
if (!fu_uefi_dbx_signature_list_validate (FU_EFI_SIGNATURE_LIST (dbx_update), &error)) {
/* TRANSLATORS: something with a blocked hash exists
* in the users ESP -- which would be bad! */
g_printerr ("%s: %s\n", _("Failed to validate ESP contents"), error->message);
......@@ -238,14 +233,14 @@ main (int argc, char *argv[])
/* TRANSLATORS: actually sending the update to the hardware */
g_print ("%s\n", _("Applying update…"));
if (!fu_efivar_set_data (FU_EFIVAR_GUID_SECURITY_DATABASE,
"dbx", buf, bufsz,
FU_EFIVAR_ATTR_APPEND_WRITE |
FU_EFIVAR_ATTR_TIME_BASED_AUTHENTICATED_WRITE_ACCESS |
FU_EFIVAR_ATTR_RUNTIME_ACCESS |
FU_EFIVAR_ATTR_BOOTSERVICE_ACCESS |
FU_EFIVAR_ATTR_NON_VOLATILE,
&error)) {
if (!fu_efivar_set_data_bytes (FU_EFIVAR_GUID_SECURITY_DATABASE,
"dbx", blob,
FU_EFIVAR_ATTR_APPEND_WRITE |
FU_EFIVAR_ATTR_TIME_BASED_AUTHENTICATED_WRITE_ACCESS |
FU_EFIVAR_ATTR_RUNTIME_ACCESS |
FU_EFIVAR_ATTR_BOOTSERVICE_ACCESS |
FU_EFIVAR_ATTR_NON_VOLATILE,
&error)) {
/* TRANSLATORS: dbx file failed to be applied as an update */
g_printerr ("%s: %s\n", _("Failed to apply update"), error->message);
return EXIT_FAILURE;
......
......@@ -8,52 +8,29 @@
#include "fu-efi-signature-common.h"
#include "fu-efi-signature-list.h"
#include "fu-efi-signature.h"
gboolean
fu_efi_signature_list_array_has_checksum (GPtrArray *siglists, const gchar *checksum)
fu_efi_signature_list_has_checksum (FuEfiSignatureList *siglist, const gchar *checksum)
{
for (guint i = 0; i < siglists->len; i++) {
FuEfiSignatureList *siglist = g_ptr_array_index (siglists, i);
if (fu_efi_signature_list_has_checksum (siglist, checksum))
return TRUE;
}
return FALSE;
g_autoptr(FuFirmwareImage) img = NULL;
img = fu_firmware_get_image_by_checksum (FU_FIRMWARE (siglist), checksum, NULL);
return img != NULL;
}
gboolean
fu_efi_signature_list_array_inclusive (GPtrArray *outer, GPtrArray *inner)
fu_efi_signature_list_inclusive (FuEfiSignatureList *outer, FuEfiSignatureList *inner)
{
for (guint j = 0; j < inner->len; j++) {
FuEfiSignatureList *siglist = g_ptr_array_index (inner, j);
GPtrArray *items = fu_efi_signature_list_get_all (siglist);
for (guint i = 0; i < items->len; i++) {
FuEfiSignature *sig = g_ptr_array_index (items, i);
const gchar *checksum = fu_efi_signature_get_checksum (sig);
if (!fu_efi_signature_list_array_has_checksum (outer, checksum))
return FALSE;
}
g_autoptr(GPtrArray) sigs = fu_firmware_get_images (FU_FIRMWARE (inner));
for (guint i = 0; i < sigs->len; i++) {
FuEfiSignature *sig = g_ptr_array_index (sigs, i);
g_autofree gchar *checksum = NULL;
checksum = fu_firmware_image_get_checksum (FU_FIRMWARE_IMAGE (sig),
G_CHECKSUM_SHA256, NULL);
if (checksum == NULL)
continue;
if (!fu_efi_signature_list_has_checksum (outer, checksum))
return FALSE;
}
return TRUE;
}
guint
fu_efi_signature_list_array_version (GPtrArray *siglists)
{
guint csum_cnt = 0;
const gchar *ignored_guids[] = {
FU_EFI_SIGNATURE_GUID_OVMF,
NULL };
for (guint j = 0; j < siglists->len; j++) {
FuEfiSignatureList *siglist = g_ptr_array_index (siglists, j);
GPtrArray *items = fu_efi_signature_list_get_all (siglist);
for (guint i = 0; i < items->len; i++) {
FuEfiSignature *sig = g_ptr_array_index (items, i);
if (fu_efi_signature_get_kind (sig) != FU_EFI_SIGNATURE_KIND_SHA256)
continue;
if (g_strv_contains (ignored_guids, fu_efi_signature_get_owner (sig)))
continue;
csum_cnt++;
}
}
return csum_cnt;
}
......@@ -6,10 +6,9 @@
#pragma once
#include "fu-efi-signature.h"
#include "fu-efi-signature-list.h"
gboolean fu_efi_signature_list_array_inclusive (GPtrArray *outer,
GPtrArray *inner);
guint fu_efi_signature_list_array_version (GPtrArray *siglists);
gboolean fu_efi_signature_list_array_has_checksum (GPtrArray *siglists,
const gchar *checksum);
gboolean fu_efi_signature_list_inclusive (FuEfiSignatureList *outer,
FuEfiSignatureList *inner);
gboolean fu_efi_signature_list_has_checksum (FuEfiSignatureList *siglist,
const gchar *checksum);
......@@ -6,74 +6,242 @@
#include "config.h"
#include <fwupd.h>
#include "fu-common.h"
#include "fu-efi-signature.h"
#include "fu-efi-signature-list.h"
struct _FuEfiSignatureList {
GObject parent_instance;
FuEfiSignatureKind kind;
GPtrArray *items; /* element-type: FuEfiSignature */
FuFirmware parent_instance;
};
G_DEFINE_TYPE (FuEfiSignatureList, fu_efi_signature_list, G_TYPE_OBJECT)
G_DEFINE_TYPE (FuEfiSignatureList, fu_efi_signature_list, FU_TYPE_FIRMWARE)
FuEfiSignatureList *
fu_efi_signature_list_new (FuEfiSignatureKind kind)
static gboolean
fu_efi_signature_list_parse_item (FuEfiSignatureList *self,
FuEfiSignatureKind sig_kind,
const guint8 *buf,
gsize bufsz,
gsize offset,
guint32 sig_size,
GError **error)
{
g_autoptr(FuEfiSignatureList) self = g_object_new (FU_TYPE_EFI_SIGNATURE_LIST, NULL);
self->kind = kind;
return g_steal_pointer (&self);
fwupd_guid_t guid;
gsize sig_datasz = sig_size - sizeof(fwupd_guid_t);
g_autofree gchar *sig_owner = NULL;
g_autofree guint8 *sig_data = g_malloc0 (sig_datasz);
g_autoptr(FuEfiSignature) sig = NULL;
g_autoptr(GBytes) data = NULL;
/* read both blocks of data */
if (!fu_memcpy_safe ((guint8 *) &guid, sizeof(guid), 0x0, /* dst */
buf, bufsz, offset, /* src */
sizeof(guid), error)) {
g_prefix_error (error, "failed to read signature GUID: ");
return FALSE;
}
if (!fu_memcpy_safe (sig_data, sig_datasz, 0x0, /* dst */
buf, bufsz, offset + sizeof(fwupd_guid_t), /* src */
sig_datasz, error)) {
g_prefix_error (error, "failed to read signature data: ");
return FALSE;
}
/* create item */
sig_owner = fwupd_guid_to_string (&guid, FWUPD_GUID_FLAG_MIXED_ENDIAN);
data = g_bytes_new (sig_data, sig_datasz);
sig = fu_efi_signature_new (sig_kind, sig_owner);
fu_firmware_image_set_bytes (FU_FIRMWARE_IMAGE (sig), data);
fu_firmware_add_image (FU_FIRMWARE (self), FU_FIRMWARE_IMAGE (sig));
return TRUE;
}
FuEfiSignatureKind
fu_efi_signature_list_get_kind (FuEfiSignatureList *self)
static gboolean
fu_efi_signature_list_parse_list (FuEfiSignatureList *self,
const guint8 *buf,
gsize bufsz,
gsize *offset,
GError **error)
{
g_return_val_if_fail (FU_IS_EFI_SIGNATURE_LIST (self), 0);
return self->kind;
FuEfiSignatureKind sig_kind = FU_EFI_SIGNATURE_KIND_UNKNOWN;
fwupd_guid_t guid;
gsize offset_tmp;
guint32 sig_header_size = 0;
guint32 sig_list_size = 0;
guint32 sig_size = 0;
g_autofree gchar *sig_type = NULL;
/* read EFI_SIGNATURE_LIST */
if (!fu_memcpy_safe ((guint8 *) &guid, sizeof(guid), 0x0, /* dst */
buf, bufsz, *offset, /* src */
sizeof(guid), error)) {
g_prefix_error (error, "failed to read GUID header: ");
return FALSE;
}
sig_type = fwupd_guid_to_string (&guid, FWUPD_GUID_FLAG_MIXED_ENDIAN);
if (g_strcmp0 (sig_type, "c1c41626-504c-4092-aca9-41f936934328") == 0) {
sig_kind = FU_EFI_SIGNATURE_KIND_SHA256;
} else if (g_strcmp0 (sig_type, "a5c059a1-94e4-4aa7-87b5-ab155c2bf072") == 0) {
sig_kind = FU_EFI_SIGNATURE_KIND_X509;
}
if (!fu_common_read_uint32_safe (buf, bufsz, *offset + 0x10,
&sig_list_size, G_LITTLE_ENDIAN, error))
return FALSE;
if (sig_list_size < 0x1c || sig_list_size > 1024 * 1024) {
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_FAILED,
"SignatureListSize invalid: 0x%x", sig_list_size);
return FALSE;
}
if (!fu_common_read_uint32_safe (buf, bufsz, *offset + 0x14,
&sig_header_size, G_LITTLE_ENDIAN, error))
return FALSE;
if (sig_header_size > 1024 * 1024) {
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_FAILED,
"SignatureHeaderSize invalid: 0x%x", sig_size);
return FALSE;
}
if (!fu_common_read_uint32_safe (buf, bufsz, *offset + 0x18,
&sig_size, G_LITTLE_ENDIAN, error))
return FALSE;
if (sig_size < sizeof(fwupd_guid_t) || sig_size > 1024 * 1024) {
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_FAILED,
"SignatureSize invalid: 0x%x", sig_size);
return FALSE;
}
/* header is typically unused */
offset_tmp = *offset + 0x1c + sig_header_size;
for (guint i = 0; i < (sig_list_size - 0x1c) / sig_size; i++) {
if (!fu_efi_signature_list_parse_item (self, sig_kind, buf, bufsz,
offset_tmp, sig_size,
error))
return FALSE;
offset_tmp += sig_size;
}
*offset += sig_list_size;
return TRUE;
}
GPtrArray *
fu_efi_signature_list_get_all (FuEfiSignatureList *self)
static gchar *
fu_efi_signature_list_get_version (FuEfiSignatureList *self)
{
g_return_val_if_fail (FU_IS_EFI_SIGNATURE_LIST (self), NULL);
return self->items;
guint csum_cnt = 0;
const gchar *ignored_guids[] = {
FU_EFI_SIGNATURE_GUID_OVMF,
NULL };
g_autoptr(GPtrArray) sigs = NULL;
sigs = fu_firmware_get_images (FU_FIRMWARE (self));
for (guint i = 0; i < sigs->len; i++) {
FuEfiSignature *sig = g_ptr_array_index (sigs, i);
if (fu_efi_signature_get_kind (sig) != FU_EFI_SIGNATURE_KIND_SHA256)
continue;
if (g_strv_contains (ignored_guids, fu_efi_signature_get_owner (sig)))
continue;
csum_cnt++;
}
return g_strdup_printf ("%u", csum_cnt);
}
void
fu_efi_signature_list_add (FuEfiSignatureList *self, FuEfiSignature *signature)
static gboolean
fu_efi_signature_list_parse (FuFirmware *firmware,
GBytes *fw,
guint64 addr_start,
guint64 addr_end,
FwupdInstallFlags flags,
GError **error)
{
g_return_if_fail (FU_IS_EFI_SIGNATURE_LIST (self));
g_ptr_array_add (self->items, g_object_ref (signature));
FuEfiSignatureList *self = FU_EFI_SIGNATURE_LIST (firmware);
gsize bufsz = 0;
gsize offset_fs = 0;
const guint8 *buf = g_bytes_get_data (fw, &bufsz);
g_autofree gchar *version_str = NULL;
/* this allows us to skip the efi permissions uint32_t or even the
* Microsoft PKCS-7 signature */
if ((flags & FWUPD_INSTALL_FLAG_NO_SEARCH) == 0) {
if (bufsz < 5) {
g_set_error (error,
G_IO_ERROR,
G_IO_ERROR_FAILED,
"signature invalid: 0x%x",
(guint) bufsz);
return FALSE;
}
for (gsize i = 0; i < bufsz - 5; i++) {
if (memcmp (buf + i, "\x26\x16\xc4\xc1\x4c", 5) == 0) {
g_debug ("found EFI_SIGNATURE_LIST @0x%x", (guint) i);
offset_fs = i;
break;
}
}
}
/* parse each EFI_SIGNATURE_LIST */
for (gsize offset = offset_fs; offset < bufsz;) {
if (!fu_efi_signature_list_parse_list (self, buf, bufsz, &offset, error))
return FALSE;
}
/* set version */
version_str = fu_efi_signature_list_get_version (self);
if (version_str != NULL)
fu_firmware_set_version (firmware, version_str);
/* success */
return TRUE;
}
gboolean
fu_efi_signature_list_has_checksum (FuEfiSignatureList *self, const gchar *checksum)
static GBytes *
fu_efi_signature_list_write (FuFirmware *firmware, GError **error)
{
g_return_val_if_fail (FU_IS_EFI_SIGNATURE_LIST (self), FALSE);
for (guint i = 0; i < self->items->len; i++) {
FuEfiSignature *item = g_ptr_array_index (self->items, i);
if (g_strcmp0 (fu_efi_signature_get_checksum (item), checksum) == 0)
return TRUE;
}
return FALSE;
GByteArray *buf = g_byte_array_new ();
/* SignatureType */
for (guint i = 0; i < 16; i++)
fu_byte_array_append_uint8 (buf, 0x0);
/* SignatureListSize */
fu_byte_array_append_uint32 (buf, 16 + 4 + 4 + 4 + 16 + 32, G_LITTLE_ENDIAN);
/* SignatureHeaderSize */
fu_byte_array_append_uint32 (buf, 0, G_LITTLE_ENDIAN);
/* SignatureSize */
fu_byte_array_append_uint32 (buf, 16 + 32, G_LITTLE_ENDIAN);
/* SignatureOwner */
for (guint i = 0; i < 16; i++)
fu_byte_array_append_uint8 (buf, '1');
/* SignatureData */
for (guint i = 0; i < 16; i++)
fu_byte_array_append_uint8 (buf, '2');
return g_byte_array_free_to_bytes (buf);
}
static void
fu_efi_signature_list_finalize (GObject *obj)
FuFirmware *
fu_efi_signature_list_new (void)
{
FuEfiSignatureList *self = FU_EFI_SIGNATURE_LIST (obj);
g_ptr_array_unref (self->items);
G_OBJECT_CLASS (fu_efi_signature_list_parent_class)->finalize (obj);
return g_object_new (FU_TYPE_EFI_SIGNATURE_LIST, NULL);
}
static void
fu_efi_signature_list_class_init (FuEfiSignatureListClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = fu_efi_signature_list_finalize;
FuFirmwareClass *klass_firmware = FU_FIRMWARE_CLASS (klass);
klass_firmware->parse = fu_efi_signature_list_parse;
klass_firmware->write = fu_efi_signature_list_write;
}
static void
fu_efi_signature_list_init (FuEfiSignatureList *self)
{
self->items = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
}
......@@ -6,16 +6,9 @@
#pragma once
#include "fu-efi-signature.h"
#include "fu-firmware.h"
#define FU_TYPE_EFI_SIGNATURE_LIST (fu_efi_signature_list_get_type ())
G_DECLARE_FINAL_TYPE (FuEfiSignatureList, fu_efi_signature_list, FU, EFI_SIGNATURE_LIST, GObject)
G_DECLARE_FINAL_TYPE (FuEfiSignatureList, fu_efi_signature_list, FU, EFI_SIGNATURE_LIST, FuFirmware)
FuEfiSignatureList*fu_efi_signature_list_new (FuEfiSignatureKind kind);
FuEfiSignatureKind fu_efi_signature_list_get_kind (FuEfiSignatureList *self);
void fu_efi_signature_list_add (FuEfiSignatureList *self,
FuEfiSignature *signature);