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.
This commit is contained in:
Dan Nicholson authored and Dan Nicholson committed 2021-07-15 15:50:04 -06:00
1 parent fc073654dc
commit a50f6d0b9f
7 files changed
+266 -3

No files matched your search

+85
View File
@@ -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,