[ostree] OstreeGpgVerifier: Take the signature as a GBytes



commit c2b01adbf0335e9b13982ecfe1d0590d9e2855a9
Author: Matthew Barnes <mbarnes redhat com>
Date:   Tue Mar 3 14:15:27 2015 -0500

    OstreeGpgVerifier: Take the signature as a GBytes
    
    The signature data is in memory to begin with, so there's no need to
    write it to disk only to immediately read it back.
    
    Also, because the GPGME multi-keyring workaround is somewhat expensive
    to setup and teardown, concatenate all signatures into a single GBytes
    so _ostree_gpg_verifier_check_signature() is only called once.  We're
    currently only looking for one valid signature anyway.

 src/libostree/ostree-gpg-verifier.c |   23 ++++++-------
 src/libostree/ostree-gpg-verifier.h |    2 +-
 src/libostree/ostree-repo.c         |   61 ++++++++++++++++------------------
 3 files changed, 41 insertions(+), 45 deletions(-)
---
diff --git a/src/libostree/ostree-gpg-verifier.c b/src/libostree/ostree-gpg-verifier.c
index c5bd911..da36011 100644
--- a/src/libostree/ostree-gpg-verifier.c
+++ b/src/libostree/ostree-gpg-verifier.c
@@ -244,7 +244,7 @@ out:
 gboolean
 _ostree_gpg_verifier_check_signature (OstreeGpgVerifier  *self,
                                       GFile              *file,
-                                      GFile              *signature,
+                                      GBytes             *signatures,
                                       gboolean           *out_had_valid_sig,
                                       GCancellable       *cancellable,
                                       GError            **error)
@@ -306,17 +306,16 @@ _ostree_gpg_verifier_check_signature (OstreeGpgVerifier  *self,
       }
   }
 
-  {
-    gs_free char *path = g_file_get_path (signature);
-    gpg_error = gpgme_data_new_from_file (&signature_buffer, path, 1);
-
-    if (gpg_error != GPG_ERR_NO_ERROR)
-      {
-        gpg_error_to_gio_error (gpg_error, error);
-        g_prefix_error (error, "Unable to read signature: ");
-        goto out;
-      }
-  }
+  gpg_error = gpgme_data_new_from_mem (&signature_buffer,
+                                       g_bytes_get_data (signatures, NULL),
+                                       g_bytes_get_size (signatures),
+                                       0 /* do not copy */);
+  if (gpg_error != GPG_ERR_NO_ERROR)
+    {
+      gpg_error_to_gio_error (gpg_error, error);
+      g_prefix_error (error, "Unable to read signature: ");
+      goto out;
+    }
 
   gpg_error = gpgme_op_verify (gpg_ctx, signature_buffer, data_buffer, NULL);
   if (gpg_error != GPG_ERR_NO_ERROR)
diff --git a/src/libostree/ostree-gpg-verifier.h b/src/libostree/ostree-gpg-verifier.h
index fa718ee..d3a9994 100644
--- a/src/libostree/ostree-gpg-verifier.h
+++ b/src/libostree/ostree-gpg-verifier.h
@@ -43,7 +43,7 @@ OstreeGpgVerifier *_ostree_gpg_verifier_new (GCancellable   *cancellable,
 
 gboolean      _ostree_gpg_verifier_check_signature (OstreeGpgVerifier *self,
                                                     GFile             *file,
-                                                    GFile             *signature,
+                                                    GBytes            *signatures,
                                                     gboolean          *had_valid_signature,
                                                     GCancellable      *cancellable,
                                                     GError           **error);
diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c
index 558d008..b114b02 100644
--- a/src/libostree/ostree-repo.c
+++ b/src/libostree/ostree-repo.c
@@ -3208,7 +3208,10 @@ _ostree_repo_gpg_verify_file_with_metadata (OstreeRepo          *self,
   gboolean ret = FALSE;
   gs_unref_object OstreeGpgVerifier *verifier = NULL;
   gs_unref_variant GVariant *signaturedata = NULL;
-  gint i, n;
+  GByteArray *buffer;
+  GVariantIter iter;
+  GVariant *child;
+  g_autoptr (GBytes) signatures = NULL;
   gboolean had_valid_signataure = FALSE;
 
   verifier = _ostree_gpg_verifier_new (cancellable, error);
@@ -3239,38 +3242,32 @@ _ostree_repo_gpg_verify_file_with_metadata (OstreeRepo          *self,
       goto out;
     }
 
-  n = g_variant_n_children (signaturedata);
-  for (i = 0; i < n; i++)
-    {
-      GVariant *signature_variant = g_variant_get_child_value (signaturedata, i);
-      gs_unref_object GFile *temp_sig_path = NULL;
-
-      if (!gs_file_open_in_tmpdir (self->tmp_dir, 0644,
-                                   &temp_sig_path, NULL,
-                                   cancellable, error))
-        goto out;
-
-      if (!g_file_replace_contents (temp_sig_path,
-                                    (char*)g_variant_get_data (signature_variant),
-                                    g_variant_get_size (signature_variant),
-                                    NULL, FALSE, 0, NULL,
-                                    cancellable, error))
-        goto out;
+  /* OpenPGP data is organized into binary records called packets.  RFC 4880
+   * defines a packet as a chunk of data that has a tag specifying its meaning,
+   * and consists of a packet header followed by a packet body.  Each packet
+   * encodes its own length, and so packets can be concatenated to construct
+   * OpenPGP messages, keyrings, or in this case, detached signatures.
+   *
+   * Each binary blob in the GVariant list is a complete signature packet, so
+   * we can concatenate them together to verify all the signatures at once. */
+  buffer = g_byte_array_new ();
+  g_variant_iter_init (&iter, signaturedata);
+  while ((child = g_variant_iter_next_value (&iter)) != NULL)
+    {
+      g_byte_array_append (buffer,
+                           g_variant_get_data (child),
+                           g_variant_get_size (child));
+      g_variant_unref (child);
+    }
+  signatures = g_byte_array_free_to_bytes (buffer);
+
+  if (!_ostree_gpg_verifier_check_signature (verifier,
+                                             path,
+                                             signatures,
+                                             &had_valid_signataure,
+                                             cancellable, error))
+    goto out;
 
-      if (!_ostree_gpg_verifier_check_signature (verifier,
-                                                 path,
-                                                 temp_sig_path,
-                                                 &had_valid_signataure,
-                                                 cancellable, error))
-        {
-          (void) gs_file_unlink (temp_sig_path, NULL, NULL);
-          goto out;
-        }
-      (void) gs_file_unlink (temp_sig_path, NULL, NULL);
-      if (had_valid_signataure)
-        break;
-    }
-  
   if (!had_valid_signataure)
     {
       g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]