[PATCH] Allow printing key digests in key edit

Christian Aistleitner christian at quelltextlich.at
Sun Jan 29 16:23:11 CET 2012


Hello,

Although SHA1 is considered to be broken by some, key-signing parties typically still rely on asserting validity of keys by comparing their fingerprints. The main obstacle being that programs as GnuPG do not provide an easy access to a more secure digest of a key.

The patch added below, adds a "digest" command in the --edit-keys menu, that allows to compute further digests of keys.

By getting easy access to SHA2 digests of their keys, participants of key-signing parties can assert validity of keys by comparing SHA2 digests, and can finally (manually) check whether a key obtained from a keyserver matches the SHA2 digests compared at the party.

Kind regards,
Christian

P.S.: Of course, this does not address the problems arising from the use of SHA1 in OpenPGP, or from (key) signatures made with SHA1. This patch just gives more options to the GnuPG user.

---
 g10/keyedit.c |   71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 70 insertions(+), 1 deletions(-)

diff --git a/g10/keyedit.c b/g10/keyedit.c
index 26e05a0..d78c761 100644
--- a/g10/keyedit.c
+++ b/g10/keyedit.c
@@ -56,6 +56,8 @@ static void show_key_with_all_names (KBNODE keyblock, int only_marked,
 				     int with_revoker, int with_fpr,
 				     int with_subkeys, int with_prefs);
 static void show_key_and_fingerprint (KBNODE keyblock);
+static void show_digest (KBNODE keyblock, int digest_algo);
+static int menu_digest (void);
 static int menu_adduid (KBNODE keyblock, int photo, const char *photo_name);
 static void menu_deluid (KBNODE pub_keyblock);
 static int menu_delsig (KBNODE pub_keyblock);
@@ -1308,7 +1310,7 @@ enum cmdids
   cmdEXPIRE, cmdBACKSIGN, cmdENABLEKEY, cmdDISABLEKEY, cmdSHOWPREF,
   cmdSETPREF, cmdPREFKS, cmdNOTATION, cmdINVCMD, cmdSHOWPHOTO, cmdUPDTRUST,
   cmdCHKTRUST, cmdADDCARDKEY, cmdKEYTOCARD, cmdBKUPTOCARD, cmdCHECKBKUPKEY,
-  cmdCLEAN, cmdMINIMIZE, cmdNOP
+  cmdCLEAN, cmdMINIMIZE, cmdDIGEST, cmdNOP
 };
 
 static struct
@@ -1399,6 +1401,7 @@ static struct
     N_("compact unusable user IDs and remove unusable signatures from key")},
   { "minimize", cmdMINIMIZE, KEYEDIT_NOT_SK,
     N_("compact unusable user IDs and remove all signatures from key")},
+  { "digest", cmdDIGEST, 0, N_("compute a digest for the key")},
 
   { NULL, cmdNONE, 0, NULL}
 };
@@ -1649,6 +1652,10 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
 	  show_key_and_fingerprint (keyblock);
 	  break;
 
+	case cmdDIGEST:
+	  show_digest( keyblock, menu_digest() );
+	  break;
+
 	case cmdSELUID:
 	  if (strlen (arg_string) == NAMEHASH_LEN * 2)
 	    redisplay = menu_select_uid_namehash (keyblock, arg_string);
@@ -2938,6 +2945,68 @@ show_key_and_fingerprint (KBNODE keyblock)
     print_fingerprint (pk, 2);
 }
 
+// Prints a digest of the public key in keyblock
+// using the digest_algo digest algorithm
+static void
+show_digest (KBNODE keyblock, int digest_algo)
+{
+  PKT_public_key *pk = NULL;
+  gcry_md_hd_t md;
+  const byte *dp;
+  int len;
+  int i;
+
+  assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY);
+  pk = keyblock->pkt->pkt.public_key;
+
+  tty_printf ("\n");
+
+  if (gcry_md_open (&md, digest_algo, 0))
+    BUG ();
+  hash_public_key(md,pk);
+  gcry_md_final( md );
+
+  dp = gcry_md_read( md, 0 );
+  len = gcry_md_get_algo_dlen (gcry_md_get_algo (md));
+  assert( len >=0 );
+  tty_printf("   %s digest of key = ", gcry_md_algo_name( digest_algo ) );
+  for ( i=0; i < len ; i++ )
+    tty_printf("%s%s%s%02X",
+	       (i&15)?"":"\n     ",
+	       (i&7)?"":" ",
+	       (i&1)?"":" ",
+	       dp[i] );
+  gcry_md_close( md );
+
+  tty_printf ("\n");
+}
+
+static int
+menu_digest ( void )
+{
+  int i;
+  char *answer;
+  int digest_algo = 0;
+
+  // Showing the possible digests
+  tty_printf (_("Please select what kind of digest you want:\n"));
+  for(i=0; i <= 110; i++ )
+    if( !openpgp_md_test_algo(i) )
+      {
+	tty_printf( "  (%d) %s\n", i, gcry_md_algo_name(i));
+      }
+
+  // User selects digest
+  while ( openpgp_md_test_algo( digest_algo ) )
+    {
+      answer = cpr_get( "keyedit.print_digest", _("Your selection? ") );
+      cpr_kill_prompt ();
+      digest_algo = *answer? atoi (answer) : DIGEST_ALGO_SHA512;
+    }
+
+  return digest_algo;
+}
+
 
 /* Show a warning if no uids on the key have the primary uid flag
    set. */
-- 
1.7.8.3
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 490 bytes
Desc: Digital signature
URL: </pipermail/attachments/20120129/ec51fb3a/attachment.pgp>


More information about the Gnupg-devel mailing list