summaryrefslogtreecommitdiff
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
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.
-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