bin/static-delta: Add signature parameters to apply-offline
authorFrédéric Danis <frederic.danis@collabora.com>
Fri, 21 Aug 2020 15:22:40 +0000 (17:22 +0200)
committerFrédéric Danis <frederic.danis@collabora.com>
Mon, 14 Sep 2020 07:27:19 +0000 (09:27 +0200)
This allows to check the delta signature before applying it.

Signed-off-by: Frédéric Danis <frederic.danis@collabora.com>
bash/ostree
man/ostree-static-delta.xml
src/ostree/ot-builtin-static-delta.c

index 34a38b2035de18e4388f0e697f24d0219172adbe..d00695efc663e71f9d8ee83f8516afe4e316e5d5 100644 (file)
@@ -1532,6 +1532,9 @@ _ostree_static_delta_apply_offline() {
     "
 
     local options_with_args="
+        --sign-type
+        --keys-file
+        --keys-dir
         --repo
     "
 
index 66fc7590267f15630a260016dade26c5cb253852..440ada41e839775dd5cac6bf5561c51f4cda1405 100644 (file)
@@ -63,7 +63,7 @@ Boston, MA 02111-1307, USA.
                 <command>ostree static-delta generate</command> <arg choice="req">--to=REV</arg> <arg choice="opt" rep="repeat">OPTIONS</arg>
             </cmdsynopsis>
             <cmdsynopsis>
-                <command>ostree static-delta apply-offline</command> <arg choice="req">PATH</arg>
+                <command>ostree static-delta apply-offline</command> <arg choice="opt" rep="repeat">OPTIONS</arg> <arg choice="req">PATH</arg> <arg choice="opt" rep="repeat">KEY-ID</arg>
             </cmdsynopsis>
             <cmdsynopsis>
                 <command>ostree static-delta verify</command> <arg choice="opt" rep="repeat">OPTIONS</arg> <arg choice="req">STATIC-DELTA</arg> <arg choice="opt" rep="repeat">KEY-ID</arg>
@@ -152,6 +152,65 @@ Boston, MA 02111-1307, USA.
         </variablelist>
     </refsect1>
 
+        <refsect1>
+            <title>'Apply-offline' Options</title>
+
+            <variablelist>
+                <varlistentry>
+                    <term><option>KEY-ID</option></term>
+
+                    <listitem><para>
+                        <variablelist>
+                            <varlistentry>
+                                <term><option>for ed25519:</option></term>
+                                <listitem><para>
+                                        <literal>base64</literal>-encoded public key for verifying.
+                                </para></listitem>
+                            </varlistentry>
+
+                            <varlistentry>
+                                <term><option>for dummy:</option></term>
+                                <listitem><para>
+                                            ASCII-string used as public key.
+                                </para></listitem>
+                            </varlistentry>
+                        </variablelist>
+                    </para></listitem>
+                </varlistentry>
+
+                <varlistentry>
+                    <term><option>--sign-type</option>=ENGINE</term>
+
+                    <listitem><para>
+                        Use particular signature engine. Currently
+                        available <arg choice="plain">ed25519</arg> and <arg choice="plain">dummy</arg>
+                        signature types.
+                    </para></listitem>
+                </varlistentry>
+
+                <varlistentry>
+                     <term><option>--keys-file</option></term>
+                     <listitem><para>
+                         Read key(s) from file <filename>filename</filename>.
+                     </para></listitem>
+
+                     <listitem><para>
+                         Valid for <literal>ed25519</literal> signature type.
+                         For <literal>ed25519</literal> this file must contain <literal>base64</literal>-encoded
+                         public key(s) per line for verifying.
+                     </para></listitem>
+                 </varlistentry>
+
+                 <varlistentry>
+                     <term><option>--keys-dir</option></term>
+                     <listitem><para>
+                         Redefine the system path, where to search files and subdirectories with
+                         well-known and revoked keys.
+                     </para></listitem>
+                 </varlistentry>
+            </variablelist>
+        </refsect1>
+
     <refsect1>
         <title>'Verify' Options</title>
 
index 4e507e7d41a9453e7768d96ee8a9cd9546644a78..3e0af5bd96220c590d83a9172b2cefdc71d41102 100644 (file)
@@ -105,6 +105,11 @@ static GOptionEntry generate_options[] = {
 };
 
 static GOptionEntry apply_offline_options[] = {
+  { "sign-type", 0, 0, G_OPTION_ARG_STRING, &opt_sign_name, "Signature type to use (defaults to 'ed25519')", "NAME"},
+#if defined(HAVE_LIBSODIUM)
+  { "keys-file", 0, 0, G_OPTION_ARG_STRING, &opt_keysfilename, "Read key(s) from file", "NAME"},
+  { "keys-dir", 0, 0, G_OPTION_ARG_STRING, &opt_keysdir, "Redefine system-wide directories with public and revoked keys for verification", "NAME"},
+#endif
   { NULL }
 };
 
@@ -423,6 +428,9 @@ ot_static_delta_builtin_apply_offline (int argc, char **argv, OstreeCommandInvoc
 {
   g_autoptr(GOptionContext) context = NULL;
   g_autoptr(OstreeRepo) repo = NULL;
+  g_autoptr (OstreeSign) sign = NULL;
+  char **key_ids;
+  int n_key_ids;
 
   context = g_option_context_new ("");
   if (!ostree_option_context_parse (context, apply_offline_options, &argc, &argv, invocation, &repo, cancellable, error))
@@ -438,13 +446,59 @@ ot_static_delta_builtin_apply_offline (int argc, char **argv, OstreeCommandInvoc
       return FALSE;
     }
 
+#if defined(HAVE_LIBSODIUM)
+  /* Initialize crypto system */
+  opt_sign_name = opt_sign_name ?: OSTREE_SIGN_NAME_ED25519;
+#endif
+
+  if (opt_sign_name)
+    {
+      sign = ostree_sign_get_by_name (opt_sign_name, error);
+      if (!sign)
+        return glnx_throw (error, "Signing type %s is not supported", opt_sign_name);
+
+      key_ids = argv + 3;
+      n_key_ids = argc - 3;
+      for (int i = 0; i < n_key_ids; i++)
+        {
+          g_autoptr (GVariant) pk = g_variant_new_string(key_ids[i]);
+          if (!ostree_sign_add_pk(sign, pk, error))
+            return FALSE;
+        }
+      if ((n_key_ids == 0) || opt_keysfilename)
+        {
+          g_autoptr (GVariantBuilder) builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
+          g_autoptr (GVariant) options = NULL;
+
+          /* Use custom directory with public and revoked keys instead of system-wide directories */
+          if (opt_keysdir)
+            g_variant_builder_add (builder, "{sv}", "basedir", g_variant_new_string (opt_keysdir));
+          /* The last chance for verification source -- system files */
+          if (opt_keysfilename)
+            g_variant_builder_add (builder, "{sv}", "filename", g_variant_new_string (opt_keysfilename));
+          options = g_variant_builder_end (builder);
+
+          if (!ostree_sign_load_pk (sign, options, error))
+            {
+              /* If it fails to load system default public keys, consider there no signature engine */
+              if (!opt_keysdir && !opt_keysfilename)
+                {
+                  g_clear_error(error);
+                  g_clear_object(&sign);
+                }
+              else
+                return FALSE;
+            }
+        }
+    }
+
   const char *patharg = argv[2];
   g_autoptr(GFile) path = g_file_new_for_path (patharg);
 
   if (!ostree_repo_prepare_transaction (repo, NULL, cancellable, error))
     return FALSE;
 
-  if (!ostree_repo_static_delta_execute_offline (repo, path, FALSE, cancellable, error))
+  if (!ostree_repo_static_delta_execute_offline_with_signature (repo, path, sign, FALSE, cancellable, error))
     return FALSE;
 
   if (!ostree_repo_commit_transaction (repo, NULL, cancellable, error))