diff options
author | Dan Nicholson <nicholson@endlessm.com> | 2019-07-26 09:38:23 -0600 |
---|---|---|
committer | Dan Nicholson <dbn@endlessos.org> | 2021-07-15 15:50:04 -0600 |
commit | dba2cdcbac5c064574f44a56714324e71ed9500b (patch) | |
tree | d113de6339490c29ce8c7b492123ca0d43f80a83 | |
parent | f216a3c170b8cd636241e9a86f0b87fb183859e7 (diff) | |
download | ostree-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.c | 109 |
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 |