Repository: fwupd/fwupd
Pull request #8671: Add the updated db as a HSI attribute
Author: login: hughsie
Created: 2025-04-08T12:19:03Z | Merged: 2025-04-08T16:39:58Z

This allows us to easily verify the machine state with `fwupdmgr security` or using a reporting agent like Red Hat Insights.

Type of pull request:

- [ ] New plugin (Please include [new plugin checklist](https://github.com/fwupd/fwupd/wiki/New-plugin-checklist))
- [ ] Code fix
- [ ] Feature
- [ ] Documentation



Diff:
diff --git a/docs/hsi-tests.d/meson.build b/docs/hsi-tests.d/meson.build
index 90154ab4fb8b..bfb6bd515f00 100644
--- a/docs/hsi-tests.d/meson.build
+++ b/docs/hsi-tests.d/meson.build
@@ -36,6 +36,7 @@ hsi_test_jsons = files([
   'org.fwupd.hsi.Uefi.BootserviceVars.json',
   'org.fwupd.hsi.Uefi.MemoryProtection.json',
   'org.fwupd.hsi.Uefi.Pk.json',
+  'org.fwupd.hsi.Uefi.Db.json',
   'org.fwupd.hsi.Uefi.SecureBoot.json',
   'org.fwupd.hsi.Bios.RollbackProtection.json',
   'org.fwupd.hsi.Amd.SmmLocked.json',
diff --git a/docs/hsi-tests.d/org.fwupd.hsi.Uefi.Db.json b/docs/hsi-tests.d/org.fwupd.hsi.Uefi.Db.json
new file mode 100644
index 000000000000..8c9185ac758d
--- /dev/null
+++ b/docs/hsi-tests.d/org.fwupd.hsi.Uefi.Db.json
@@ -0,0 +1,21 @@
+{
+  "id": "org.fwupd.hsi.Uefi.Db",
+  "name": "UEFI db",
+  "description": [
+    "The UEFI db contains the list of valid certificates that is used to authorize what EFI binaries are allowed to run."
+  ],
+  "failure-impact": [
+    "Distribution-provided signed bootloader binaries may not boot on any system that does not have the new Microsoft UEFI certificate installed in the db."
+  ],
+  "failure-results": {
+    "not-valid": "the certificate store is not up to date"
+  },
+  "success-results": {
+    "not-found": "the certificate store does not contain any Microsoft UEFI certificate",
+    "valid": "the certificate store has the Microsoft UEFI 2023 certificate installed"
+  },
+  "references": {
+    "https://wiki.ubuntu.com/UEFI/SecureBoot/Testing": "Ubuntu SecureBoot Wiki Page"
+  },
+  "fwupd-version": "2.0.8"
+}
diff --git a/libfwupd/fwupd-security-attr-private.h b/libfwupd/fwupd-security-attr-private.h
index a3f36284b7e2..5850a5b5379e 100644
--- a/libfwupd/fwupd-security-attr-private.h
+++ b/libfwupd/fwupd-security-attr-private.h
@@ -396,6 +396,14 @@ G_BEGIN_DECLS
  * Since: 2.0.7
  **/
 #define FWUPD_SECURITY_ATTR_ID_UEFI_MEMORY_PROTECTION "org.fwupd.hsi.Uefi.MemoryProtection"
+/**
+ * FWUPD_SECURITY_ATTR_ID_UEFI_DB:
+ *
+ * Host Security ID attribute for UEFI db certificate store
+ *
+ * Since: 2.0.8
+ **/
+#define FWUPD_SECURITY_ATTR_ID_UEFI_DB "org.fwupd.hsi.Uefi.Db"
 
 FwupdSecurityAttr *
 fwupd_security_attr_copy(FwupdSecurityAttr *self) G_GNUC_NON_NULL(1);
diff --git a/libfwupdplugin/fu-security-attrs.c b/libfwupdplugin/fu-security-attrs.c
index e62c06960a95..2d95d921b198 100644
--- a/libfwupdplugin/fu-security-attrs.c
+++ b/libfwupdplugin/fu-security-attrs.c
@@ -405,6 +405,7 @@ static struct {
     {FWUPD_SECURITY_ATTR_ID_BIOS_CAPSULE_UPDATES, FWUPD_SECURITY_ATTR_LEVEL_CRITICAL},
     {FWUPD_SECURITY_ATTR_ID_AMD_SMM_LOCKED, FWUPD_SECURITY_ATTR_LEVEL_CRITICAL},
     {FWUPD_SECURITY_ATTR_ID_UEFI_MEMORY_PROTECTION, FWUPD_SECURITY_ATTR_LEVEL_IMPORTANT},
+    {FWUPD_SECURITY_ATTR_ID_UEFI_DB, FWUPD_SECURITY_ATTR_LEVEL_IMPORTANT},
 };
 
 static void
@@ -475,6 +476,7 @@ static struct {
     {FWUPD_SECURITY_ATTR_ID_TPM_RECONSTRUCTION_PCR0, "1.5.0"},
     {FWUPD_SECURITY_ATTR_ID_TPM_VERSION_20, "1.5.0"},
     {FWUPD_SECURITY_ATTR_ID_UEFI_BOOTSERVICE_VARS, "1.9.3"},
+    {FWUPD_SECURITY_ATTR_ID_UEFI_DB, "2.0.8"},
     {FWUPD_SECURITY_ATTR_ID_UEFI_MEMORY_PROTECTION, "2.0.7"},
     {FWUPD_SECURITY_ATTR_ID_UEFI_PK, "1.5.0"},
     {FWUPD_SECURITY_ATTR_ID_UEFI_SECUREBOOT, "1.5.0"},
diff --git a/plugins/uefi-db/fu-uefi-db-device.c b/plugins/uefi-db/fu-uefi-db-device.c
index a41ac3853cad..e5b009eacb5d 100644
--- a/plugins/uefi-db/fu-uefi-db-device.c
+++ b/plugins/uefi-db/fu-uefi-db-device.c
@@ -86,6 +86,49 @@ fu_uefi_db_device_write_firmware(FuDevice *device,
 	return TRUE;
 }
 
+static void
+fu_uefi_db_device_add_security_attrs(FuDevice *device, FuSecurityAttrs *attrs)
+{
+	GPtrArray *children = fu_device_get_children(device);
+	gboolean seen_old = FALSE;
+	gboolean seen_new = FALSE;
+	g_autoptr(FwupdSecurityAttr) attr = NULL;
+
+	/* create attr */
+	attr = fu_device_security_attr_new(device, FWUPD_SECURITY_ATTR_ID_UEFI_DB);
+	fwupd_security_attr_set_result_success(attr, FWUPD_SECURITY_ATTR_RESULT_VALID);
+	fwupd_security_attr_add_flag(attr, FWUPD_SECURITY_ATTR_FLAG_RUNTIME_ISSUE);
+	fwupd_security_attr_add_flag(attr, FWUPD_SECURITY_ATTR_FLAG_ACTION_CONFIG_FW);
+	fu_security_attrs_append(attrs, attr);
+
+	/* look for both versions of the Microsoft UEFI CA */
+	for (guint i = 0; i < children->len; i++) {
+		FuDevice *child = g_ptr_array_index(children, i);
+		if (fu_device_has_instance_id(child,
+					      "UEFI\\CRT_A5B7C551CEDC06B94D0C5B920F473E03C2F142F2",
+					      FU_DEVICE_INSTANCE_FLAG_VISIBLE)) {
+			seen_new = TRUE;
+			break;
+		}
+		if (fu_device_has_instance_id(child,
+					      "UEFI\\CRT_03DE12BE14CA397DF20CEE646C7D9B727FCCE5F8",
+					      FU_DEVICE_INSTANCE_FLAG_VISIBLE)) {
+			seen_old = TRUE;
+			break;
+		}
+	}
+
+	if (!seen_new && !seen_old) {
+		/* user is using a custom UEFI db, just ignore this HSI attribute */
+		fwupd_security_attr_add_flag(attr, FWUPD_SECURITY_ATTR_FLAG_SUCCESS);
+		fwupd_security_attr_set_result(attr, FWUPD_SECURITY_ATTR_RESULT_NOT_FOUND);
+	} else if (seen_new) {
+		fwupd_security_attr_add_flag(attr, FWUPD_SECURITY_ATTR_FLAG_SUCCESS);
+	} else {
+		fwupd_security_attr_set_result(attr, FWUPD_SECURITY_ATTR_RESULT_NOT_VALID);
+	}
+}
+
 static void
 fu_uefi_db_device_set_progress(FuDevice *self, FuProgress *progress)
 {
@@ -114,5 +157,6 @@ fu_uefi_db_device_class_init(FuUefiDbDeviceClass *klass)
 	FuDeviceClass *device_class = FU_DEVICE_CLASS(klass);
 	device_class->probe = fu_uefi_db_device_probe;
 	device_class->write_firmware = fu_uefi_db_device_write_firmware;
+	device_class->add_security_attrs = fu_uefi_db_device_add_security_attrs;
 	device_class->set_progress = fu_uefi_db_device_set_progress;
 }
diff --git a/src/fu-security-attr-common.c b/src/fu-security-attr-common.c
index f437fe421b72..64576f7cd15e 100644
--- a/src/fu-security-attr-common.c
+++ b/src/fu-security-attr-common.c
@@ -231,6 +231,10 @@ fu_security_attr_get_name(FwupdSecurityAttr *attr)
 		/* TRANSLATORS: Title: is UEFI early-boot memory protection turned on */
 		return g_strdup(_("UEFI memory protection"));
 	}
+	if (g_strcmp0(appstream_id, FWUPD_SECURITY_ATTR_ID_UEFI_DB) == 0) {
+		/* TRANSLATORS: Title: is UEFI db up-to-date */
+		return g_strdup(_("UEFI db"));
+	}
 	/* we should not get here */
 	return g_strdup(fwupd_security_attr_get_name(attr));
 }
@@ -420,6 +424,10 @@ fu_security_attr_get_title(FwupdSecurityAttr *attr)
 		/* TRANSLATORS: Title: is UEFI early-boot memory protection turned on */
 		return _("UEFI Memory Protection");
 	}
+	if (g_strcmp0(appstream_id, FWUPD_SECURITY_ATTR_ID_UEFI_DB) == 0) {
+		/* TRANSLATORS: Title: is UEFI db up-to-date */
+		return _("UEFI db");
+	}
 	return NULL;
 }
 
@@ -618,5 +626,10 @@ fu_security_attr_get_description(FwupdSecurityAttr *attr)
 		return _("The UEFI system can set up memory attributes at boot which prevent "
 			 "common exploits from running.");
 	}
