mirror of
https://github.com/ostreedev/ostree.git
synced 2025-01-26 14:04:12 +03:00
libotutil: Add helper for GPG WKD update URLs
Calculate the advanced and direct update URLs for the key discovery portion[1] of the OpenPGP Web Key Directory specification, and include the URLs in the key listing in ostree_repo_remote_get_gpg_keys(). These URLs can be used to locate updated GPG keys for the remote. 1. https://datatracker.ietf.org/doc/html/draft-koch-openpgp-webkey-service#section-3.1
This commit is contained in:
parent
fbff05e28d
commit
4fa403aee5
@ -27,6 +27,7 @@
|
||||
|
||||
#include <gio/gunixoutputstream.h>
|
||||
#include "libglnx.h"
|
||||
#include "zbase32.h"
|
||||
|
||||
/* Like glnx_throw_errno_prefix, but takes @gpg_error */
|
||||
gboolean
|
||||
@ -538,3 +539,77 @@ ot_gpgme_kill_agent (const char *homedir)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Takes the SHA1 checksum of the local component of an email address and
|
||||
* returns the zbase32 encoding.
|
||||
*/
|
||||
static char *
|
||||
encode_wkd_local (const char *local)
|
||||
{
|
||||
g_return_val_if_fail (local != NULL, NULL);
|
||||
|
||||
guint8 digest[20] = { 0 };
|
||||
gsize len = sizeof (digest);
|
||||
g_autoptr(GChecksum) checksum = g_checksum_new (G_CHECKSUM_SHA1);
|
||||
g_checksum_update (checksum, (const guchar *)local, -1);
|
||||
g_checksum_get_digest (checksum, digest, &len);
|
||||
|
||||
char *encoded = zbase32_encode (digest, len);
|
||||
|
||||
/* If the returned string is NULL, then there must have been a memory
|
||||
* allocation problem. Just exit immediately like g_malloc.
|
||||
*/
|
||||
if (encoded == NULL)
|
||||
g_error ("%s: %s", G_STRLOC, g_strerror (errno));
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
/* Implementation of OpenPGP Web Key Directory URLs as defined in
|
||||
* https://datatracker.ietf.org/doc/html/draft-koch-openpgp-webkey-service
|
||||
*/
|
||||
gboolean
|
||||
ot_gpg_wkd_urls (const char *email,
|
||||
char **out_advanced_url,
|
||||
char **out_direct_url,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (email != NULL, FALSE);
|
||||
|
||||
g_auto(GStrv) email_parts = g_strsplit (email, "@", -1);
|
||||
if (g_strv_length (email_parts) != 2)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
|
||||
"Invalid email address \"%s\"", email);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_autofree char *local_lowered = g_ascii_strdown (email_parts[0], -1);
|
||||
g_autofree char *domain_lowered = g_ascii_strdown (email_parts[1], -1);
|
||||
g_autofree char *local_encoded = encode_wkd_local (local_lowered);
|
||||
g_autofree char *local_escaped = g_uri_escape_string (email_parts[0], NULL, FALSE);
|
||||
|
||||
g_autofree char *advanced_url = g_strdup_printf ("https://openpgpkey.%s"
|
||||
"/.well-known/openpgpkey"
|
||||
"/%s/hu/%s?l=%s",
|
||||
email_parts[1],
|
||||
domain_lowered,
|
||||
local_encoded,
|
||||
local_escaped);
|
||||
g_debug ("GPG UID \"%s\" advanced WKD URL: %s", email, advanced_url);
|
||||
|
||||
g_autofree char *direct_url = g_strdup_printf ("https://%s"
|
||||
"/.well-known/openpgpkey"
|
||||
"/hu/%s?l=%s",
|
||||
email_parts[1],
|
||||
local_encoded,
|
||||
local_escaped);
|
||||
g_debug ("GPG UID \"%s\" direct WKD URL: %s", email, direct_url);
|
||||
|
||||
if (out_advanced_url != NULL)
|
||||
*out_advanced_url = g_steal_pointer (&advanced_url);
|
||||
if (out_direct_url != NULL)
|
||||
*out_direct_url = g_steal_pointer (&direct_url);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -48,4 +48,9 @@ gpgme_ctx_t ot_gpgme_new_ctx (const char *homedir,
|
||||
|
||||
void ot_gpgme_kill_agent (const char *homedir);
|
||||
|
||||
gboolean ot_gpg_wkd_urls (const char *email,
|
||||
char **out_advanced_url,
|
||||
char **out_direct_url,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
Loading…
x
Reference in New Issue
Block a user