diff --git a/g10/export.c b/g10/export.c index b9272515f..3c2aa5745 100644 --- a/g10/export.c +++ b/g10/export.c @@ -819,7 +819,7 @@ print_status_exported (PKT_public_key *pk) if (!is_status_enabled ()) return; - hexfpr = hexfingerprint (pk); + hexfpr = hexfingerprint (pk, NULL, 0); write_status_text (STATUS_EXPORTED, hexfpr? hexfpr : "[?]"); xfree (hexfpr); } diff --git a/g10/gpg.h b/g10/gpg.h index 6f92abdde..5cd836697 100644 --- a/g10/gpg.h +++ b/g10/gpg.h @@ -43,6 +43,10 @@ Warning: At some places we still use 20 instead of this macro. */ #define MAX_FINGERPRINT_LEN 20 +/* The maximum length of a formatted fingerprint as returned by + format_hexfingerprint(). */ +#define MAX_FORMATTED_FINGERPRINT_LEN 50 + /* Forward declarations. diff --git a/g10/keydb.h b/g10/keydb.h index 76136c156..e909c0fec 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -809,7 +809,9 @@ const char *colon_datestr_from_pk (PKT_public_key *pk); const char *colon_datestr_from_sig (PKT_signature *sig); const char *colon_expirestr_from_sig (PKT_signature *sig); byte *fingerprint_from_pk( PKT_public_key *pk, byte *buf, size_t *ret_len ); -char *hexfingerprint (PKT_public_key *pk); +char *hexfingerprint (PKT_public_key *pk, char *buffer, size_t buflen); +char *format_hexfingerprint (const char *fingerprint, + char *buffer, size_t buflen); gpg_error_t keygrip_from_pk (PKT_public_key *pk, unsigned char *array); gpg_error_t hexkeygrip_from_pk (PKT_public_key *pk, char **r_grip); diff --git a/g10/keyid.c b/g10/keyid.c index 42a5f9fe0..de46d7212 100644 --- a/g10/keyid.c +++ b/g10/keyid.c @@ -704,18 +704,81 @@ fingerprint_from_pk (PKT_public_key *pk, byte *array, size_t *ret_len) /* Return an allocated buffer with the fingerprint of PK formatted as - a plain hexstring. */ + a plain hexstring. If BUFFER is NULL the result is a malloc'd + string. If BUFFER is not NULL the result will be copied into this + buffer. In the latter case BUFLEN describes the length of the + buffer; if this is too short the function terminates the process. + Returns a malloc'ed string or BUFFER. A suitable length for BUFFER + is (2*MAX_FINGERPRINT_LEN + 1). */ char * -hexfingerprint (PKT_public_key *pk) +hexfingerprint (PKT_public_key *pk, char *buffer, size_t buflen) { unsigned char fpr[MAX_FINGERPRINT_LEN]; size_t len; - char *result; fingerprint_from_pk (pk, fpr, &len); - result = xmalloc (2 * len + 1); - bin2hex (fpr, len, result); - return result; + if (!buffer) + buffer = xmalloc (2 * len + 1); + else if (buflen < 2*len+1) + log_fatal ("%s: buffer too short (%zu)\n", __func__, buflen); + bin2hex (fpr, len, buffer); + return buffer; +} + + +/* Pretty print a hex fingerprint. If BUFFER is NULL the result is a + malloc'd string. If BUFFER is not NULL the result will be copied + into this buffer. In the latter case BUFLEN describes the length + of the buffer; if this is too short the function terminates the + process. Returns a malloc'ed string or BUFFER. A suitable length + for BUFFER is (MAX_FORMATTED_FINGERPRINT_LEN + 1). */ +char * +format_hexfingerprint (const char *fingerprint, char *buffer, size_t buflen) +{ + int hexlen = strlen (fingerprint); + int space; + int i, j; + + if (hexlen == 40) /* v4 fingerprint */ + { + space = (/* The characters and the NUL. */ + 40 + 1 + /* After every fourth character, we add a space (except + the last). */ + + 40 / 4 - 1 + /* Half way through we add a second space. */ + + 1); + } + else /* Other fingerprint versions - print as is. */ + { + space = hexlen + 1; + } + + if (!buffer) + buffer = xmalloc (space); + else if (buflen < space) + log_fatal ("%s: buffer too short (%zu)\n", __func__, buflen); + + if (hexlen == 40) /* v4 fingerprint */ + { + for (i = 0, j = 0; i < 40; i ++) + { + if (i && i % 4 == 0) + buffer[j ++] = ' '; + if (i == 40 / 2) + buffer[j ++] = ' '; + + buffer[j ++] = fingerprint[i]; + } + buffer[j ++] = 0; + assert (j == space); + } + else + { + strcpy (buffer, fingerprint); + } + + return buffer; } diff --git a/g10/keylist.c b/g10/keylist.c index f3fd9d99a..2923a13e3 100644 --- a/g10/keylist.c +++ b/g10/keylist.c @@ -895,7 +895,7 @@ list_keyblock_pka (ctrl_t ctrl, kbnode_t keyblock) } - hexfpr = hexfingerprint (pk); + hexfpr = hexfingerprint (pk, NULL, 0); if (opt.print_dane_records) { kbnode_t dummy_keyblock; @@ -1833,8 +1833,9 @@ print_icao_hexdigit (estream_t fp, int c) void print_fingerprint (estream_t override_fp, PKT_public_key *pk, int mode) { - byte array[MAX_FINGERPRINT_LEN], *p; - size_t i, n; + char hexfpr[2*MAX_FINGERPRINT_LEN+1]; + char *p; + size_t i; estream_t fp; const char *text; int primary = 0; @@ -1903,47 +1904,33 @@ print_fingerprint (estream_t override_fp, PKT_public_key *pk, int mode) text = _(" Key fingerprint ="); } - fingerprint_from_pk (pk, array, &n); - p = array; + hexfingerprint (pk, hexfpr, sizeof hexfpr); if (with_colons && !mode) { - es_fprintf (fp, "fpr:::::::::"); - for (i = 0; i < n; i++, p++) - es_fprintf (fp, "%02X", *p); - es_putc (':', fp); + es_fprintf (fp, "fpr:::::::::%s:", hexfpr); } else { - tty_fprintf (fp, "%s", text); - if (n == 20) - { - for (i = 0; i < n; i++, i++, p += 2) - tty_fprintf (fp, "%s %02X%02X", i==10? " ":"", *p, p[1]); - } - else - { - for (i = 0; i < n; i++, p++) - tty_fprintf (fp, "%s %02X", (i && !(i % 8))? " ":"", *p); - } + char fmtfpr[MAX_FORMATTED_FINGERPRINT_LEN + 1]; + format_hexfingerprint (hexfpr, fmtfpr, sizeof fmtfpr); + tty_fprintf (fp, "%s %s", text, fmtfpr); } tty_fprintf (fp, "\n"); if (!with_colons && with_icao) { - p = array; + ; tty_fprintf (fp, "%*s\"", (int)strlen(text)+1, ""); - for (i = 0; i < n; i++, p++) + for (i = 0, p = hexfpr; *p; i++, p++) { if (!i) ; - else if (!(i%4)) + else if (!(i%8)) tty_fprintf (fp, "\n%*s ", (int)strlen(text)+1, ""); - else if (!(i%2)) + else if (!(i%4)) tty_fprintf (fp, " "); else tty_fprintf (fp, " "); - print_icao_hexdigit (fp, *p >> 4); - tty_fprintf (fp, " "); - print_icao_hexdigit (fp, *p & 15); + print_icao_hexdigit (fp, xtoi_1 (p)); } tty_fprintf (fp, "\"\n"); } diff --git a/g10/revoke.c b/g10/revoke.c index 7ff50be2a..460f346b7 100644 --- a/g10/revoke.c +++ b/g10/revoke.c @@ -530,7 +530,7 @@ gen_standard_revoke (PKT_public_key *psk, const char *cache_nonce) char *orig_codeset; dir = get_openpgp_revocdir (opt.homedir); - tmpstr = hexfingerprint (psk); + tmpstr = hexfingerprint (psk, NULL, 0); fname = xstrconcat (dir, DIRSEP_S, tmpstr, NULL); xfree (tmpstr); xfree (dir); diff --git a/g10/tofu.c b/g10/tofu.c index 5501ceedb..b1b9f7174 100644 --- a/g10/tofu.c +++ b/g10/tofu.c @@ -167,48 +167,9 @@ tofu_cache_dump (struct db *db) # define TIME_AGO_UNIT_LARGE_NAME _("month") # define TIME_AGO_UNIT_LARGE_NAME_PLURAL _("months") #endif + -/* Pretty print a MAX_FINGERPRINT_LEN-byte binary fingerprint into a - malloc'd string. */ -static char * -fingerprint_format (const byte *fingerprint) -{ - char *fingerprint_pretty; - int space = (/* The characters and the NUL. */ - 2 * MAX_FINGERPRINT_LEN + 1 - /* After every fourth character, we add a space (except - the last). */ - + 2 * MAX_FINGERPRINT_LEN / 4 - 1 - /* Half way through we add a second space. */ - + 1); - int i; - int j; - - if (strlen (fingerprint) != 2 * MAX_FINGERPRINT_LEN) - { - log_info (_("Fingerprint with unexpected length (%zu chars)\n"), - strlen (fingerprint)); - return xstrdup (fingerprint); - } - - fingerprint_pretty = xmalloc (space); - - for (i = 0, j = 0; i < MAX_FINGERPRINT_LEN * 2; i ++) - { - if (i && i % 4 == 0) - fingerprint_pretty[j ++] = ' '; - if (i == MAX_FINGERPRINT_LEN * 2 / 2) - fingerprint_pretty[j ++] = ' '; - - fingerprint_pretty[j ++] = fingerprint[i]; - } - fingerprint_pretty[j ++] = 0; - assert (j == space); - - return fingerprint_pretty; -} - const char * tofu_policy_str (enum tofu_policy policy) { @@ -1114,7 +1075,7 @@ static gpg_error_t record_binding (struct dbs *dbs, const char *fingerprint, const char *email, const char *user_id, enum tofu_policy policy, int show_old) { - char *fingerprint_pp = fingerprint_format (fingerprint); + char *fingerprint_pp = format_hexfingerprint (fingerprint, NULL, 0); struct db *db_email = NULL, *db_key = NULL; int rc; char *err = NULL; @@ -1639,7 +1600,7 @@ get_trust (struct dbs *dbs, const char *fingerprint, const char *email, if (! db) return _tofu_GET_TRUST_ERROR; - fingerprint_pp = fingerprint_format (fingerprint); + fingerprint_pp = format_hexfingerprint (fingerprint, NULL, 0); policy = get_policy (dbs, fingerprint, email, &conflict); if (policy == TOFU_POLICY_AUTO || policy == TOFU_POLICY_NONE) @@ -1878,7 +1839,7 @@ get_trust (struct dbs *dbs, const char *fingerprint, const char *email, display this message. */ && conflict && strcmp (conflict, fingerprint) != 0) { - char *conflict_pp = fingerprint_format (conflict); + char *conflict_pp = format_hexfingerprint (conflict, NULL, 0); es_fprintf (fp, _("The key %s raised a conflict with this binding (%s)." " Since this binding's policy was 'auto', it was " @@ -2035,7 +1996,7 @@ get_trust (struct dbs *dbs, const char *fingerprint, const char *email, char *key_pp; key = stats_iter->fingerprint; this_key = strcmp (key, fingerprint) == 0; - key_pp = fingerprint_format (key); + key_pp = format_hexfingerprint (key, NULL, 0); if (this_key) es_fprintf (fp, _(" %s (this key):"), key_pp); else @@ -2351,7 +2312,7 @@ show_statistics (struct dbs *dbs, const char *fingerprint, if (! db) return; - fingerprint_pp = fingerprint_format (fingerprint); + fingerprint_pp = format_hexfingerprint (fingerprint, NULL, 0); rc = sqlite3_exec_printf (db->db, strings_collect_cb, &strlist, &err, @@ -2579,8 +2540,8 @@ tofu_register (PKT_public_key *pk, const char *user_id, goto die; } - fingerprint = hexfingerprint (pk); - fingerprint_pp = fingerprint_format (fingerprint); + fingerprint = hexfingerprint (pk, NULL, 0); + fingerprint_pp = format_hexfingerprint (fingerprint, NULL, 0); if (! *user_id) { @@ -2794,7 +2755,7 @@ tofu_get_validity (PKT_public_key *pk, const char *user_id, goto die; } - fingerprint = hexfingerprint (pk); + fingerprint = hexfingerprint (pk, NULL, 0); if (! *user_id) { @@ -2853,7 +2814,7 @@ tofu_set_policy (kbnode_t kb, enum tofu_policy policy) && pk->main_keyid[1] == pk->keyid[1])) log_bug ("%s: Passed a subkey, but expecting a primary key.\n", __func__); - fingerprint = hexfingerprint (pk); + fingerprint = hexfingerprint (pk, NULL, 0); for (; kb; kb = kb->next) { @@ -2925,7 +2886,7 @@ tofu_get_policy (PKT_public_key *pk, PKT_user_id *user_id, return gpg_error (GPG_ERR_GENERAL); } - fingerprint = hexfingerprint (pk); + fingerprint = hexfingerprint (pk, NULL, 0); email = email_from_user_id (user_id->name);