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 /src/libostree/ostree-gpg-verifier.c | |
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.
Diffstat (limited to 'src/libostree/ostree-gpg-verifier.c')
-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 |