From 7bf8530e75d05a712d00a333d59b0a8cf663b9cb Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 18 May 2021 22:44:14 +0200 Subject: [PATCH] gpg: Fix sending an OpenPGP key with umlaut to an LDAP keyserver. * g10/call-dirmngr.c (record_output): Rewrite. -- Thou shalt not percent-escape for C-unescaping. Fixes-commit: 51341badb623927f2a358588c725a356fc77dbe7 Signed-off-by: Werner Koch --- g10/call-dirmngr.c | 96 ++++++++++------------------------------------ 1 file changed, 21 insertions(+), 75 deletions(-) diff --git a/g10/call-dirmngr.c b/g10/call-dirmngr.c index f5fc8fcde..6b44bdeb8 100644 --- a/g10/call-dirmngr.c +++ b/g10/call-dirmngr.c @@ -849,24 +849,14 @@ static void record_output (estream_t output, pkttype_t type, const char *validity, - /* The public key length or -1. */ - int pub_key_length, - /* The public key algo or -1. */ - int pub_key_algo, - /* 2 ulongs or NULL. */ - const u32 *keyid, - /* The creation / expiration date or 0. */ - u32 creation_date, - u32 expiration_date, - const char *userid) + int pub_key_length, /* The public key length or -1. */ + int pub_key_algo, /* The public key algo or -1. */ + const u32 *keyid, /* 2 ulongs or NULL. */ + u32 creation_date, /* The creation date or 0. */ + u32 expiration_date, /* The expiration date or 0. */ + const char *userid) /* The userid or NULL. */ { const char *type_str = NULL; - char *pub_key_length_str = NULL; - char *pub_key_algo_str = NULL; - char *keyid_str = NULL; - char *creation_date_str = NULL; - char *expiration_date_str = NULL; - char *userid_escaped = NULL; switch (type) { @@ -885,77 +875,33 @@ record_output (estream_t output, default: log_assert (! "Unhandled type."); } + es_fprintf (output, "%s:%s:", + type_str, + validity ? validity : ""); if (pub_key_length > 0) - pub_key_length_str = xasprintf ("%d", pub_key_length); + es_fprintf (output, "%d", pub_key_length); + es_fputc (':', output); if (pub_key_algo != -1) - pub_key_algo_str = xasprintf ("%d", pub_key_algo); + es_fprintf (output, "%d", pub_key_algo); + es_fputc (':', output); if (keyid) - keyid_str = xasprintf ("%08lX%08lX", (ulong) keyid[0], (ulong) keyid[1]); + es_fprintf (output, "%08lX%08lX", (ulong) keyid[0], (ulong) keyid[1]); - if (creation_date) - creation_date_str = xstrdup (colon_strtime (creation_date)); + es_fprintf (output, ":%s:", colon_strtime (creation_date)); + es_fprintf (output, "%s:::", colon_strtime (expiration_date)); - if (expiration_date) - expiration_date_str = xstrdup (colon_strtime (expiration_date)); - - /* Quote ':', '%', and any 8-bit characters. */ if (userid) - { - int r; - int w = 0; + es_write_sanitized (output, userid, strlen (userid), ":", NULL); + else + es_fputc (':', output); + es_fputs (":::::::::\n", output); - int len = strlen (userid); - /* A 100k character limit on the uid should be way more than - enough. */ - if (len > 100 * 1024) - len = 100 * 1024; - - /* The minimum amount of space that we need. */ - userid_escaped = xmalloc (len * 3 + 1); - - for (r = 0; r < len; r++) - { - if (userid[r] == ':' || userid[r]== '%' || (userid[r] & 0x80)) - { - sprintf (&userid_escaped[w], "%%%02X", (byte) userid[r]); - w += 3; - } - else - userid_escaped[w ++] = userid[r]; - } - userid_escaped[w] = '\0'; - } - - es_fprintf (output, "%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s\n", - type_str, - validity ?: "", - pub_key_length_str ?: "", - pub_key_algo_str ?: "", - keyid_str ?: "", - creation_date_str ?: "", - expiration_date_str ?: "", - "" /* Certificate S/N */, - "" /* Ownertrust. */, - userid_escaped ?: "", - "" /* Signature class. */, - "" /* Key capabilities. */, - "" /* Issuer certificate fingerprint. */, - "" /* Flag field. */, - "" /* S/N of a token. */, - "" /* Hash algo. */, - "" /* Curve name. */); - - xfree (userid_escaped); - xfree (expiration_date_str); - xfree (creation_date_str); - xfree (keyid_str); - xfree (pub_key_algo_str); - xfree (pub_key_length_str); } + /* Handle the KS_PUT inquiries. */ static gpg_error_t ks_put_inq_cb (void *opaque, const char *line)