+	if (g_strcmp0(appstream_id, FWUPD_SECURITY_ATTR_ID_UEFI_DB) == 0) {
+		/* TRANSLATORS: longer description */
+		return _("The UEFI db contains the list of valid certificates that can be used to "
+			 "authorize what EFI binaries are allowed to run.");
+	}
 	return NULL;
 }
diff --git a/src/fu-self-test.c b/src/fu-self-test.c
index 0fe7e821c292..166fe48925ed 100644
--- a/src/fu-self-test.c
+++ b/src/fu-self-test.c
@@ -1050,6 +1050,7 @@ fu_engine_plugin_device_gtype(FuTest *self, GType gtype)
 	g_autofree gchar *str = NULL;
 	g_autoptr(FuDevice) device = NULL;
 	g_autoptr(FuProgress) progress_tmp = fu_progress_new(G_STRLOC);
+	g_autoptr(FuSecurityAttrs) attrs = fu_security_attrs_new();
 	g_autoptr(GError) error = NULL;
 	g_autoptr(GHashTable) metadata_post = NULL;
 	g_autoptr(GHashTable) metadata_pre = NULL;
@@ -1063,6 +1064,7 @@ fu_engine_plugin_device_gtype(FuTest *self, GType gtype)
 	g_debug("loading %s", g_type_name(gtype));
 	device = g_object_new(gtype, "context", self->ctx, "physical-id", "/sys", NULL);
 	g_assert_nonnull(device);
