From bcaeda34ad71a60b629a1cbe3dffc7c349287d04 Mon Sep 17 00:00:00 2001 From: Daniel Campello Date: Thu, 24 Feb 2022 17:50:15 -0700 Subject: [PATCH] Backfill SHA256 when generating metadata from cab files This change allows for the computation of SHA256 checksum when generating metadata from cabinet file. This is particularly used when working with the directory type of remote config. Change-Id: I1a6e90a76b79cdae97d68d799a5cea81430da03f --- libfwupdplugin/fu-cabinet.c | 74 +++++++++++++++++++++++++------------ 1 file changed, 50 insertions(+), 24 deletions(-) diff --git a/libfwupdplugin/fu-cabinet.c b/libfwupdplugin/fu-cabinet.c index 3e47a6f10..02b7edc66 100644 --- a/libfwupdplugin/fu-cabinet.c +++ b/libfwupdplugin/fu-cabinet.c @@ -31,6 +31,7 @@ struct _FuCabinet { guint64 size_max; GCabCabinet *gcab_cabinet; gchar *container_checksum; + gchar *container_checksum_alt; XbBuilder *builder; XbSilo *silo; JcatContext *jcat_context; @@ -48,6 +49,7 @@ fu_cabinet_finalize(GObject *obj) if (self->builder != NULL) g_object_unref(self->builder); g_free(self->container_checksum); + g_free(self->container_checksum_alt); g_object_unref(self->gcab_cabinet); g_object_unref(self->jcat_context); g_object_unref(self->jcat_file); @@ -412,47 +414,70 @@ static XbBuilderNode * _xb_builder_node_get_child_by_element_attr(XbBuilderNode *bn, const gchar *element, const gchar *attr_name, - const gchar *attr_value) + const gchar *attr_value, + const gchar *attr2_name, + const gchar *attr2_value) { GPtrArray *bcs = xb_builder_node_get_children(bn); for (guint i = 0; i < bcs->len; i++) { XbBuilderNode *bc = g_ptr_array_index(bcs, i); if (g_strcmp0(xb_builder_node_get_element(bc), element) != 0) continue; - if (g_strcmp0(xb_builder_node_get_attr(bc, attr_name), attr_value) == 0) + if (g_strcmp0(xb_builder_node_get_attr(bc, attr_name), attr_value) != 0) + continue; + if (g_strcmp0(xb_builder_node_get_attr(bc, attr2_name), attr2_value) == 0) return g_object_ref(bc); } return NULL; } +static void +fu_cabinet_ensure_container_checksum(XbBuilderNode *bn, const gchar *type, const gchar *checksum) +{ + g_autoptr(XbBuilderNode) csum = NULL; + + /* verify it exists */ + csum = _xb_builder_node_get_child_by_element_attr(bn, + "checksum", + "type", + type, + "target", + "container"); + if (csum == NULL) { + csum = xb_builder_node_insert(bn, + "checksum", + "type", + type, + "target", + "container", + NULL); + } + + /* verify it is correct */ + if (g_strcmp0(xb_builder_node_get_text(csum), checksum) != 0) { + if (xb_builder_node_get_text(csum) != NULL) { + g_warning("invalid container checksum %s, fixing up to %s", + xb_builder_node_get_text(csum), + checksum); + } + xb_builder_node_set_text(csum, checksum, -1); + } +} + static gboolean -fu_cabinet_set_container_checksum_cb(XbBuilderFixup *builder_fixup, - XbBuilderNode *bn, - gpointer user_data, - GError **error) +fu_cabinet_ensure_container_checksum_cb(XbBuilderFixup *builder_fixup, + XbBuilderNode *bn, + gpointer user_data, + GError **error) { FuCabinet *self = FU_CABINET(user_data); - g_autoptr(XbBuilderNode) csum = NULL; /* not us */ if (g_strcmp0(xb_builder_node_get_element(bn), "release") != 0) return TRUE; - /* verify it exists */ - csum = _xb_builder_node_get_child_by_element_attr(bn, "checksum", "type", "container"); - if (csum == NULL) { - csum = xb_builder_node_insert(bn, "checksum", "target", "container", NULL); - } - - /* verify it is correct */ - if (g_strcmp0(xb_builder_node_get_text(csum), self->container_checksum) != 0) { - if (xb_builder_node_get_text(csum) != NULL) { - g_warning("invalid container checksum %s, fixing up to %s", - xb_builder_node_get_text(csum), - self->container_checksum); - } - xb_builder_node_set_text(csum, self->container_checksum, -1); - } + fu_cabinet_ensure_container_checksum(bn, "sha1", self->container_checksum); + fu_cabinet_ensure_container_checksum(bn, "sha256", self->container_checksum_alt); return TRUE; } @@ -673,8 +698,8 @@ fu_cabinet_build_silo(FuCabinet *self, GBytes *data, GError **error) xb_builder_add_fixup(self->builder, fixup1); /* ensure the container checksum is always set */ - fixup2 = xb_builder_fixup_new("SetContainerChecksum", - fu_cabinet_set_container_checksum_cb, + fixup2 = xb_builder_fixup_new("EnsureContainerChecksum", + fu_cabinet_ensure_container_checksum_cb, self, NULL); xb_builder_add_fixup(self->builder, fixup2); @@ -1046,6 +1071,7 @@ fu_cabinet_parse(FuCabinet *self, GBytes *data, FuCabinetParseFlags flags, GErro /* build xmlb silo */ self->container_checksum = g_compute_checksum_for_bytes(G_CHECKSUM_SHA1, data); + self->container_checksum_alt = g_compute_checksum_for_bytes(G_CHECKSUM_SHA256, data); if (!fu_cabinet_build_silo(self, data, error)) return FALSE;