summaryrefslogtreecommitdiff
path: root/src/libostree/ostree-gpg-verifier.c
diff options
context:
space:
mode:
authorDan Nicholson <nicholson@endlessm.com>2019-07-26 09:38:23 -0600
committerDan Nicholson <dbn@endlessos.org>2021-07-15 15:50:04 -0600
commitdba2cdcbac5c064574f44a56714324e71ed9500b (patch)
treed113de6339490c29ce8c7b492123ca0d43f80a83 /src/libostree/ostree-gpg-verifier.c
parentf216a3c170b8cd636241e9a86f0b87fb183859e7 (diff)
downloadostree-dba2cdcbac5c064574f44a56714324e71ed9500b.tar.gz
lib/repo: Factor out GPG verifier key imports
Currently the verifier only imports all the GPG keys when verifying data, but it would also be useful for inspecting the trusted keys.
Diffstat (limited to 'src/libostree/ostree-gpg-verifier.c')
-rw-r--r--src/libostree/ostree-gpg-verifier.c109
1 files changed, 64 insertions, 45 deletions
diff --git a/src/libostree/ostree-gpg-verifier.c b/src/libostree/ostree-gpg-verifier.c
index 95ed36ee..88850d46 100644
--- a/src/libostree/ostree-gpg-verifier.c
+++ b/src/libostree/ostree-gpg-verifier.c
@@ -91,43 +91,16 @@ verify_result_finalized_cb (gpointer data,
(void) glnx_shutil_rm_rf_at (AT_FDCWD, tmp_dir, NULL, NULL);
}
-OstreeGpgVerifyResult *
-_ostree_gpg_verifier_check_signature (OstreeGpgVerifier *self,
- GBytes *signed_data,
- GBytes *signatures,
- GCancellable *cancellable,
- GError **error)
+static gboolean
+_ostree_gpg_verifier_import_keys (OstreeGpgVerifier *self,
+ gpgme_ctx_t gpgme_ctx,
+ GOutputStream *pubring_stream,
+ GCancellable *cancellable,
+ GError **error)
{
GLNX_AUTO_PREFIX_ERROR("GPG", error);
- gpgme_error_t gpg_error = 0;
- g_auto(gpgme_data_t) data_buffer = NULL;
- g_auto(gpgme_data_t) signature_buffer = NULL;
- g_autofree char *tmp_dir = NULL;
- g_autoptr(GOutputStream) target_stream = NULL;
- OstreeGpgVerifyResult *result = NULL;
- gboolean success = FALSE;
- GList *link;
- int armor;
-
- /* GPGME has no API for using multiple keyrings (aka, gpg --keyring),
- * so we concatenate all the keyring files into one pubring.gpg in a
- * temporary directory, then tell GPGME to use that directory as the
- * home directory. */
-
- if (g_cancellable_set_error_if_cancelled (cancellable, error))
- goto out;
-
- result = g_initable_new (OSTREE_TYPE_GPG_VERIFY_RESULT,
- cancellable, error, NULL);
- if (result == NULL)
- goto out;
- if (!ot_gpgme_ctx_tmp_home_dir (result->context,
- &tmp_dir, &target_stream,
- cancellable, error))
- goto out;
-
- for (link = self->keyrings; link != NULL; link = link->next)
+ for (GList *link = self->keyrings; link != NULL; link = link->next)
{
g_autoptr(GFileInputStream) source_stream = NULL;
GFile *keyring_file = link->data;
@@ -145,15 +118,15 @@ _ostree_gpg_verifier_check_signature (OstreeGpgVerifier *self,
else if (local_error != NULL)
{
g_propagate_error (error, local_error);
- goto out;
+ return FALSE;
}
- bytes_written = g_output_stream_splice (target_stream,
+ bytes_written = g_output_stream_splice (pubring_stream,
G_INPUT_STREAM (source_stream),
G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE,
cancellable, error);
if (bytes_written < 0)
- goto out;
+ return FALSE;
}
for (guint i = 0; i < self->keyring_data->len; i++)
@@ -162,23 +135,25 @@ _ostree_gpg_verifier_check_signature (OstreeGpgVerifier *self,
gsize len;
gsize bytes_written;
const guint8 *buf = g_bytes_get_data (keyringd, &len);
- if (!g_output_stream_write_all (target_stream, buf, len, &bytes_written,
+ if (!g_output_stream_write_all (pubring_stream, buf, len, &bytes_written,
cancellable, error))
- goto out;
+ return FALSE;
}
- if (!g_output_stream_close (target_stream, cancellable, error))
- goto out;
+ if (!g_output_stream_close (pubring_stream, cancellable, error))
+ return FALSE;
/* Save the previous armor value - we need it on for importing ASCII keys */
- armor = gpgme_get_armor (result->context);
- gpgme_set_armor (result->context, 1);
+ gboolean ret = FALSE;
+ int armor = gpgme_get_armor (gpgme_ctx);
+ gpgme_set_armor (gpgme_ctx, 1);
/* Now, use the API to import ASCII-armored keys */
if (self->key_ascii_files)
{
for (guint i = 0; i < self->key_ascii_files->len; i++)
{
+ gpgme_error_t gpg_error;
const char *path = self->key_ascii_files->pdata[i];
glnx_autofd int fd = -1;
g_auto(gpgme_data_t) kdata = NULL;
@@ -193,7 +168,7 @@ _ostree_gpg_verifier_check_signature (OstreeGpgVerifier *self,
goto out;
}
- gpg_error = gpgme_op_import (result->context, kdata);
+ gpg_error = gpgme_op_import (gpgme_ctx, kdata);
if (gpg_error != GPG_ERR_NO_ERROR)
{
ot_gpgme_throw (gpg_error, error, "Failed to import key");
@@ -202,7 +177,51 @@ _ostree_gpg_verifier_check_signature (OstreeGpgVerifier *self,
}
}
- gpgme_set_armor (result->context, armor);
+ ret = TRUE;
+
+ out:
+ gpgme_set_armor (gpgme_ctx, armor);
+
+ return ret;
+}
+
+OstreeGpgVerifyResult *
+_ostree_gpg_verifier_check_signature (OstreeGpgVerifier *self,
+ GBytes *signed_data,
+ GBytes *signatures,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GLNX_AUTO_PREFIX_ERROR("GPG", error);
+ gpgme_error_t gpg_error = 0;
+ g_auto(gpgme_data_t) data_buffer = NULL;
+ g_auto(gpgme_data_t) signature_buffer = NULL;
+ g_autofree char *tmp_dir = NULL;
+ g_autoptr(GOutputStream) target_stream = NULL;
+ OstreeGpgVerifyResult *result = NULL;
+ gboolean success = FALSE;
+
+ /* GPGME has no API for using multiple keyrings (aka, gpg --keyring),
+ * so we concatenate all the keyring files into one pubring.gpg in a
+ * temporary directory, then tell GPGME to use that directory as the
+ * home directory. */
+
+ if (g_cancellable_set_error_if_cancelled (cancellable, error))
+ goto out;
+
+ result = g_initable_new (OSTREE_TYPE_GPG_VERIFY_RESULT,
+ cancellable, error, NULL);
+ if (result == NULL)
+ goto out;
+
+ if (!ot_gpgme_ctx_tmp_home_dir (result->context,
+ &tmp_dir, &target_stream,
+ cancellable, error))
+ goto out;
+
+ if (!_ostree_gpg_verifier_import_keys (self, result->context, target_stream,
+ cancellable, error))
+ goto out;
/* Both the signed data and signature GBytes instances will outlive the
* gpgme_data_t structs, so we can safely reuse the GBytes memory buffer