+	fu_device_set_plugin(device, "test");
 
 	/* version convert */
 	if (fu_device_get_version_format(device) != FWUPD_VERSION_FORMAT_UNKNOWN)
@@ -1079,6 +1081,9 @@ fu_engine_plugin_device_gtype(FuTest *self, GType gtype)
 	if (metadata_post != NULL)
 		g_debug("got %u metadata items", g_hash_table_size(metadata_post));
 
+	/* security attrs */
+	fu_device_add_security_attrs(device, attrs);
+
 	/* quirk kvs */
 	ret = fu_device_set_quirk_kv(device,
 				     "NoGoingTo",
diff --git a/src/fu-util-common.c b/src/fu-util-common.c
index 171ccb735312..b47ab0c76cb9 100644
--- a/src/fu-util-common.c
+++ b/src/fu-util-common.c
@@ -2417,6 +2417,11 @@ fu_util_security_event_to_string(FwupdSecurityAttr *attr)
 		      FWUPD_SECURITY_ATTR_RESULT_NOT_LOCKED,
 		      /* TRANSLATORS: HSI event title */
 		      _("UEFI memory protection is now unlocked")},
+		     {FWUPD_SECURITY_ATTR_ID_UEFI_DB,
+		      FWUPD_SECURITY_ATTR_RESULT_NOT_VALID,
+		      FWUPD_SECURITY_ATTR_RESULT_VALID,
+		      /* TRANSLATORS: HSI event title */
+		      _("The UEFI certificate store is now up to date")},
 		     {NULL, 0, 0, NULL}};
 
 	/* sanity check */


