aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2023-09-04 14:34:55 +0000
committerWerner Koch <[email protected]>2023-09-04 14:36:51 +0000
commit1f76cbca35133969ccccfa324d633556e19a386c (patch)
tree5475d0fc7ab2801f3a761f59d84ad891d6c12054
parentgpgsm: Add --always-trust feature. (diff)
downloadgnupg-1f76cbca35133969ccccfa324d633556e19a386c.tar.gz
gnupg-1f76cbca35133969ccccfa324d633556e19a386c.zip
gpg: Add option --with-v5-fingerprint
* g10/gpg.c (oWithV5Fingerprint): New. (opts): Add new option. (main): Set option. * g10/options.h (opt): Add with_v5_fingerprint. * g10/keyid.c (hash_public_key): Factor out to ... (do_hash_public_key): this. Add new arg to foce v5 style hashing. (v5_fingerprint_from_pk): New. (v5hexfingerprint): New. * g10/keylist.c (print_fingerprint): Print v5 fingerprint for v4 keys if the option is set. -- GnuPG-bug-id: 6705
-rw-r--r--doc/gpg.texi5
-rw-r--r--g10/gpg.c13
-rw-r--r--g10/keydb.h2
-rw-r--r--g10/keyid.c84
-rw-r--r--g10/keylist.c6
-rw-r--r--g10/options.h1
6 files changed, 102 insertions, 9 deletions
diff --git a/doc/gpg.texi b/doc/gpg.texi
index 15b3243d0..ce72afbf5 100644
--- a/doc/gpg.texi
+++ b/doc/gpg.texi
@@ -2849,6 +2849,11 @@ achieved by using the @option{--with-fingerprint} twice but by using
this option along with keyid-format "none" a compact fingerprint is
printed.
+@item --with-v5-fingerprint
+@opindex with-v5-fingerprint
+In a colon mode listing emit "fp2" lines for version 4 OpenPGP keys
+having a v5 style fingerprint of the key.
+
@item --with-icao-spelling
@opindex with-icao-spelling
Print the ICAO spelling of the fingerprint in addition to the hex digits.
diff --git a/g10/gpg.c b/g10/gpg.c
index 2ae3750a9..cb6e42e3c 100644
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -203,6 +203,7 @@ enum cmd_and_opt_values
oAskCertLevel,
oNoAskCertLevel,
oFingerprint,
+ oWithV5Fingerprint,
oWithFingerprint,
oWithSubkeyFingerprint,
oWithICAOSpelling,
@@ -816,6 +817,7 @@ static gpgrt_opt_t opts[] = {
ARGPARSE_s_n (oWithKeyData,"with-key-data", "@"),
ARGPARSE_s_n (oWithSigList,"with-sig-list", "@"),
ARGPARSE_s_n (oWithSigCheck,"with-sig-check", "@"),
+ ARGPARSE_s_n (oWithV5Fingerprint, "with-v5-fingerprint", "@"),
ARGPARSE_s_n (oWithFingerprint, "with-fingerprint", "@"),
ARGPARSE_s_n (oWithSubkeyFingerprint, "with-subkey-fingerprint", "@"),
ARGPARSE_s_n (oWithSubkeyFingerprint, "with-subkey-fingerprints", "@"),
@@ -2890,6 +2892,9 @@ main (int argc, char **argv)
opt_log_time = 1;
break;
+ case oWithV5Fingerprint:
+ opt.with_v5_fingerprint = 1;
+ break;
case oWithFingerprint:
opt.with_fingerprint = 1;
opt.fingerprint++;
@@ -3794,6 +3799,14 @@ main (int argc, char **argv)
g10_exit(2);
}
+ /* Set depended fingerprint options. */
+ if (opt.with_v5_fingerprint && !opt.with_fingerprint)
+ {
+ opt.with_fingerprint = 1;
+ if (!opt.fingerprint)
+ opt.fingerprint = 1;
+ }
+
/* Process common component options. */
if (parse_comopt (GNUPG_MODULE_NAME_GPG, debug_argparser))
{
diff --git a/g10/keydb.h b/g10/keydb.h
index 1a66d664e..b18f6e93a 100644
--- a/g10/keydb.h
+++ b/g10/keydb.h
@@ -570,8 +570,10 @@ 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 );
+byte *v5_fingerprint_from_pk (PKT_public_key *pk, byte *array, size_t *ret_len);
void fpr20_from_pk (PKT_public_key *pk, byte array[20]);
char *hexfingerprint (PKT_public_key *pk, char *buffer, size_t buflen);
+char *v5hexfingerprint (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);
diff --git a/g10/keyid.c b/g10/keyid.c
index 9191fec92..b80ee320e 100644
--- a/g10/keyid.c
+++ b/g10/keyid.c
@@ -2,7 +2,7 @@
* Copyright (C) 1998, 1999, 2000, 2001, 2003,
* 2004, 2006, 2010 Free Software Foundation, Inc.
* Copyright (C) 2014 Werner Koch
- * Copyright (C) 2016 g10 Code GmbH
+ * Copyright (C) 2016, 2023 g10 Code GmbH
*
* This file is part of GnuPG.
*
@@ -18,6 +18,7 @@
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <https://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: GPL-3.0-or-later
*/
#include <config.h>
@@ -139,10 +140,11 @@ pubkey_string (PKT_public_key *pk, char *buffer, size_t bufsize)
}
-/* Hash a public key. This function is useful for v4 and v5
- * fingerprints and for v3 or v4 key signing. */
-void
-hash_public_key (gcry_md_hd_t md, PKT_public_key *pk)
+/* Hash a public key and allow to specify the to be used format.
+ * Note that if the v5 format is requested for a v4 key, a 0x04 as
+ * version is hashed instead of the 0x05. */
+static void
+do_hash_public_key (gcry_md_hd_t md, PKT_public_key *pk, int use_v5)
{
unsigned int n;
unsigned int nn[PUBKEY_MAX_NPKEY];
@@ -151,9 +153,8 @@ hash_public_key (gcry_md_hd_t md, PKT_public_key *pk)
unsigned int nbits;
size_t nbytes;
int npkey = pubkey_get_npkey (pk->pubkey_algo);
- int is_v5 = pk->version == 5;
- n = is_v5? 10 : 6;
+ n = use_v5? 10 : 6;
/* FIXME: We can avoid the extra malloc by calling only the first
mpi_print here which computes the required length and calling the
real mpi_print only at the end. The speed advantage would only be
@@ -230,13 +231,14 @@ hash_public_key (gcry_md_hd_t md, PKT_public_key *pk)
}
}
- if (is_v5)
+ if (use_v5)
{
gcry_md_putc ( md, 0x9a ); /* ctb */
gcry_md_putc ( md, n >> 24 ); /* 4 byte length header */
gcry_md_putc ( md, n >> 16 );
gcry_md_putc ( md, n >> 8 );
gcry_md_putc ( md, n );
+ /* Note that the next byte may either be 4 or 5. */
gcry_md_putc ( md, pk->version );
}
else
@@ -253,7 +255,7 @@ hash_public_key (gcry_md_hd_t md, PKT_public_key *pk)
gcry_md_putc ( md, pk->pubkey_algo );
- if (is_v5)
+ if (use_v5)
{
n -= 10;
gcry_md_putc ( md, n >> 24 );
@@ -280,6 +282,15 @@ hash_public_key (gcry_md_hd_t md, PKT_public_key *pk)
}
+/* Hash a public key. This function is useful for v4 and v5
+ * fingerprints and for v3 or v4 key signing. */
+void
+hash_public_key (gcry_md_hd_t md, PKT_public_key *pk)
+{
+ do_hash_public_key (md, pk, pk->version);
+}
+
+
/* fixme: Check whether we can replace this function or if not
describe why we need it. */
u32
@@ -889,6 +900,37 @@ fingerprint_from_pk (PKT_public_key *pk, byte *array, size_t *ret_len)
/*
+ * Return a byte array with the fingerprint for the given PK/SK The
+ * length of the array is returned in ret_len. Caller must free the
+ * array or provide an array of length MAX_FINGERPRINT_LEN. This
+ * version creates a v5 fingerprint even vor v4 keys.
+ */
+byte *
+v5_fingerprint_from_pk (PKT_public_key *pk, byte *array, size_t *ret_len)
+{
+ const byte *dp;
+ gcry_md_hd_t md;
+
+ if (pk->version == 5)
+ return fingerprint_from_pk (pk, array, ret_len);
+
+ if (gcry_md_open (&md, GCRY_MD_SHA256, 0))
+ BUG ();
+ do_hash_public_key (md, pk, 1);
+ gcry_md_final (md);
+ dp = gcry_md_read (md, 0);
+ if (!array)
+ array = xmalloc (32);
+ memcpy (array, dp, 32);
+ gcry_md_close (md);
+
+ if (ret_len)
+ *ret_len = 32;
+ return array;
+}
+
+
+/*
* Get FPR20 for the given PK/SK into ARRAY.
*
* FPR20 is special form of fingerprint of length 20 for the record of
@@ -947,6 +989,30 @@ hexfingerprint (PKT_public_key *pk, char *buffer, size_t buflen)
}
+/* Same as hexfingerprint but returns a v5 fingerprint also for a v4
+ * key. */
+char *
+v5hexfingerprint (PKT_public_key *pk, char *buffer, size_t buflen)
+{
+ char fprbuf[32];
+
+ if (pk->version == 5)
+ return hexfingerprint (pk, buffer, buflen);
+
+ if (!buffer)
+ {
+ buffer = xtrymalloc (2 * 32 + 1);
+ if (!buffer)
+ return NULL;
+ }
+ else if (buflen < 2 * 32 + 1)
+ log_fatal ("%s: buffer too short (%zu)\n", __func__, buflen);
+
+ v5_fingerprint_from_pk (pk, fprbuf, NULL);
+ return bin2hex (fprbuf, 32, 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
diff --git a/g10/keylist.c b/g10/keylist.c
index 8b7c597cb..d0ebfc86f 100644
--- a/g10/keylist.c
+++ b/g10/keylist.c
@@ -2413,6 +2413,12 @@ print_fingerprint (ctrl_t ctrl, estream_t override_fp,
if (with_colons && !mode)
{
es_fprintf (fp, "fpr:::::::::%s:", hexfpr);
+ if (opt.with_v5_fingerprint && pk->version == 4)
+ {
+ char *v5fpr = v5hexfingerprint (pk, NULL, 0);
+ es_fprintf (fp, "\nfp2:::::::::%s:", v5fpr);
+ xfree (v5fpr);
+ }
}
else if (compact && !opt.fingerprint && !opt.with_fingerprint)
{
diff --git a/g10/options.h b/g10/options.h
index 914c24849..e0ee99533 100644
--- a/g10/options.h
+++ b/g10/options.h
@@ -79,6 +79,7 @@ struct
int with_colons;
int with_key_data;
int with_icao_spelling; /* Print ICAO spelling with fingerprints. */
+ int with_v5_fingerprint; /* Option --with-v5-fingerprint active. */
int with_fingerprint; /* Option --with-fingerprint active. */
int with_subkey_fingerprint; /* Option --with-subkey-fingerprint active. */
int with_keygrip; /* Option --with-keygrip active. */