@@ -305,11 +305,41 @@ load_variant (const char *root_mountpoint, const char *digest, const char *exten
305305 return TRUE;
306306}
307307
308+ /* For local bootc commit, return the base ostree commit that was used to generate the commit.
309+ */
310+ static char *
311+ get_base_digest_for_bootc_commit (GVariant * commit )
312+ {
313+ g_autoptr (GVariant ) metadata = g_variant_get_child_value (commit , 0 );
314+
315+ /* Check for ostree.container.image-config to determine if this is a bootc commit */
316+ const char * image_config = NULL ;
317+ if (!g_variant_lookup (metadata , "ostree.container.image-config" , "s" , & image_config ))
318+ return NULL ;
319+
320+ /* If so, since https://github.com/bootc-dev/bootc/pull/1600, the
321+ * parent commit will be the base ostree commit. */
322+
323+ g_autoptr (GVariant ) parent_commit_v = g_variant_get_child_value (commit , 1 );
324+ if (g_variant_n_children (parent_commit_v ) != OSTREE_SHA256_DIGEST_LEN )
325+ return NULL ;
326+
327+ const guint8 * parent_commit_bin = ot_variant_get_data (parent_commit_v , NULL );
328+ if (parent_commit_bin == NULL )
329+ return NULL ;
330+
331+ char * basecommit_digest = g_malloc (OSTREE_SHA256_STRING_LEN + 1 );
332+ ot_bin2hex (basecommit_digest , parent_commit_bin , OSTREE_SHA256_DIGEST_LEN );
333+
334+ return basecommit_digest ;
335+ }
336+
308337// Given a mount point, directly load the .commit object. At the current time this tool
309338// doesn't link to libostree.
310339static gboolean
311340load_commit_for_deploy (const char * root_mountpoint , const char * deploy_path , GVariant * * commit_out ,
312- GVariant * * commitmeta_out , GError * * error )
341+ GVariant * * commitmeta_out , GVariant * * basecommit_out ,
342+ GVariant * * basecommitmeta_out , GError * * error )
313343{
314344 g_autofree char * digest = g_path_get_basename (deploy_path );
315345 char * dot = strchr (digest , '.' );
@@ -318,6 +348,8 @@ load_commit_for_deploy (const char *root_mountpoint, const char *deploy_path, GV
318348
319349 g_autoptr (GVariant ) commit_v = NULL ;
320350 g_autoptr (GVariant ) commitmeta_v = NULL ;
351+ g_autoptr (GVariant ) basecommit_v = NULL ;
352+ g_autoptr (GVariant ) basecommitmeta_v = NULL ;
321353
322354 if (!load_variant (root_mountpoint , digest , "commit" , OSTREE_COMMIT_GVARIANT_FORMAT , FALSE,
323355 & commit_v , error ))
@@ -327,8 +359,28 @@ load_commit_for_deploy (const char *root_mountpoint, const char *deploy_path, GV
327359 & commitmeta_v , error ))
328360 return FALSE;
329361
362+ /* In case the commit is one created by bootc when importing a container, it will not
363+ * be signed. However, we can still look at the base commit which may be signed.
364+ */
365+ g_autofree char * basecommit_digest = get_base_digest_for_bootc_commit (commit_v );
366+ if (basecommit_digest )
367+ {
368+ if (!load_variant (root_mountpoint , basecommit_digest , "commit" ,
369+ OSTREE_COMMIT_GVARIANT_FORMAT , TRUE, & basecommit_v , error ))
370+ return FALSE;
371+
372+ if (basecommit_v != NULL )
373+ {
374+ if (!load_variant (root_mountpoint , basecommit_digest , "commitmeta" ,
375+ G_VARIANT_TYPE ("a{sv}" ), TRUE, & basecommitmeta_v , error ))
376+ return FALSE;
377+ }
378+ }
379+
330380 * commit_out = g_steal_pointer (& commit_v );
331381 * commitmeta_out = g_steal_pointer (& commitmeta_v );
382+ * basecommit_out = g_steal_pointer (& basecommit_v );
383+ * basecommitmeta_out = g_steal_pointer (& basecommitmeta_v );
332384
333385 return TRUE;
334386}
@@ -556,14 +608,30 @@ otcore_mount_rootfs (RootConfig *rootfs_config, GVariantBuilder *metadata_builde
556608 if (rootfs_config -> is_signed )
557609 {
558610 const char * composefs_pubkey = rootfs_config -> signature_pubkey ;
559- g_autoptr (GVariant ) commit = NULL ;
560- g_autoptr (GVariant ) commitmeta = NULL ;
561-
562- if (!load_commit_for_deploy (root_mountpoint , deploy_path , & commit , & commitmeta ,
563- error ))
611+ g_autoptr (GVariant ) main_commit = NULL ;
612+ g_autoptr (GVariant ) main_commitmeta = NULL ;
613+ g_autoptr (GVariant ) base_commit = NULL ;
614+ g_autoptr (GVariant ) base_commitmeta = NULL ;
615+ GVariant * commit = NULL ;
616+ GVariant * commitmeta = NULL ;
617+
618+ if (!load_commit_for_deploy (root_mountpoint , deploy_path , & main_commit , & main_commitmeta ,
619+ & base_commit , & base_commitmeta , error ))
564620 return glnx_prefix_error (error , "Error loading signatures from repo" );
565621
566- if (commitmeta == NULL )
622+ if (main_commitmeta != NULL )
623+ {
624+ commit = main_commit ;
625+ commitmeta = main_commitmeta ;
626+ }
627+ else if (base_commitmeta != NULL )
628+ {
629+ ot_journal_print (LOG_INFO ,
630+ "composefs+ostree: Validating composefs using bootc base commit" );
631+ commit = base_commit ;
632+ commitmeta = base_commitmeta ;
633+ }
634+ else
567635 return glnx_throw (error , "No commitmeta for deploy %s" , deploy_path );
568636
569637 g_autoptr (GVariant ) signatures = g_variant_lookup_value (
0 commit comments