bin/static-delta: Add support to sign superblock
authorFrédéric Danis <frederic.danis@collabora.com>
Tue, 26 Nov 2019 10:20:10 +0000 (11:20 +0100)
committerFrédéric Danis <frederic.danis@collabora.com>
Mon, 14 Sep 2020 07:27:19 +0000 (09:27 +0200)
Add signing ability to "static-delta generate" builtin.

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 7256e40a4d768a8e95008d9f64307d375dcea2d5..a7389bd7ddca580668a72a474a28aa65b947558b 100644 (file)
@@ -1613,6 +1613,8 @@ _ostree_static_delta_generate() {
         --repo
         --set-endianness
         --to
+        --sign
+        --sign-type
     "
 
     local options_with_args_glob=$( __ostree_to_extglob "$options_with_args" )
@@ -1630,6 +1632,9 @@ _ostree_static_delta_generate() {
             COMPREPLY=( $( compgen -W "l B" -- "$cur" ) )
             return 0
             ;;
+        $options_with_args_glob )
+            return 0
+            ;;
     esac
 
     case "$cur" in
index dfeef28bc53db9a968df469fcb4a0c97f2ef1030..a4bef237a0f5d986fea8334d9ddf23a367618734 100644 (file)
@@ -113,6 +113,39 @@ Boston, MA 02111-1307, USA.
                 </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.
+
+                    The default is <arg choice="plain">ed25519</arg>.
+                </para></listitem>
+            </varlistentry>
+
+            <varlistentry>
+                <term><option>--sign</option>="KEY-ID"</term>
+                <listitem><para>
+                        There <literal>KEY-ID</literal> is:
+                        <variablelist>
+                            <varlistentry>
+                                <term><option>for ed25519:</option></term>
+                                <listitem><para>
+                                        <literal>base64</literal>-encoded secret key for signing.
+                                </para></listitem>
+                            </varlistentry>
+
+                            <varlistentry>
+                                <term><option>for dummy:</option></term>
+                                <listitem><para>
+                                            ASCII-string used as secret key.
+                                </para></listitem>
+                            </varlistentry>
+                        </variablelist>
+                </para></listitem>
+            </varlistentry>
         </variablelist>
     </refsect1>
 
index 4f9ff2b238922a76704bfc181177a7f3f574810d..d5e937834fcabc2a94d63286874ade72ea09b734 100644 (file)
@@ -40,6 +40,9 @@ static gboolean opt_swap_endianness;
 static gboolean opt_inline;
 static gboolean opt_disable_bsdiff;
 static gboolean opt_if_not_exists;
+static char **opt_key_ids;
+static char *opt_sign_name;
+static char *opt_keysfilename;
 
 #define BUILTINPROTO(name) static gboolean ot_static_delta_builtin_ ## name (int argc, char **argv, OstreeCommandInvocation *invocation, GCancellable *cancellable, GError **error)
 
@@ -88,6 +91,11 @@ static GOptionEntry generate_options[] = {
   { "max-bsdiff-size", 0, 0, G_OPTION_ARG_STRING, &opt_max_bsdiff_size, "Maximum size in megabytes to consider bsdiff compression for input files", NULL},
   { "max-chunk-size", 0, 0, G_OPTION_ARG_STRING, &opt_max_chunk_size, "Maximum size of delta chunks in megabytes", NULL},
   { "filename", 0, 0, G_OPTION_ARG_FILENAME, &opt_filename, "Write the delta content to PATH (a directory).  If not specified, the OSTree repository is used", "PATH"},
+  { "sign", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_key_ids, "Sign the delta with", "KEY_ID"},
+  { "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"},
+#endif
   { NULL }
 };
 
@@ -326,6 +334,60 @@ ot_static_delta_builtin_generate (int argc, char **argv, OstreeCommandInvocation
       if (opt_endianness || opt_swap_endianness)
         g_variant_builder_add (parambuilder, "{sv}", "endianness", g_variant_new_uint32 (endianness));
 
+      if (opt_key_ids || opt_keysfilename)
+        {
+          g_autoptr(GPtrArray) key_ids = g_ptr_array_new ();
+
+          for (char **iter = opt_key_ids; iter != NULL && *iter != NULL; ++iter)
+            g_ptr_array_add (key_ids, *iter);
+
+          if (opt_keysfilename)
+            {
+              g_autoptr (GFile) keyfile = NULL;
+              g_autoptr (GFileInputStream) key_stream_in = NULL;
+              g_autoptr (GDataInputStream) key_data_in = NULL;
+
+              if (!g_file_test (opt_keysfilename, G_FILE_TEST_IS_REGULAR))
+                {
+                  g_warning ("Can't open file '%s' with keys", opt_keysfilename);
+                  return glnx_throw (error, "File object '%s' is not a regular file", opt_keysfilename);
+                }
+
+              keyfile = g_file_new_for_path (opt_keysfilename);
+              key_stream_in = g_file_read (keyfile, NULL, error);
+              if (key_stream_in == NULL)
+                return FALSE;
+
+              key_data_in = g_data_input_stream_new (G_INPUT_STREAM(key_stream_in));
+              g_assert (key_data_in != NULL);
+
+              /* Use simple file format with just a list of base64 public keys per line */
+              while (TRUE)
+                {
+                  gsize len = 0;
+                  g_autofree char *line = g_data_input_stream_read_line (key_data_in, &len, NULL, error);
+                  g_autoptr (GVariant) sk = NULL;
+
+                  if (*error != NULL)
+                    return FALSE;
+
+                  if (line == NULL)
+                    break;
+
+                  // Pass the key as a string
+                  g_ptr_array_add (key_ids, g_strdup (line));
+                }
+            }
+
+          g_autoptr(GVariant) key_ids_v = g_variant_new_strv ((const char *const *)key_ids->pdata,
+                                                              key_ids->len);
+          g_variant_builder_add (parambuilder, "{s@v}", "sign-key-ids",
+                                 g_variant_new_variant (g_steal_pointer (&key_ids_v)));
+        }
+      opt_sign_name = opt_sign_name ?: OSTREE_SIGN_NAME_ED25519;
+      g_variant_builder_add (parambuilder, "{sv}", "sign-name",
+                             g_variant_new_bytestring (opt_sign_name));
+
       g_print ("Generating static delta:\n");
       g_print ("  From: %s\n", from_resolved ? from_resolved : "empty");
       g_print ("  To:   %s\n", to_resolved);