mirror of
https://github.com/ostreedev/ostree.git
synced 2025-01-07 21:18:55 +03:00
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.
This commit is contained in:
parent
70cabcea0a
commit
c2b01adbf0
@ -244,7 +244,7 @@ out:
|
|||||||
gboolean
|
gboolean
|
||||||
_ostree_gpg_verifier_check_signature (OstreeGpgVerifier *self,
|
_ostree_gpg_verifier_check_signature (OstreeGpgVerifier *self,
|
||||||
GFile *file,
|
GFile *file,
|
||||||
GFile *signature,
|
GBytes *signatures,
|
||||||
gboolean *out_had_valid_sig,
|
gboolean *out_had_valid_sig,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error)
|
GError **error)
|
||||||
@ -306,17 +306,16 @@ _ostree_gpg_verifier_check_signature (OstreeGpgVerifier *self,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
gpg_error = gpgme_data_new_from_mem (&signature_buffer,
|
||||||
gs_free char *path = g_file_get_path (signature);
|
g_bytes_get_data (signatures, NULL),
|
||||||
gpg_error = gpgme_data_new_from_file (&signature_buffer, path, 1);
|
g_bytes_get_size (signatures),
|
||||||
|
0 /* do not copy */);
|
||||||
if (gpg_error != GPG_ERR_NO_ERROR)
|
if (gpg_error != GPG_ERR_NO_ERROR)
|
||||||
{
|
{
|
||||||
gpg_error_to_gio_error (gpg_error, error);
|
gpg_error_to_gio_error (gpg_error, error);
|
||||||
g_prefix_error (error, "Unable to read signature: ");
|
g_prefix_error (error, "Unable to read signature: ");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
gpg_error = gpgme_op_verify (gpg_ctx, signature_buffer, data_buffer, NULL);
|
gpg_error = gpgme_op_verify (gpg_ctx, signature_buffer, data_buffer, NULL);
|
||||||
if (gpg_error != GPG_ERR_NO_ERROR)
|
if (gpg_error != GPG_ERR_NO_ERROR)
|
||||||
|
@ -43,7 +43,7 @@ OstreeGpgVerifier *_ostree_gpg_verifier_new (GCancellable *cancellable,
|
|||||||
|
|
||||||
gboolean _ostree_gpg_verifier_check_signature (OstreeGpgVerifier *self,
|
gboolean _ostree_gpg_verifier_check_signature (OstreeGpgVerifier *self,
|
||||||
GFile *file,
|
GFile *file,
|
||||||
GFile *signature,
|
GBytes *signatures,
|
||||||
gboolean *had_valid_signature,
|
gboolean *had_valid_signature,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
@ -3208,7 +3208,10 @@ _ostree_repo_gpg_verify_file_with_metadata (OstreeRepo *self,
|
|||||||
gboolean ret = FALSE;
|
gboolean ret = FALSE;
|
||||||
gs_unref_object OstreeGpgVerifier *verifier = NULL;
|
gs_unref_object OstreeGpgVerifier *verifier = NULL;
|
||||||
gs_unref_variant GVariant *signaturedata = 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;
|
gboolean had_valid_signataure = FALSE;
|
||||||
|
|
||||||
verifier = _ostree_gpg_verifier_new (cancellable, error);
|
verifier = _ostree_gpg_verifier_new (cancellable, error);
|
||||||
@ -3239,38 +3242,32 @@ _ostree_repo_gpg_verify_file_with_metadata (OstreeRepo *self,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
n = g_variant_n_children (signaturedata);
|
/* OpenPGP data is organized into binary records called packets. RFC 4880
|
||||||
for (i = 0; i < n; i++)
|
* 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)
|
||||||
{
|
{
|
||||||
GVariant *signature_variant = g_variant_get_child_value (signaturedata, i);
|
g_byte_array_append (buffer,
|
||||||
gs_unref_object GFile *temp_sig_path = NULL;
|
g_variant_get_data (child),
|
||||||
|
g_variant_get_size (child));
|
||||||
if (!gs_file_open_in_tmpdir (self->tmp_dir, 0644,
|
g_variant_unref (child);
|
||||||
&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;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
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 (!had_valid_signataure)
|
if (!had_valid_signataure)
|
||||||
{
|
{
|
||||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||||
|
Loading…
Reference in New Issue
Block a user