diff options
author | Dan Nicholson <nicholson@endlessm.com> | 2019-08-13 13:36:00 -0600 |
---|---|---|
committer | Dan Nicholson <dbn@endlessos.org> | 2021-07-15 15:50:04 -0600 |
commit | a50f6d0b9fa1d3079ff5bf78e46da3a635a37611 (patch) | |
tree | 92cca77c85d04c36532c37d853b3de886a977092 /src/libostree/ostree-gpg-verifier.c | |
parent | fc073654dca64dacdc0067bd35ecb82f8c794fe3 (diff) | |
download | ostree-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.c | 85 |
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, |