Reviews:
user: login: superm1
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-08T13:25:42Z
user: login: superm1
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-08T13:26:17Z
user: login: superm1
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-08T13:26:38Z
user: login: superm1
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-08T13:28:44Z
user: login: hughsie
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-08T13:31:50Z
user: login: hughsie
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-08T13:32:28Z
user: login: hughsie
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-08T13:32:59Z
user: login: superm1
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-08T13:33:40Z
user: login: superm1
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-08T13:34:00Z
user: login: superm1
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-08T13:34:35Z
user: login: hughsie
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-08T14:36:22Z
user: login: hughsie
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-08T14:36:33Z
user: login: hughsie
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-08T14:36:53Z
user: login: hughsie
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-08T14:38:10Z
user: login: superm1
state: DISMISSED
author_association: MEMBER
submitted_at: 2025-04-08T14:42:07Z
user: login: superm1
state: APPROVED
author_association: MEMBER
submitted_at: 2025-04-08T16:16:13Z

Review comments:
diff_hunk: @@ -0,0 +1,21 @@
+{
+  "id": "org.fwupd.hsi.Uefi.Db",
+  "name": "UEFI db",
+  "description": [
+    "The UEFI db contains the list of valid certificates that is used to authorize what EFI binaries are allowed to run."
+  ],
+  "failure-impact": [
+    "Distribution-provided signed bootloader binaries may not boot on any system that does not have the new Microsoft UEFI certificate installed in the db."
+  ],
+  "failure-results": {
+    "not-valid": "the certificate store is not up to date"
+  },
+  "success-results": {
+    "valid": "the certificate store has the Microsoft UEFI 2023 certificate installed"
+  },
+  "hsi-level": 2,
path: docs/hsi-tests.d/org.fwupd.hsi.Uefi.Db.json
user: login: superm1
body: this is currently marked as runtime suffix not HSI-2 in this PR
created_at: 2025-04-08T13:25:42Z
author_association: MEMBER
diff_hunk: @@ -86,6 +86,49 @@ fu_uefi_db_device_write_firmware(FuDevice *device,
 	return TRUE;
 }
 
+static void
+fu_uefi_db_device_add_security_attrs(FuDevice *device, FuSecurityAttrs *attrs)
+{
+	GPtrArray *children = fu_device_get_children(device);
+	gboolean seen_old = FALSE;
+	gboolean seen_new = FALSE;
+	g_autoptr(FwupdSecurityAttr) attr = NULL;
+
+	/* look for both versions of the Microsoft UEFI CA */
+	for (guint i = 0; i < children->len; i++) {
+		FuDevice *child = g_ptr_array_index(children, i);
+		if (fu_device_has_instance_id(child,
+					      "UEFI\\CRT_A5B7C551CEDC06B94D0C5B920F473E03C2F142F2",
+					      FU_DEVICE_INSTANCE_FLAG_VISIBLE)) {
+			seen_new = TRUE;
+			break;
+		}
+		if (fu_device_has_instance_id(child,
+					      "UEFI\\CRT_03DE12BE14CA397DF20CEE646C7D9B727FCCE5F8",
+					      FU_DEVICE_INSTANCE_FLAG_VISIBLE)) {
+			seen_old = TRUE;
+			break;
+		}
+	}
+
+	/* user is using a custom UEFI db, just ignore this HSI attribute */
+	if (!seen_new && !seen_old)
+		return;
+
+	/* create attr */
+	attr = fu_device_security_attr_new(device, FWUPD_SECURITY_ATTR_ID_UEFI_DB);
+	fwupd_security_attr_set_result_success(attr, FWUPD_SECURITY_ATTR_RESULT_VALID);
+	fwupd_security_attr_add_flag(attr, FWUPD_SECURITY_ATTR_FLAG_CAN_FIX);
+	fwupd_security_attr_add_flag(attr, FWUPD_SECURITY_ATTR_FLAG_RUNTIME_ISSUE);
path: plugins/uefi-db/fu-uefi-db-device.c
user: login: superm1
body: need to decide if runtime issue or HSI2
created_at: 2025-04-08T13:26:17Z
author_association: MEMBER
diff_hunk: @@ -86,6 +86,49 @@ fu_uefi_db_device_write_firmware(FuDevice *device,
 	return TRUE;
 }
 
+static void
+fu_uefi_db_device_add_security_attrs(FuDevice *device, FuSecurityAttrs *attrs)
+{
+	GPtrArray *children = fu_device_get_children(device);
+	gboolean seen_old = FALSE;
+	gboolean seen_new = FALSE;
+	g_autoptr(FwupdSecurityAttr) attr = NULL;
+
+	/* look for both versions of the Microsoft UEFI CA */
+	for (guint i = 0; i < children->len; i++) {
+		FuDevice *child = g_ptr_array_index(children, i);
+		if (fu_device_has_instance_id(child,
+					      "UEFI\\CRT_A5B7C551CEDC06B94D0C5B920F473E03C2F142F2",
+					      FU_DEVICE_INSTANCE_FLAG_VISIBLE)) {
+			seen_new = TRUE;
+			break;
+		}
+		if (fu_device_has_instance_id(child,
+					      "UEFI\\CRT_03DE12BE14CA397DF20CEE646C7D9B727FCCE5F8",
+					      FU_DEVICE_INSTANCE_FLAG_VISIBLE)) {
+			seen_old = TRUE;
+			break;
+		}
+	}
+
+	/* user is using a custom UEFI db, just ignore this HSI attribute */
+	if (!seen_new && !seen_old)
+		return;
+
+	/* create attr */
+	attr = fu_device_security_attr_new(device, FWUPD_SECURITY_ATTR_ID_UEFI_DB);
+	fwupd_security_attr_set_result_success(attr, FWUPD_SECURITY_ATTR_RESULT_VALID);
+	fwupd_security_attr_add_flag(attr, FWUPD_SECURITY_ATTR_FLAG_CAN_FIX);
path: plugins/uefi-db/fu-uefi-db-device.c
user: login: superm1
body: is this really can fix?  Not all the OEMs are going to roll out PK and KEK updates are they?
created_at: 2025-04-08T13:26:38Z
author_association: MEMBER
diff_hunk: @@ -2417,6 +2417,16 @@ fu_util_security_event_to_string(FwupdSecurityAttr *attr)
 		      FWUPD_SECURITY_ATTR_RESULT_NOT_LOCKED,
 		      /* TRANSLATORS: HSI event title */
 		      _("UEFI memory protection is now unlocked")},
+		     {FWUPD_SECURITY_ATTR_ID_UEFI_DB,
+		      FWUPD_SECURITY_ATTR_RESULT_NOT_VALID,
+		      FWUPD_SECURITY_ATTR_RESULT_VALID,
+		      /* TRANSLATORS: HSI event title */
+		      _("The latest UEFI certificate has been installed")},
path: src/fu-util-common.c
user: login: superm1
body: _latest_ won't age well
created_at: 2025-04-08T13:28:44Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,21 @@
+{
+  "id": "org.fwupd.hsi.Uefi.Db",
+  "name": "UEFI db",
+  "description": [
+    "The UEFI db contains the list of valid certificates that is used to authorize what EFI binaries are allowed to run."
+  ],
+  "failure-impact": [
+    "Distribution-provided signed bootloader binaries may not boot on any system that does not have the new Microsoft UEFI certificate installed in the db."
+  ],
+  "failure-results": {
+    "not-valid": "the certificate store is not up to date"
+  },
+  "success-results": {
+    "valid": "the certificate store has the Microsoft UEFI 2023 certificate installed"
+  },
+  "hsi-level": 2,
path: docs/hsi-tests.d/org.fwupd.hsi.Uefi.Db.json
user: login: hughsie
body: ya, I flip-flopped on this -- I'm not sure it really fits as HSI-2 -- it's not a security problem per-se -- it just means that things might not work in the future.
created_at: 2025-04-08T13:31:50Z
author_association: MEMBER
diff_hunk: @@ -86,6 +86,49 @@ fu_uefi_db_device_write_firmware(FuDevice *device,
 	return TRUE;
 }
 
+static void
+fu_uefi_db_device_add_security_attrs(FuDevice *device, FuSecurityAttrs *attrs)
+{
+	GPtrArray *children = fu_device_get_children(device);
+	gboolean seen_old = FALSE;
+	gboolean seen_new = FALSE;
+	g_autoptr(FwupdSecurityAttr) attr = NULL;
+
+	/* look for both versions of the Microsoft UEFI CA */
+	for (guint i = 0; i < children->len; i++) {
+		FuDevice *child = g_ptr_array_index(children, i);
+		if (fu_device_has_instance_id(child,
+					      "UEFI\\CRT_A5B7C551CEDC06B94D0C5B920F473E03C2F142F2",
+					      FU_DEVICE_INSTANCE_FLAG_VISIBLE)) {
+			seen_new = TRUE;
+			break;
+		}
+		if (fu_device_has_instance_id(child,
+					      "UEFI\\CRT_03DE12BE14CA397DF20CEE646C7D9B727FCCE5F8",
+					      FU_DEVICE_INSTANCE_FLAG_VISIBLE)) {
+			seen_old = TRUE;
+			break;
+		}
+	}
+
+	/* user is using a custom UEFI db, just ignore this HSI attribute */
+	if (!seen_new && !seen_old)
+		return;
+
+	/* create attr */
+	attr = fu_device_security_attr_new(device, FWUPD_SECURITY_ATTR_ID_UEFI_DB);
+	fwupd_security_attr_set_result_success(attr, FWUPD_SECURITY_ATTR_RESULT_VALID);
+	fwupd_security_attr_add_flag(attr, FWUPD_SECURITY_ATTR_FLAG_CAN_FIX);
path: plugins/uefi-db/fu-uefi-db-device.c
user: login: hughsie
body: According to an inside source, the OEM reception to this has been lukewarm to say the least.
created_at: 2025-04-08T13:32:28Z
author_association: MEMBER
diff_hunk: @@ -2417,6 +2417,16 @@ fu_util_security_event_to_string(FwupdSecurityAttr *attr)
 		      FWUPD_SECURITY_ATTR_RESULT_NOT_LOCKED,
 		      /* TRANSLATORS: HSI event title */
 		      _("UEFI memory protection is now unlocked")},
+		     {FWUPD_SECURITY_ATTR_ID_UEFI_DB,
+		      FWUPD_SECURITY_ATTR_RESULT_NOT_VALID,
+		      FWUPD_SECURITY_ATTR_RESULT_VALID,
+		      /* TRANSLATORS: HSI event title */
+		      _("The latest UEFI certificate has been installed")},
path: src/fu-util-common.c
user: login: hughsie
body: `The UEFI certificate store is up to date` perhaps?
created_at: 2025-04-08T13:32:59Z
author_association: MEMBER
diff_hunk: @@ -2417,6 +2417,16 @@ fu_util_security_event_to_string(FwupdSecurityAttr *attr)
 		      FWUPD_SECURITY_ATTR_RESULT_NOT_LOCKED,
 		      /* TRANSLATORS: HSI event title */
 		      _("UEFI memory protection is now unlocked")},
+		     {FWUPD_SECURITY_ATTR_ID_UEFI_DB,
+		      FWUPD_SECURITY_ATTR_RESULT_NOT_VALID,
+		      FWUPD_SECURITY_ATTR_RESULT_VALID,
+		      /* TRANSLATORS: HSI event title */
+		      _("The latest UEFI certificate has been installed")},
path: src/fu-util-common.c
user: login: superm1
body: Yeah; I think that's better
created_at: 2025-04-08T13:33:40Z
author_association: MEMBER
diff_hunk: @@ -86,6 +86,49 @@ fu_uefi_db_device_write_firmware(FuDevice *device,
 	return TRUE;
 }
 
+static void
+fu_uefi_db_device_add_security_attrs(FuDevice *device, FuSecurityAttrs *attrs)
+{
+	GPtrArray *children = fu_device_get_children(device);
+	gboolean seen_old = FALSE;
+	gboolean seen_new = FALSE;
+	g_autoptr(FwupdSecurityAttr) attr = NULL;
+
+	/* look for both versions of the Microsoft UEFI CA */
+	for (guint i = 0; i < children->len; i++) {
+		FuDevice *child = g_ptr_array_index(children, i);
+		if (fu_device_has_instance_id(child,
+					      "UEFI\\CRT_A5B7C551CEDC06B94D0C5B920F473E03C2F142F2",
+					      FU_DEVICE_INSTANCE_FLAG_VISIBLE)) {
+			seen_new = TRUE;
+			break;
+		}
+		if (fu_device_has_instance_id(child,
+					      "UEFI\\CRT_03DE12BE14CA397DF20CEE646C7D9B727FCCE5F8",
+					      FU_DEVICE_INSTANCE_FLAG_VISIBLE)) {
+			seen_old = TRUE;
+			break;
+		}
+	}
+
+	/* user is using a custom UEFI db, just ignore this HSI attribute */
+	if (!seen_new && !seen_old)
+		return;
+
+	/* create attr */
+	attr = fu_device_security_attr_new(device, FWUPD_SECURITY_ATTR_ID_UEFI_DB);
+	fwupd_security_attr_set_result_success(attr, FWUPD_SECURITY_ATTR_RESULT_VALID);
+	fwupd_security_attr_add_flag(attr, FWUPD_SECURITY_ATTR_FLAG_CAN_FIX);
path: plugins/uefi-db/fu-uefi-db-device.c
user: login: superm1
body: Yeah that's what I was suspecting. 
created_at: 2025-04-08T13:33:59Z
author_association: MEMBER
diff_hunk: @@ -86,6 +86,49 @@ fu_uefi_db_device_write_firmware(FuDevice *device,
 	return TRUE;
 }
 
+static void
+fu_uefi_db_device_add_security_attrs(FuDevice *device, FuSecurityAttrs *attrs)
+{
+	GPtrArray *children = fu_device_get_children(device);
+	gboolean seen_old = FALSE;
+	gboolean seen_new = FALSE;
+	g_autoptr(FwupdSecurityAttr) attr = NULL;
+
+	/* look for both versions of the Microsoft UEFI CA */
+	for (guint i = 0; i < children->len; i++) {
+		FuDevice *child = g_ptr_array_index(children, i);
+		if (fu_device_has_instance_id(child,
+					      "UEFI\\CRT_A5B7C551CEDC06B94D0C5B920F473E03C2F142F2",
+					      FU_DEVICE_INSTANCE_FLAG_VISIBLE)) {
+			seen_new = TRUE;
+			break;
+		}
+		if (fu_device_has_instance_id(child,
+					      "UEFI\\CRT_03DE12BE14CA397DF20CEE646C7D9B727FCCE5F8",
+					      FU_DEVICE_INSTANCE_FLAG_VISIBLE)) {
+			seen_old = TRUE;
+			break;
+		}
+	}
+
+	/* user is using a custom UEFI db, just ignore this HSI attribute */
+	if (!seen_new && !seen_old)
+		return;
+
+	/* create attr */
+	attr = fu_device_security_attr_new(device, FWUPD_SECURITY_ATTR_ID_UEFI_DB);
+	fwupd_security_attr_set_result_success(attr, FWUPD_SECURITY_ATTR_RESULT_VALID);
+	fwupd_security_attr_add_flag(attr, FWUPD_SECURITY_ATTR_FLAG_CAN_FIX);
path: plugins/uefi-db/fu-uefi-db-device.c
user: login: superm1
body: Can we leave out `CAN_FIX` and later control that based upon OEMs actually _releasing_ updates?
created_at: 2025-04-08T13:34:35Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,21 @@
+{
+  "id": "org.fwupd.hsi.Uefi.Db",
+  "name": "UEFI db",
+  "description": [
+    "The UEFI db contains the list of valid certificates that is used to authorize what EFI binaries are allowed to run."
+  ],
+  "failure-impact": [
+    "Distribution-provided signed bootloader binaries may not boot on any system that does not have the new Microsoft UEFI certificate installed in the db."
+  ],
+  "failure-results": {
+    "not-valid": "the certificate store is not up to date"
+  },
+  "success-results": {
+    "valid": "the certificate store has the Microsoft UEFI 2023 certificate installed"
+  },
+  "hsi-level": 2,
path: docs/hsi-tests.d/org.fwupd.hsi.Uefi.Db.json
user: login: hughsie
body: Removed.
created_at: 2025-04-08T14:36:22Z
author_association: MEMBER
diff_hunk: @@ -86,6 +86,49 @@ fu_uefi_db_device_write_firmware(FuDevice *device,
 	return TRUE;
 }
 
+static void
+fu_uefi_db_device_add_security_attrs(FuDevice *device, FuSecurityAttrs *attrs)
+{
+	GPtrArray *children = fu_device_get_children(device);
+	gboolean seen_old = FALSE;
+	gboolean seen_new = FALSE;
+	g_autoptr(FwupdSecurityAttr) attr = NULL;
+
+	/* look for both versions of the Microsoft UEFI CA */
+	for (guint i = 0; i < children->len; i++) {
+		FuDevice *child = g_ptr_array_index(children, i);
+		if (fu_device_has_instance_id(child,
+					      "UEFI\\CRT_A5B7C551CEDC06B94D0C5B920F473E03C2F142F2",
+					      FU_DEVICE_INSTANCE_FLAG_VISIBLE)) {
+			seen_new = TRUE;
+			break;
+		}
+		if (fu_device_has_instance_id(child,
+					      "UEFI\\CRT_03DE12BE14CA397DF20CEE646C7D9B727FCCE5F8",
+					      FU_DEVICE_INSTANCE_FLAG_VISIBLE)) {
+			seen_old = TRUE;
+			break;
+		}
+	}
+
+	/* user is using a custom UEFI db, just ignore this HSI attribute */
+	if (!seen_new && !seen_old)
+		return;
+
+	/* create attr */
+	attr = fu_device_security_attr_new(device, FWUPD_SECURITY_ATTR_ID_UEFI_DB);
+	fwupd_security_attr_set_result_success(attr, FWUPD_SECURITY_ATTR_RESULT_VALID);
+	fwupd_security_attr_add_flag(attr, FWUPD_SECURITY_ATTR_FLAG_CAN_FIX);
+	fwupd_security_attr_add_flag(attr, FWUPD_SECURITY_ATTR_FLAG_RUNTIME_ISSUE);
path: plugins/uefi-db/fu-uefi-db-device.c
user: login: hughsie
body: Lets go runtime for now.
created_at: 2025-04-08T14:36:33Z
author_association: MEMBER
diff_hunk: @@ -86,6 +86,49 @@ fu_uefi_db_device_write_firmware(FuDevice *device,
 	return TRUE;
 }
 
+static void
+fu_uefi_db_device_add_security_attrs(FuDevice *device, FuSecurityAttrs *attrs)
+{
+	GPtrArray *children = fu_device_get_children(device);
+	gboolean seen_old = FALSE;
+	gboolean seen_new = FALSE;
+	g_autoptr(FwupdSecurityAttr) attr = NULL;
+
+	/* look for both versions of the Microsoft UEFI CA */
+	for (guint i = 0; i < children->len; i++) {
+		FuDevice *child = g_ptr_array_index(children, i);
+		if (fu_device_has_instance_id(child,
+					      "UEFI\\CRT_A5B7C551CEDC06B94D0C5B920F473E03C2F142F2",
+					      FU_DEVICE_INSTANCE_FLAG_VISIBLE)) {
+			seen_new = TRUE;
+			break;
+		}
+		if (fu_device_has_instance_id(child,
+					      "UEFI\\CRT_03DE12BE14CA397DF20CEE646C7D9B727FCCE5F8",
+					      FU_DEVICE_INSTANCE_FLAG_VISIBLE)) {
+			seen_old = TRUE;
+			break;
+		}
+	}
+
+	/* user is using a custom UEFI db, just ignore this HSI attribute */
+	if (!seen_new && !seen_old)
+		return;
+
+	/* create attr */
+	attr = fu_device_security_attr_new(device, FWUPD_SECURITY_ATTR_ID_UEFI_DB);
+	fwupd_security_attr_set_result_success(attr, FWUPD_SECURITY_ATTR_RESULT_VALID);
+	fwupd_security_attr_add_flag(attr, FWUPD_SECURITY_ATTR_FLAG_CAN_FIX);
path: plugins/uefi-db/fu-uefi-db-device.c
user: login: hughsie
body: Done.
created_at: 2025-04-08T14:36:52Z
author_association: MEMBER
diff_hunk: @@ -2417,6 +2417,16 @@ fu_util_security_event_to_string(FwupdSecurityAttr *attr)
 		      FWUPD_SECURITY_ATTR_RESULT_NOT_LOCKED,
 		      /* TRANSLATORS: HSI event title */
 		      _("UEFI memory protection is now unlocked")},
+		     {FWUPD_SECURITY_ATTR_ID_UEFI_DB,
+		      FWUPD_SECURITY_ATTR_RESULT_NOT_VALID,
+		      FWUPD_SECURITY_ATTR_RESULT_VALID,
+		      /* TRANSLATORS: HSI event title */
+		      _("The latest UEFI certificate has been installed")},
path: src/fu-util-common.c
user: login: hughsie
body: Fixed
created_at: 2025-04-08T14:38:09Z
author_association: MEMBER

PR comments:
user: login: hughsie
created_at: 2025-04-08T12:45:11Z
body: I'm in two minds about adding this before we've got the KEK blobs from OEMs -- i.e. the user can't actually fix it yet.
author_association: MEMBER
user: login: superm1
created_at: 2025-04-08T14:43:03Z
body: Oh I had one thought I wanted to mention - when is the expiry of the current cert?  Should fwupd showing a **failure** be _tied to that date_?
author_association: MEMBER
user: login: hughsie
created_at: 2025-04-08T14:45:01Z
body: > when is the expiry of the current cert

End of this year, but we'll have a new fwupd release before that. Plus; QA hates when things change because of a date!
author_association: MEMBER
user: login: superm1
created_at: 2025-04-08T15:02:29Z
body: > > when is the expiry of the current cert
> 
> End of this year, but we'll have a new fwupd release before that. Plus; QA hates when things change because of a date!

Yeah I know qa hates that, but it's the reality of when it will stop booting too.

There could always be test cases that cover the difference of date by emulating a later date.
author_association: MEMBER