summaryrefslogtreecommitdiff
path: root/src/libostree/ostree-gpg-verifier.c
diff options
context:
space:
mode:
authorDan Nicholson <nicholson@endlessm.com>2019-08-13 13:36:00 -0600
committerDan Nicholson <dbn@endlessos.org>2021-07-15 15:50:04 -0600
commita50f6d0b9fa1d3079ff5bf78e46da3a635a37611 (patch)
tree92cca77c85d04c36532c37d853b3de886a977092 /src/libostree/ostree-gpg-verifier.c
parentfc073654dca64dacdc0067bd35ecb82f8c794fe3 (diff)
downloadostree-a50f6d0b9fa1d3079ff5bf78e46da3a635a37611.tar.gz
lib/repo: Add ostree_repo_remote_get_gpg_keys()
This function enumerates the trusted GPG keys for a remote and returns an array of `GVariant`s describing them. This is useful to see which keys are collected by ostree for a particular remote. The same information can be gathered with `gpg`. However, since ostree allows multiple keyring locations, that's only really useful if you have knowledge of how ostree collects GPG keyrings. The format of the variants is documented in `OSTREE_GPG_KEY_GVARIANT_FORMAT`. This format is primarily a copy of selected fields within `gpgme_key_t` and its subtypes. The fields are placed within vardicts rather than using a more efficient tuple of concrete types. This will allow flexibility if more components of `gpgme_key_t` are desired in the future.
Diffstat (limited to 'src/libostree/ostree-gpg-verifier.c')
-rw-r--r--src/libostree/ostree-gpg-verifier.c85
1 files changed, 85 insertions, 0 deletions
diff --git a/src/libostree/ostree-gpg-verifier.c b/src/libostree/ostree-gpg-verifier.c
index 88850d46..e9f5c5e3 100644
--- a/src/libostree/ostree-gpg-verifier.c
+++ b/src/libostree/ostree-gpg-verifier.c
@@ -185,6 +185,91 @@ _ostree_gpg_verifier_import_keys (OstreeGpgVerifier *self,
return ret;
}
+gboolean
+_ostree_gpg_verifier_list_keys (OstreeGpgVerifier *self,
+ const char * const *key_ids,
+ GPtrArray **out_keys,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GLNX_AUTO_PREFIX_ERROR("GPG", error);
+ g_auto(gpgme_ctx_t) context = NULL;
+ g_autoptr(GOutputStream) pubring_stream = NULL;
+ g_autofree char *tmp_dir = NULL;
+ g_autoptr(GPtrArray) keys = NULL;
+ gpgme_error_t gpg_error = 0;
+ gboolean ret = FALSE;
+
+ if (g_cancellable_set_error_if_cancelled (cancellable, error))
+ goto out;
+
+ context = ot_gpgme_new_ctx (NULL, error);
+ if (context == NULL)
+ goto out;
+
+ if (!ot_gpgme_ctx_tmp_home_dir (context, &tmp_dir, &pubring_stream,
+ cancellable, error))
+ goto out;
+
+ if (!_ostree_gpg_verifier_import_keys (self, context, pubring_stream,
+ cancellable, error))
+ goto out;
+
+ keys = g_ptr_array_new_with_free_func ((GDestroyNotify) gpgme_key_unref);
+ if (key_ids != NULL)
+ {
+ for (guint i = 0; key_ids[i] != NULL; i++)
+ {
+ gpgme_key_t key = NULL;
+
+ gpg_error = gpgme_get_key (context, key_ids[i], &key, 0);
+ if (gpg_error != GPG_ERR_NO_ERROR)
+ {
+ ot_gpgme_throw (gpg_error, error, "Unable to find key \"%s\"",
+ key_ids[i]);
+ goto out;
+ }
+
+ /* Transfer ownership. */
+ g_ptr_array_add (keys, key);
+ }
+ }
+ else
+ {
+ gpg_error = gpgme_op_keylist_start (context, NULL, 0);
+ while (gpg_error == GPG_ERR_NO_ERROR)
+ {
+ gpgme_key_t key = NULL;
+
+ gpg_error = gpgme_op_keylist_next (context, &key);
+ if (gpg_error != GPG_ERR_NO_ERROR)
+ break;
+
+ /* Transfer ownership. */
+ g_ptr_array_add (keys, key);
+ }
+
+ if (gpgme_err_code (gpg_error) != GPG_ERR_EOF)
+ {
+ ot_gpgme_throw (gpg_error, error, "Unable to list keys");
+ goto out;
+ }
+ }
+
+ if (out_keys != NULL)
+ *out_keys = g_steal_pointer (&keys);
+
+ ret = TRUE;
+
+ out:
+ if (tmp_dir != NULL) {
+ ot_gpgme_kill_agent (tmp_dir);
+ (void) glnx_shutil_rm_rf_at (AT_FDCWD, tmp_dir, NULL, NULL);
+ }
+
+ return ret;
+}
+
OstreeGpgVerifyResult *
_ostree_gpg_verifier_check_signature (OstreeGpgVerifier *self,
GBytes *signed_data,