From: Alexander Larsson Date: Mon, 15 May 2023 13:18:16 +0000 (+0200) Subject: Commit: Add composefs digest and sig to the commit metadata X-Git-Tag: archive/raspbian/2023.7-3+rpi1~1^2~9^2~1^2~29^2~9 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=0c3d9894be1f1fa0a825aa7b16c119b72c4edc7e;p=ostree.git Commit: Add composefs digest and sig to the commit metadata If `composefs-apply-sig` is enabled (default no) we add an ostree.composefs digest to the commit metadata. This can be verified on deploy. This is a separate option from the generic `composefs` option which controls whether composefs is used during deploy. It is separate because we want to not have to force use of fs-verity, etc during the build. If the `composefs-certfile` and `composefs-keyfile` keys in the ex-integrity group are set, then the commit metadata also gets a ostree.composefs-sig containing the signature of the composefs file. --- diff --git a/src/libostree/ostree-repo-commit.c b/src/libostree/ostree-repo-commit.c index 0900205f..fe924861 100644 --- a/src/libostree/ostree-repo-commit.c +++ b/src/libostree/ostree-repo-commit.c @@ -398,14 +398,9 @@ compare_ascii_checksums_for_sorting (gconstpointer a_pp, gconstpointer b_pp) /* * Create sizes metadata GVariant and add it to the metadata variant given. */ -static GVariant * -add_size_index_to_metadata (OstreeRepo *self, GVariant *original_metadata) +static void +add_size_index_to_metadata (OstreeRepo *self, GVariantBuilder *builder) { - g_autoptr (GVariantBuilder) builder = NULL; - - /* original_metadata may be NULL */ - builder = ot_util_variant_builder_from_variant (original_metadata, G_VARIANT_TYPE ("a{sv}")); - if (self->object_sizes && g_hash_table_size (self->object_sizes) > 0) { GVariantBuilder index_builder; @@ -443,8 +438,6 @@ add_size_index_to_metadata (OstreeRepo *self, GVariant *original_metadata) /* Clear the object sizes hash table for a subsequent commit. */ g_hash_table_remove_all (self->object_sizes); } - - return g_variant_ref_sink (g_variant_builder_end (builder)); } static gboolean @@ -2912,6 +2905,23 @@ ostree_repo_write_commit (OstreeRepo *self, const char *parent, const char *subj out_commit, cancellable, error); } +static GVariant * +add_auto_metadata (OstreeRepo *self, GVariant *original_metadata, OstreeRepoFile *repo_root, + GCancellable *cancellable, GError **error) +{ + g_autoptr (GVariantBuilder) builder = NULL; + + /* original_metadata may be NULL */ + builder = ot_util_variant_builder_from_variant (original_metadata, G_VARIANT_TYPE ("a{sv}")); + + add_size_index_to_metadata (self, builder); + + if (!ostree_repo_commit_add_composefs_metadata (self, builder, repo_root, cancellable, error)) + return NULL; + + return g_variant_ref_sink (g_variant_builder_end (builder)); +} + /** * ostree_repo_write_commit_with_time: * @self: Repo @@ -2938,7 +2948,10 @@ ostree_repo_write_commit_with_time (OstreeRepo *self, const char *parent, const OstreeRepoFile *repo_root = OSTREE_REPO_FILE (root); /* Add sizes information to our metadata object */ - g_autoptr (GVariant) new_metadata = add_size_index_to_metadata (self, metadata); + g_autoptr (GVariant) new_metadata + = add_auto_metadata (self, metadata, repo_root, cancellable, error); + if (new_metadata == NULL) + return FALSE; g_autoptr (GVariant) commit = g_variant_new ( "(@a{sv}@ay@a(say)sst@ay@ay)", new_metadata ? new_metadata : create_empty_gvariant_dict (), diff --git a/src/libostree/ostree-repo-composefs.c b/src/libostree/ostree-repo-composefs.c index 3df1cf98..f33f5d30 100644 --- a/src/libostree/ostree-repo-composefs.c +++ b/src/libostree/ostree-repo-composefs.c @@ -558,3 +558,74 @@ ostree_repo_checkout_composefs (OstreeRepo *self, OstreeComposefsTarget *target, return FALSE; #endif } + +#ifdef HAVE_COMPOSEFS +static gboolean +ostree_repo_commit_add_composefs_sig (OstreeRepo *self, GVariantBuilder *builder, + guchar *fsverity_digest, GCancellable *cancellable, + GError **error) +{ + g_autofree char *certfile = NULL; + g_autofree char *keyfile = NULL; + g_autoptr (GBytes) sig = NULL; + + certfile + = g_key_file_get_string (self->config, _OSTREE_INTEGRITY_SECTION, "composefs-certfile", NULL); + keyfile + = g_key_file_get_string (self->config, _OSTREE_INTEGRITY_SECTION, "composefs-keyfile", NULL); + + if (certfile == NULL && keyfile == NULL) + return TRUE; + + if (certfile == NULL) + return glnx_throw (error, "Error signing compoosefs: keyfile specified but certfile is not"); + + if (keyfile == NULL) + return glnx_throw (error, "Error signing compoosefs: certfile specified but keyfile is not"); + + if (!_ostree_fsverity_sign (certfile, keyfile, fsverity_digest, &sig, cancellable, error)) + return FALSE; + + g_variant_builder_add (builder, "{sv}", "ostree.composefs-sig", ot_gvariant_new_ay_bytes (sig)); + + return TRUE; +} +#endif + +gboolean +ostree_repo_commit_add_composefs_metadata (OstreeRepo *self, GVariantBuilder *builder, + OstreeRepoFile *repo_root, GCancellable *cancellable, + GError **error) +{ + gboolean add_metadata; + + if (!ot_keyfile_get_boolean_with_default (self->config, _OSTREE_INTEGRITY_SECTION, + "composefs-add-metadata", FALSE, &add_metadata, error)) + return FALSE; + + if (add_metadata) + { +#ifdef HAVE_COMPOSEFS + /* Create a composefs image and put in deploy dir as .ostree.cfs */ + g_autoptr (OstreeComposefsTarget) target = ostree_composefs_target_new (); + + if (!ostree_repo_checkout_composefs (self, target, repo_root, cancellable, error)) + return FALSE; + + g_autofree guchar *fsverity_digest = NULL; + if (!ostree_composefs_target_write (target, -1, &fsverity_digest, cancellable, error)) + return FALSE; + + g_variant_builder_add (builder, "{sv}", "ostree.composefs", + ot_gvariant_new_bytearray (fsverity_digest, OSTREE_SHA256_DIGEST_LEN)); + + if (!ostree_repo_commit_add_composefs_sig (self, builder, fsverity_digest, cancellable, + error)) + return FALSE; +#else + return glnx_throw (error, "composefs required, but libostree compiled without support"); +#endif + } + + return TRUE; +} diff --git a/src/libostree/ostree-repo-private.h b/src/libostree/ostree-repo-private.h index 15121372..76f3152b 100644 --- a/src/libostree/ostree-repo-private.h +++ b/src/libostree/ostree-repo-private.h @@ -465,6 +465,10 @@ gboolean ostree_repo_checkout_composefs (OstreeRepo *self, OstreeComposefsTarget OstreeRepoFile *source, GCancellable *cancellable, GError **error); +gboolean ostree_repo_commit_add_composefs_metadata (OstreeRepo *self, GVariantBuilder *builder, + OstreeRepoFile *repo_root, + GCancellable *cancellable, GError **error); + G_DEFINE_AUTOPTR_CLEANUP_FUNC (OstreeComposefsTarget, ostree_composefs_target_unref) G_END_DECLS