gpg: Add command --print-pka-records.
authorWerner Koch <wk@gnupg.org>
Tue, 24 Feb 2015 18:31:59 +0000 (19:31 +0100)
committerWerner Koch <wk@gnupg.org>
Tue, 24 Feb 2015 18:31:59 +0000 (19:31 +0100)
* g10/gpg.c (main): Add command --print-pka-records.
* g10/options.h (struct opt): Add field "print_pka_records".
* g10/keylist.c (list_keyblock_pka): New.
(list_keyblock): Call it if new option is set.
(print_fingerprint): Add mode 10.
--

This is a fist step towards a slightly updated PKA implementation.

Signed-off-by: Werner Koch <wk@gnupg.org>
g10/gpg.c
g10/keylist.c
g10/options.h

index df67d4f..ea331d6 100644 (file)
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -131,6 +131,7 @@ enum cmd_and_opt_values
     aSendKeys,
     aRecvKeys,
     aLocateKeys,
+    aPrintPKARecords,
     aSearchKeys,
     aRefreshKeys,
     aFetchKeys,
@@ -407,6 +408,7 @@ static ARGPARSE_OPTS opts[] = {
   ARGPARSE_c (aCheckKeys, "check-sigs",N_("list and check key signatures")),
   ARGPARSE_c (oFingerprint, "fingerprint", N_("list keys and fingerprints")),
   ARGPARSE_c (aListSecretKeys, "list-secret-keys", N_("list secret keys")),
+  ARGPARSE_c (aPrintPKARecords, "print-pka-records", "@"),
   ARGPARSE_c (aKeygen,     "gen-key",
               N_("generate a new key pair")),
   ARGPARSE_c (aQuickKeygen, "quick-gen-key" ,
@@ -2312,6 +2314,11 @@ main (int argc, char **argv)
             set_cmd (&cmd, pargs.r_opt);
             break;
 
+         case aPrintPKARecords:
+            set_cmd (&cmd, pargs.r_opt);
+            opt.print_pka_records = 1;
+            break;
+
          case aKeygen:
          case aFullKeygen:
          case aEditKey:
@@ -3857,6 +3864,13 @@ main (int argc, char **argv)
        public_key_list (ctrl, sl, 1);
        free_strlist (sl);
        break;
+      case aPrintPKARecords:
+       sl = NULL;
+       for (; argc; argc--, argv++)
+          add_to_strlist2( &sl, *argv, utf8_strings );
+       public_key_list (ctrl, sl, 0);
+       free_strlist (sl);
+       break;
 
       case aQuickKeygen:
         if (argc != 1 )
index da933ca..881ffa4 100644 (file)
@@ -794,6 +794,78 @@ dump_attribs (const PKT_user_id *uid, PKT_public_key *pk)
 }
 
 
+/* Print IPGP cert records instead of a standard key listing.  */
+static void
+list_keyblock_pka (kbnode_t keyblock)
+{
+  kbnode_t kbctx;
+  kbnode_t node;
+  PKT_public_key *pk;
+  char pkstrbuf[PUBKEY_STRING_SIZE];
+  char *hexfpr;
+
+  /* Get the keyid from the keyblock.  */
+  node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
+  if (!node)
+    {
+      log_error ("Oops; key lost!\n");
+      dump_kbnode (keyblock);
+      return;
+    }
+
+  pk = node->pkt->pkt.public_key;
+
+  es_fprintf (es_stdout, ";; pub  %s/%s %s\n;; ",
+              pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
+              keystr_from_pk (pk), datestr_from_pk (pk));
+  print_fingerprint (NULL, pk, 10);
+  hexfpr = hexfingerprint (pk);
+
+  for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0));)
+    {
+      if (node->pkt->pkttype == PKT_USER_ID)
+       {
+         PKT_user_id *uid = node->pkt->pkt.user_id;
+          char *mbox;
+          char *p;
+
+         if (pk && (uid->is_expired || uid->is_revoked)
+             && !(opt.list_options & LIST_SHOW_UNUSABLE_UIDS))
+            continue;
+
+          es_fputs (";; uid  ", es_stdout);
+          print_utf8_buffer (es_stdout, uid->name, uid->len);
+         es_putc ('\n', es_stdout);
+          mbox = mailbox_from_userid (uid->name);
+          if (mbox && (p = strchr (mbox, '@')))
+            {
+              char hashbuf[20];
+              char *hash;
+              unsigned int len;
+
+              *p++ = 0;
+              es_fprintf (es_stdout, "$ORIGIN _pka.%s.\n", p);
+              gcry_md_hash_buffer (GCRY_MD_SHA1, hashbuf, mbox, strlen (mbox));
+              hash = zb32_encode (hashbuf, 8*20);
+              if (hash)
+                {
+                  len = strlen (hexfpr)/2;
+                  es_fprintf (es_stdout,
+                              "%s TYPE37 \\# %u 0006 0000 00 %02X %s\n",
+                              hash, 6 + len, len, hexfpr);
+                  xfree (hash);
+                }
+            }
+          xfree (mbox);
+       }
+
+    }
+  es_putc ('\n', es_stdout);
+
+  xfree (hexfpr);
+}
+
+
 static void
 list_keyblock_print (KBNODE keyblock, int secret, int fpr, void *opaque)
 {
@@ -1572,7 +1644,12 @@ list_keyblock (KBNODE keyblock, int secret, int has_secret, int fpr,
                void *opaque)
 {
   reorder_keyblock (keyblock);
-  if (opt.with_colons)
+  if (opt.print_pka_records)
+    {
+      if (!secret)
+        list_keyblock_pka (keyblock);
+    }
+  else if (opt.with_colons)
     list_keyblock_colon (keyblock, secret, has_secret, fpr);
   else
     list_keyblock_print (keyblock, secret, fpr, opaque);
@@ -1600,6 +1677,7 @@ print_icao_hexdigit (estream_t fp, int c)
  *      1: print using log_info ()
  *      2: direct use of tty
  *      3: direct use of tty but only primary key.
+ *     10: Same as 0 but with_colons etc is ignored.
  *
  * Modes 1 and 2 will try and print both subkey and primary key
  * fingerprints.  A MODE with bit 7 set is used internally.  If
@@ -1614,6 +1692,15 @@ print_fingerprint (estream_t override_fp, PKT_public_key *pk, int mode)
   estream_t fp;
   const char *text;
   int primary = 0;
+  int with_colons = opt.with_colons;
+  int with_icao   = opt.with_icao_spelling;
+
+  if (mode == 10)
+    {
+      mode = 0;
+      with_colons = 0;
+      with_icao = 0;
+    }
 
   if (pk->main_keyid[0] == pk->keyid[0]
       && pk->main_keyid[1] == pk->keyid[1])
@@ -1667,7 +1754,7 @@ print_fingerprint (estream_t override_fp, PKT_public_key *pk, int mode)
 
   fingerprint_from_pk (pk, array, &n);
   p = array;
-  if (opt.with_colons && !mode)
+  if (with_colons && !mode)
     {
       es_fprintf (fp, "fpr:::::::::");
       for (i = 0; i < n; i++, p++)
@@ -1689,7 +1776,7 @@ print_fingerprint (estream_t override_fp, PKT_public_key *pk, int mode)
        }
     }
   tty_fprintf (fp, "\n");
-  if (!opt.with_colons && opt.with_icao_spelling)
+  if (!with_colons && with_icao)
     {
       p = array;
       tty_fprintf (fp, "%*s\"", (int)strlen(text)+1, "");
index a09d3d5..18cca2b 100644 (file)
@@ -73,6 +73,7 @@ struct
   int with_secret;      /* Option --with-secret active.  */
   int fingerprint; /* list fingerprints */
   int list_sigs;   /* list signatures */
+  int print_pka_records;
   int no_armor;
   int list_packets; /* list-packets mode: 1=normal, 2=invoked by command*/
   int def_cipher_algo;