More agent support for gpg.
[gnupg.git] / g10 / keylist.c
1 /* keylist.c - Print information about OpenPGP keys
2  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
3  *               2008, 2010 Free Software Foundation, Inc.
4  *
5  * This file is part of GnuPG.
6  *
7  * GnuPG is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * GnuPG is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <assert.h>
27 #ifdef HAVE_DOSISH_SYSTEM
28 #include <fcntl.h>              /* for setmode() */
29 #endif
30
31 #include "gpg.h"
32 #include "options.h"
33 #include "packet.h"
34 #include "status.h"
35 #include "keydb.h"
36 #include "photoid.h"
37 #include "util.h"
38 #include "ttyio.h"
39 #include "trustdb.h"
40 #include "main.h"
41 #include "i18n.h"
42 #include "status.h"
43 #include "call-agent.h"
44
45 static void list_all (int);
46 static void list_one (strlist_t names, int secret);
47 static void locate_one (ctrl_t ctrl, strlist_t names);
48 static void print_card_serialno (const char *serialno);
49
50 struct sig_stats
51 {
52   int inv_sigs;
53   int no_key;
54   int oth_err;
55 };
56
57 /* The stream used to write attribute packets to.  */
58 static estream_t attrib_fp;
59
60
61 /* List the keys.  If list is NULL, all available keys are listed.
62    With LOCATE_MODE set the locate algorithm is used to find a
63    key.  */
64 void
65 public_key_list (ctrl_t ctrl, strlist_t list, int locate_mode)
66 {
67   if (opt.with_colons)
68     {
69       byte trust_model, marginals, completes, cert_depth;
70       ulong created, nextcheck;
71
72       read_trust_options (&trust_model, &created, &nextcheck,
73                           &marginals, &completes, &cert_depth);
74
75       es_fprintf (es_stdout, "tru:");
76
77       if (nextcheck && nextcheck <= make_timestamp ())
78         es_fprintf (es_stdout, "o");
79       if (trust_model != opt.trust_model)
80         es_fprintf (es_stdout, "t");
81       if (opt.trust_model == TM_PGP || opt.trust_model == TM_CLASSIC)
82         {
83           if (marginals != opt.marginals_needed)
84             es_fprintf (es_stdout, "m");
85           if (completes != opt.completes_needed)
86             es_fprintf (es_stdout, "c");
87           if (cert_depth != opt.max_cert_depth)
88             es_fprintf (es_stdout, "d");
89         }
90
91       es_fprintf (es_stdout, ":%d:%lu:%lu", trust_model, created, nextcheck);
92
93       /* Only show marginals, completes, and cert_depth in the classic
94          or PGP trust models since they are not meaningful
95          otherwise. */
96
97       if (trust_model == TM_PGP || trust_model == TM_CLASSIC)
98         es_fprintf (es_stdout, ":%d:%d:%d", marginals, completes, cert_depth);
99
100       es_fprintf (es_stdout, "\n");
101     }
102
103   /* We need to do the stale check right here because it might need to
104      update the keyring while we already have the keyring open.  This
105      is very bad for W32 because of a sharing violation. For real OSes
106      it might lead to false results if we are later listing a keyring
107      which is associated with the inode of a deleted file.  */
108   check_trustdb_stale ();
109
110   if (locate_mode)
111     locate_one (ctrl, list);
112   else if (!list)
113     list_all (0);
114   else
115     list_one (list, 0);
116 }
117
118
119 void
120 secret_key_list (ctrl_t ctrl, strlist_t list)
121 {
122   (void)ctrl;
123
124   check_trustdb_stale ();
125
126   if (!list)
127     list_all (1);
128   else                          /* List by user id */
129     list_one (list, 1);
130 }
131
132 void
133 print_seckey_info (PKT_public_key *pk)
134 {
135   u32 keyid[2];
136   char *p;
137
138   keyid_from_pk (pk, keyid);
139   p = get_user_id_native (keyid);
140
141   tty_printf ("\nsec  %4u%c/%s %s %s\n",
142               nbits_from_pk (pk),
143               pubkey_letter (pk->pubkey_algo),
144               keystr (keyid), datestr_from_pk (pk), p);
145
146   xfree (p);
147 }
148
149 /* Print information about the public key.  With FP passed as NULL,
150    the tty output interface is used, otherwise output is directted to
151    the given stream.  */
152 void
153 print_pubkey_info (estream_t fp, PKT_public_key * pk)
154 {
155   u32 keyid[2];
156   char *p;
157
158   keyid_from_pk (pk, keyid);
159
160   /* If the pk was chosen by a particular user ID, that is the one to
161      print.  */
162   if (pk->user_id)
163     p = utf8_to_native (pk->user_id->name, pk->user_id->len, 0);
164   else
165     p = get_user_id_native (keyid);
166
167   if (fp)
168     tty_printf ("\n");
169   tty_fprintf (fp, "pub  %4u%c/%s %s %s\n",
170                nbits_from_pk (pk),
171                pubkey_letter (pk->pubkey_algo),
172                keystr (keyid), datestr_from_pk (pk), p);
173   xfree (p);
174 }
175
176
177 /* Print basic information of a secret key including the card serial
178    number information.  */
179 #ifdef ENABLE_CARD_SUPPORT
180 void
181 print_card_key_info (estream_t fp, kbnode_t keyblock)
182 {
183   /* KBNODE node; */
184   /* int i; */
185
186   log_debug ("Fixme: Needs to be adjusted to gpg-agent\n");
187   /* for (node = keyblock; node; node = node->next) */
188   /*   { */
189   /*     if (node->pkt->pkttype == PKT_SECRET_KEY */
190   /*         || (node->pkt->pkttype == PKT_SECRET_SUBKEY)) */
191   /*       { */
192   /*         PKT_public_key *pk = node->pkt->pkt.public_key; */
193
194   /*         tty_fprintf (fp, "%s%c  %4u%c/%s  ", */
195   /*                   node->pkt->pkttype == PKT_SECRET_KEY ? "sec" : "ssb", */
196   /*                   (sk->protect.s2k.mode == 1001) ? '#' : */
197   /*                   (sk->protect.s2k.mode == 1002) ? '>' : ' ', */
198   /*                   nbits_from_sk (sk), */
199   /*                   pubkey_letter (sk->pubkey_algo), keystr_from_sk (sk)); */
200   /*         tty_fprintf (fp, _("created: %s"), datestr_from_sk (sk)); */
201   /*         tty_fprintf (fp, "  "); */
202   /*         tty_fprintf (fp, _("expires: %s"), expirestr_from_sk (sk)); */
203   /*         if (sk->is_protected && sk->protect.s2k.mode == 1002) */
204   /*           { */
205   /*             tty_fprintf (fp, "\n                      "); */
206   /*             tty_fprintf (fp, _("card-no: ")); */
207   /*             if (sk->protect.ivlen == 16 */
208   /*              && !memcmp (sk->protect.iv, "\xD2\x76\x00\x01\x24\x01", 6)) */
209   /*            { */
210   /*              /\* This is an OpenPGP card. *\/ */
211   /*              for (i = 8; i < 14; i++) */
212   /*                { */
213   /*                  if (i == 10) */
214   /*                    tty_fprintf (fp, " "); */
215   /*                  tty_fprintf (fp, "%02X", sk->protect.iv[i]); */
216   /*                } */
217   /*            } */
218   /*             else */
219   /*            { */
220   /*                 /\* Something is wrong: Print all. *\/ */
221   /*              for (i = 0; i < sk->protect.ivlen; i++) */
222   /*                tty_fprintf (fp, "%02X", sk->protect.iv[i]); */
223   /*            } */
224   /*           } */
225   /*         tty_fprintf (fp, "\n"); */
226   /*       } */
227   /*   } */
228 }
229 #endif /*ENABLE_CARD_SUPPORT*/
230
231
232 /* Flags = 0x01 hashed 0x02 critical.  */
233 static void
234 status_one_subpacket (sigsubpkttype_t type, size_t len, int flags,
235                       const byte * buf)
236 {
237   char status[40];
238
239   /* Don't print these. */
240   if (len > 256)
241     return;
242
243   snprintf (status, sizeof status, 
244             "%d %u %u ", type, flags, (unsigned int) len);
245
246   write_status_text_and_buffer (STATUS_SIG_SUBPACKET, status, buf, len, 0);
247 }
248
249
250 /* Print a policy URL.  Allowed values for MODE are:
251  *   0 - print to stdout.
252  *   1 - use log_info and emit status messages.
253  *   2 - emit only status messages.
254  */
255 void
256 show_policy_url (PKT_signature * sig, int indent, int mode)
257 {
258   const byte *p;
259   size_t len;
260   int seq = 0, crit;
261   estream_t fp = mode ? log_get_stream () : es_stdout;
262
263   while ((p =
264           enum_sig_subpkt (sig->hashed, SIGSUBPKT_POLICY, &len, &seq, &crit)))
265     {
266       if (mode != 2)
267         {
268           int i;
269           const char *str;
270
271           for (i = 0; i < indent; i++)
272             es_putc (' ', fp);
273
274           if (crit)
275             str = _("Critical signature policy: ");
276           else
277             str = _("Signature policy: ");
278           if (mode)
279             log_info ("%s", str);
280           else
281             es_fprintf (fp, "%s", str);
282           print_utf8_buffer (fp, p, len);
283           es_fprintf (fp, "\n");
284         }
285
286       if (mode)
287         write_status_buffer (STATUS_POLICY_URL, p, len, 0);
288     }
289 }
290
291
292 /*
293   mode=0 for stdout.
294   mode=1 for log_info + status messages
295   mode=2 for status messages only
296 */
297 /* TODO: use this */
298 void
299 show_keyserver_url (PKT_signature * sig, int indent, int mode)
300 {
301   const byte *p;
302   size_t len;
303   int seq = 0, crit;
304   estream_t fp = mode ? log_get_stream () : es_stdout;
305
306   while ((p =
307           enum_sig_subpkt (sig->hashed, SIGSUBPKT_PREF_KS, &len, &seq,
308                            &crit)))
309     {
310       if (mode != 2)
311         {
312           int i;
313           const char *str;
314
315           for (i = 0; i < indent; i++)
316             es_putc (' ', es_stdout);
317
318           if (crit)
319             str = _("Critical preferred keyserver: ");
320           else
321             str = _("Preferred keyserver: ");
322           if (mode)
323             log_info ("%s", str);
324           else
325             es_fprintf (es_stdout, "%s", str);
326           print_utf8_buffer (fp, p, len);
327           es_fprintf (fp, "\n");
328         }
329
330       if (mode)
331         status_one_subpacket (SIGSUBPKT_PREF_KS, len,
332                               (crit ? 0x02 : 0) | 0x01, p);
333     }
334 }
335
336 /*
337   mode=0 for stdout.
338   mode=1 for log_info + status messages
339   mode=2 for status messages only
340
341   Defined bits in WHICH:
342     1 == standard notations
343     2 == user notations
344 */
345 void
346 show_notation (PKT_signature * sig, int indent, int mode, int which)
347 {
348   estream_t fp = mode ? log_get_stream () : es_stdout;
349   struct notation *nd, *notations;
350
351   if (which == 0)
352     which = 3;
353
354   notations = sig_to_notation (sig);
355
356   /* There may be multiple notations in the same sig. */
357   for (nd = notations; nd; nd = nd->next)
358     {
359       if (mode != 2)
360         {
361           int has_at = !!strchr (nd->name, '@');
362
363           if ((which & 1 && !has_at) || (which & 2 && has_at))
364             {
365               int i;
366               const char *str;
367
368               for (i = 0; i < indent; i++)
369                 es_putc (' ', es_stdout);
370
371               if (nd->flags.critical)
372                 str = _("Critical signature notation: ");
373               else
374                 str = _("Signature notation: ");
375               if (mode)
376                 log_info ("%s", str);
377               else
378                 es_fprintf (es_stdout, "%s", str);
379               /* This is all UTF8 */
380               print_utf8_buffer (fp, nd->name, strlen (nd->name));
381               es_fprintf (fp, "=");
382               print_utf8_buffer (fp, nd->value, strlen (nd->value));
383               es_fprintf (fp, "\n");
384             }
385         }
386
387       if (mode)
388         {
389           write_status_buffer (STATUS_NOTATION_NAME,
390                                nd->name, strlen (nd->name), 0);
391           write_status_buffer (STATUS_NOTATION_DATA,
392                                nd->value, strlen (nd->value), 50);
393         }
394     }
395
396   free_notation (notations);
397 }
398
399 static void
400 print_signature_stats (struct sig_stats *s)
401 {
402   if (s->inv_sigs == 1)
403     tty_printf (_("1 bad signature\n"));
404   else if (s->inv_sigs)
405     tty_printf (_("%d bad signatures\n"), s->inv_sigs);
406   if (s->no_key == 1)
407     tty_printf (_("1 signature not checked due to a missing key\n"));
408   else if (s->no_key)
409     tty_printf (_("%d signatures not checked due to missing keys\n"),
410                 s->no_key);
411   if (s->oth_err == 1)
412     tty_printf (_("1 signature not checked due to an error\n"));
413   else if (s->oth_err)
414     tty_printf (_("%d signatures not checked due to errors\n"), s->oth_err);
415 }
416
417 static void
418 list_all (int secret)
419 {
420   KEYDB_HANDLE hd;
421   KBNODE keyblock = NULL;
422   int rc = 0;
423   const char *lastresname, *resname;
424   struct sig_stats stats;
425
426   memset (&stats, 0, sizeof (stats));
427
428   hd = keydb_new ();
429   if (!hd)
430     rc = G10ERR_GENERAL;
431   else
432     rc = keydb_search_first (hd);
433   if (rc)
434     {
435       if (rc != -1)
436         log_error ("keydb_search_first failed: %s\n", g10_errstr (rc));
437       goto leave;
438     }
439
440   lastresname = NULL;
441   do
442     {
443       rc = keydb_get_keyblock (hd, &keyblock);
444       if (rc)
445         {
446           log_error ("keydb_get_keyblock failed: %s\n", g10_errstr (rc));
447           goto leave;
448         }
449       if (secret && agent_probe_any_secret_key (NULL, keyblock))
450         ; /* Secret key listing requested but this isn't one.  */
451       else
452         {
453           if (!opt.with_colons)
454             {
455               resname = keydb_get_resource_name (hd);
456               if (lastresname != resname)
457                 {
458                   int i;
459                   
460                   es_fprintf (es_stdout, "%s\n", resname);
461                   for (i = strlen (resname); i; i--)
462                     es_putc ('-', es_stdout);
463                   es_putc ('\n', es_stdout);
464                   lastresname = resname;
465                 }
466             }
467           merge_keys_and_selfsig (keyblock);
468           list_keyblock (keyblock, secret, opt.fingerprint,
469                          opt.check_sigs ? &stats : NULL);
470         }
471       release_kbnode (keyblock);
472       keyblock = NULL;
473     }
474   while (!(rc = keydb_search_next (hd)));
475   if (rc && rc != -1)
476     log_error ("keydb_search_next failed: %s\n", g10_errstr (rc));
477
478   if (opt.check_sigs && !opt.with_colons)
479     print_signature_stats (&stats);
480
481 leave:
482   release_kbnode (keyblock);
483   keydb_release (hd);
484 }
485
486
487 static void
488 list_one (strlist_t names, int secret)
489 {
490   int rc = 0;
491   KBNODE keyblock = NULL;
492   GETKEY_CTX ctx;
493   const char *resname;
494   const char *keyring_str = _("Keyring");
495   int i;
496   struct sig_stats stats;
497
498   memset (&stats, 0, sizeof (stats));
499
500   /* fixme: using the bynames function has the disadvantage that we
501    * don't know wether one of the names given was not found.  OTOH,
502    * this function has the advantage to list the names in the
503    * sequence as defined by the keyDB and does not duplicate
504    * outputs.  A solution could be do test whether all given have
505    * been listed (this needs a way to use the keyDB search
506    * functions) or to have the search function return indicators for
507    * found names.  Yet another way is to use the keydb search
508    * facilities directly. */
509   rc = getkey_bynames (&ctx, NULL, names, secret, &keyblock);
510   if (rc)
511     {
512       log_error ("error reading key: %s\n", g10_errstr (rc));
513       get_pubkey_end (ctx);
514       return;
515     }
516
517   do
518     {
519       if ((opt.list_options & LIST_SHOW_KEYRING) && !opt.with_colons)
520         {
521           resname = keydb_get_resource_name (get_ctx_handle (ctx));
522           es_fprintf (es_stdout, "%s: %s\n", keyring_str, resname);
523           for (i = strlen (resname) + strlen (keyring_str) + 2; i; i--)
524             es_putc ('-', es_stdout);
525           es_putc ('\n', es_stdout);
526         }
527       list_keyblock (keyblock, secret, opt.fingerprint,
528                      (!secret && opt.check_sigs)? &stats : NULL);
529       release_kbnode (keyblock);
530     }
531   while (!getkey_next (ctx, NULL, &keyblock));
532   getkey_end (ctx);
533   
534   if (opt.check_sigs && !opt.with_colons)
535     print_signature_stats (&stats);
536 }
537
538
539 static void
540 locate_one (ctrl_t ctrl, strlist_t names)
541 {
542   int rc = 0;
543   strlist_t sl;
544   GETKEY_CTX ctx = NULL;
545   KBNODE keyblock = NULL;
546   struct sig_stats stats;
547
548   memset (&stats, 0, sizeof (stats));
549
550   for (sl = names; sl; sl = sl->next)
551     {
552       rc = get_pubkey_byname (ctrl, &ctx, NULL, sl->d, &keyblock, NULL, 1, 0);
553       if (rc)
554         {
555           if (gpg_err_code (rc) != GPG_ERR_NO_PUBKEY)
556             log_error ("error reading key: %s\n", g10_errstr (rc));
557         }
558       else
559         {
560           do
561             {
562               list_keyblock (keyblock, 0, opt.fingerprint,
563                              opt.check_sigs ? &stats : NULL);
564               release_kbnode (keyblock);
565             }
566           while (ctx && !get_pubkey_next (ctx, NULL, &keyblock));
567           get_pubkey_end (ctx);
568           ctx = NULL;
569         }
570     }
571
572   if (opt.check_sigs && !opt.with_colons)
573     print_signature_stats (&stats);
574 }
575
576
577 static void
578 print_key_data (PKT_public_key * pk)
579 {
580   int n = pk ? pubkey_get_npkey (pk->pubkey_algo) : 0;
581   int i;
582
583   for (i = 0; i < n; i++)
584     {
585       es_fprintf (es_stdout, "pkd:%d:%u:", i, mpi_get_nbits (pk->pkey[i]));
586       mpi_print (es_stdout, pk->pkey[i], 1);
587       es_putc (':', es_stdout);
588       es_putc ('\n', es_stdout);
589     }
590 }
591
592 static void
593 print_capabilities (PKT_public_key *pk, KBNODE keyblock)
594 {
595   unsigned int use = pk->pubkey_usage;
596   int c_printed = 0;
597
598   if (use & PUBKEY_USAGE_ENC)
599     es_putc ('e', es_stdout);
600   
601   if (use & PUBKEY_USAGE_SIG)
602     {
603       es_putc ('s', es_stdout);
604       if (pk->is_primary)
605         {
606           es_putc ('c', es_stdout);
607           /* The PUBKEY_USAGE_CERT flag was introduced later and we
608              used to always print 'c' for a primary key.  To avoid any
609              regression here we better track whether we printed 'c'
610              already.  */
611           c_printed = 1;
612         }
613     }
614
615   if ((use & PUBKEY_USAGE_CERT) && !c_printed)
616     es_putc ('c', es_stdout);
617
618   if ((use & PUBKEY_USAGE_AUTH))
619     es_putc ('a', es_stdout);
620
621   if (keyblock)
622     {
623       /* Figure out the usable capabilities.  */
624       KBNODE k;
625       int enc = 0, sign = 0, cert = 0, auth = 0, disabled = 0;
626
627       for (k = keyblock; k; k = k->next)
628         {
629           if (k->pkt->pkttype == PKT_PUBLIC_KEY
630               || k->pkt->pkttype == PKT_PUBLIC_SUBKEY)
631             {
632               pk = k->pkt->pkt.public_key;
633
634               if (pk->is_primary)
635                 disabled = pk_is_disabled (pk);
636
637               if (pk->is_valid && !pk->is_revoked && !pk->has_expired)
638                 {
639                   if (pk->pubkey_usage & PUBKEY_USAGE_ENC)
640                     enc = 1;
641                   if (pk->pubkey_usage & PUBKEY_USAGE_SIG)
642                     {
643                       sign = 1;
644                       if (pk->is_primary)
645                         cert = 1;
646                     }
647                   if (pk->pubkey_usage & PUBKEY_USAGE_CERT)
648                     cert = 1;
649                   if ((pk->pubkey_usage & PUBKEY_USAGE_AUTH))
650                     auth = 1;
651                 }
652             }
653         }
654       if (enc)
655         es_putc ('E', es_stdout);
656       if (sign)
657         es_putc ('S', es_stdout);
658       if (cert)
659         es_putc ('C', es_stdout);
660       if (auth)
661         es_putc ('A', es_stdout);
662       if (disabled)
663         es_putc ('D', es_stdout);
664     }
665   
666   es_putc (':', es_stdout);
667 }
668
669
670 /* FLAGS: 0x01 hashed
671           0x02 critical  */
672 static void
673 print_one_subpacket (sigsubpkttype_t type, size_t len, int flags,
674                      const byte * buf)
675 {
676   size_t i;
677
678   es_fprintf (es_stdout, "spk:%d:%u:%u:", type, flags, (unsigned int) len);
679
680   for (i = 0; i < len; i++)
681     {
682       /* printable ascii other than : and % */
683       if (buf[i] >= 32 && buf[i] <= 126 && buf[i] != ':' && buf[i] != '%')
684         es_fprintf (es_stdout, "%c", buf[i]);
685       else
686         es_fprintf (es_stdout, "%%%02X", buf[i]);
687     }
688
689   es_fprintf (es_stdout, "\n");
690 }
691
692
693 void
694 print_subpackets_colon (PKT_signature * sig)
695 {
696   byte *i;
697
698   assert (opt.show_subpackets);
699
700   for (i = opt.show_subpackets; *i; i++)
701     {
702       const byte *p;
703       size_t len;
704       int seq, crit;
705
706       seq = 0;
707
708       while ((p = enum_sig_subpkt (sig->hashed, *i, &len, &seq, &crit)))
709         print_one_subpacket (*i, len, 0x01 | (crit ? 0x02 : 0), p);
710
711       seq = 0;
712
713       while ((p = enum_sig_subpkt (sig->unhashed, *i, &len, &seq, &crit)))
714         print_one_subpacket (*i, len, 0x00 | (crit ? 0x02 : 0), p);
715     }
716 }
717
718
719 void
720 dump_attribs (const PKT_user_id *uid, PKT_public_key *pk)
721 {
722   int i;
723
724   if (!attrib_fp)
725     return;
726
727   for (i = 0; i < uid->numattribs; i++)
728     {
729       if (is_status_enabled ())
730         {
731           byte array[MAX_FINGERPRINT_LEN], *p;
732           char buf[(MAX_FINGERPRINT_LEN * 2) + 90];
733           size_t j, n;
734
735           if (!pk)
736             BUG ();
737           fingerprint_from_pk (pk, array, &n);
738
739           p = array;
740           for (j = 0; j < n; j++, p++)
741             sprintf (buf + 2 * j, "%02X", *p);
742
743           sprintf (buf + strlen (buf), " %lu %u %u %u %lu %lu %u",
744                    (ulong) uid->attribs[i].len, uid->attribs[i].type, i + 1,
745                    uid->numattribs, (ulong) uid->created,
746                    (ulong) uid->expiredate,
747                    ((uid->is_primary ? 0x01 : 0) | (uid->
748                                                     is_revoked ? 0x02 : 0) |
749                     (uid->is_expired ? 0x04 : 0)));
750           write_status_text (STATUS_ATTRIBUTE, buf);
751         }
752
753       es_fwrite (uid->attribs[i].data, uid->attribs[i].len, 1, attrib_fp);
754       es_fflush (attrib_fp);
755     }
756 }
757
758
759 static void
760 list_keyblock_print (KBNODE keyblock, int secret, int fpr, void *opaque)
761 {
762   int rc;
763   KBNODE kbctx;
764   KBNODE node;
765   PKT_public_key *pk;
766   struct sig_stats *stats = opaque;
767   int skip_sigs = 0;
768   int s2k_char;
769   char *hexgrip = NULL;
770   char *serialno = NULL;
771
772   /* Get the keyid from the keyblock.  */
773   node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
774   if (!node)
775     {
776       log_error ("Oops; key lost!\n");
777       dump_kbnode (keyblock);
778       return;
779     }
780
781   pk = node->pkt->pkt.public_key;
782
783   if (secret || opt.with_keygrip)
784     {
785       rc = hexkeygrip_from_pk (pk, &hexgrip);
786       if (rc)
787         log_error ("error computing a keygrip: %s\n", gpg_strerror (rc));
788     }
789
790   if (secret)
791     {
792       if (!agent_get_keyinfo (NULL, hexgrip, &serialno))
793         s2k_char = serialno? '>':' ';
794       else
795         s2k_char = '#';  /* Key not found.  */
796     }
797   else
798     s2k_char = ' ';
799   
800   check_trustdb_stale ();
801
802   es_fprintf (es_stdout, "%s%c  %4u%c/%s %s", 
803           secret? "sec":"pub",
804           s2k_char,
805           nbits_from_pk (pk), pubkey_letter (pk->pubkey_algo),
806           keystr_from_pk (pk), datestr_from_pk (pk));
807
808   if (pk->is_revoked)
809     {
810       es_fprintf (es_stdout, " [");
811       es_fprintf (es_stdout, _("revoked: %s"), revokestr_from_pk (pk));
812       es_fprintf (es_stdout, "]");
813     }
814   else if (pk->has_expired)
815     {
816       es_fprintf (es_stdout, " [");
817       es_fprintf (es_stdout, _("expired: %s"), expirestr_from_pk (pk));
818       es_fprintf (es_stdout, "]");
819     }
820   else if (pk->expiredate)
821     {
822       es_fprintf (es_stdout, " [");
823       es_fprintf (es_stdout, _("expires: %s"), expirestr_from_pk (pk));
824       es_fprintf (es_stdout, "]");
825     }
826
827 #if 0
828   /* I need to think about this some more.  It's easy enough to
829      include, but it looks sort of confusing in the listing... */
830   if (opt.list_options & LIST_SHOW_VALIDITY)
831     {
832       int validity = get_validity (pk, NULL);
833       es_fprintf (es_stdout, " [%s]", trust_value_to_string (validity));
834     }
835 #endif
836
837   es_fprintf (es_stdout, "\n");
838
839   if (fpr)
840     print_fingerprint (pk, 0);
841
842   if (opt.with_keygrip && hexgrip)
843     es_fprintf (es_stdout, "      Keygrip = %s\n", hexgrip);
844
845   if (serialno)
846     print_card_serialno (serialno);
847
848   if (opt.with_key_data)
849     print_key_data (pk);
850
851   for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0));)
852     {
853       if (node->pkt->pkttype == PKT_USER_ID && !opt.fast_list_mode)
854         {
855           PKT_user_id *uid = node->pkt->pkt.user_id;
856
857           if (pk && (uid->is_expired || uid->is_revoked)
858               && !(opt.list_options & LIST_SHOW_UNUSABLE_UIDS))
859             {
860               skip_sigs = 1;
861               continue;
862             }
863           else
864             skip_sigs = 0;
865
866           if (attrib_fp && uid->attrib_data != NULL)
867             dump_attribs (uid, pk);
868
869           if ((uid->is_revoked || uid->is_expired)
870               || ((opt.list_options & LIST_SHOW_UID_VALIDITY) && pk))
871             {
872               const char *validity;
873               int indent;
874
875               validity = uid_trust_string_fixed (pk, uid);
876               indent =
877                 (keystrlen () + 9) -
878                 atoi (uid_trust_string_fixed (NULL, NULL));
879
880               if (indent < 0 || indent > 40)
881                 indent = 0;
882
883               es_fprintf (es_stdout, "uid%*s%s ", indent, "", validity);
884             }
885           else
886             es_fprintf (es_stdout, "uid%*s", (int) keystrlen () + 10, "");
887
888           print_utf8_buffer (es_stdout, uid->name, uid->len);
889           es_putc ('\n', es_stdout);
890
891           if ((opt.list_options & LIST_SHOW_PHOTOS) && uid->attribs != NULL)
892             show_photos (uid->attribs, uid->numattribs, pk, uid);
893         }
894       else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
895         {
896           PKT_public_key *pk2 = node->pkt->pkt.public_key;
897
898           if ((pk2->is_revoked || pk2->has_expired)
899               && !(opt.list_options & LIST_SHOW_UNUSABLE_SUBKEYS))
900             {
901               skip_sigs = 1;
902               continue;
903             }
904           else
905             skip_sigs = 0;
906
907           xfree (serialno); serialno = NULL;
908           xfree (hexgrip); hexgrip = NULL;
909           if (secret || opt.with_keygrip)
910             {
911               rc = hexkeygrip_from_pk (pk2, &hexgrip);
912               if (rc)
913                 log_error ("error computing a keygrip: %s\n",
914                            gpg_strerror (rc));
915             }
916           if (secret)
917             {
918               if (!agent_get_keyinfo (NULL, hexgrip, &serialno))
919                 s2k_char = serialno? '>':' ';
920               else
921                 s2k_char = '#';  /* Key not found.  */
922             }
923           else
924             s2k_char = ' ';
925           
926           es_fprintf (es_stdout, "%s%c  %4u%c/%s %s",
927                   secret? "ssb":"sub",
928                   s2k_char,
929                   nbits_from_pk (pk2), pubkey_letter (pk2->pubkey_algo),
930                   keystr_from_pk (pk2), datestr_from_pk (pk2));
931           if (pk2->is_revoked)
932             {
933               es_fprintf (es_stdout, " [");
934               es_fprintf (es_stdout, _("revoked: %s"), revokestr_from_pk (pk2));
935               es_fprintf (es_stdout, "]");
936             }
937           else if (pk2->has_expired)
938             {
939               es_fprintf (es_stdout, " [");
940               es_fprintf (es_stdout, _("expired: %s"), expirestr_from_pk (pk2));
941               es_fprintf (es_stdout, "]");
942             }
943           else if (pk2->expiredate)
944             {
945               es_fprintf (es_stdout, " [");
946               es_fprintf (es_stdout, _("expires: %s"), expirestr_from_pk (pk2));
947               es_fprintf (es_stdout, "]");
948             }
949           es_putc ('\n', es_stdout);
950           if (fpr > 1)
951             {
952               print_fingerprint (pk2, 0);
953               if (serialno)
954                 print_card_serialno (serialno);
955             }
956           if (opt.with_keygrip && hexgrip)
957             es_fprintf (es_stdout, "      Keygrip = %s\n", hexgrip);
958           if (opt.with_key_data)
959             print_key_data (pk2);
960         }
961       else if (opt.list_sigs
962                && node->pkt->pkttype == PKT_SIGNATURE && !skip_sigs)
963         {
964           PKT_signature *sig = node->pkt->pkt.signature;
965           int sigrc;
966           char *sigstr;
967
968           if (stats)
969             {
970               rc = check_key_signature (keyblock, node, NULL);
971               switch (gpg_err_code (rc))
972                 {
973                 case 0:
974                   sigrc = '!';
975                   break;
976                 case GPG_ERR_BAD_SIGNATURE:
977                   stats->inv_sigs++;
978                   sigrc = '-';
979                   break;
980                 case GPG_ERR_NO_PUBKEY:
981                 case GPG_ERR_UNUSABLE_PUBKEY:
982                   stats->no_key++;
983                   continue;
984                 default:
985                   stats->oth_err++;
986                   sigrc = '%';
987                   break;
988                 }
989
990               /* TODO: Make sure a cached sig record here still has
991                  the pk that issued it.  See also
992                  keyedit.c:print_and_check_one_sig */
993             }
994           else
995             {
996               rc = 0;
997               sigrc = ' ';
998             }
999
1000           if (sig->sig_class == 0x20 || sig->sig_class == 0x28
1001               || sig->sig_class == 0x30)
1002             sigstr = "rev";
1003           else if ((sig->sig_class & ~3) == 0x10)
1004             sigstr = "sig";
1005           else if (sig->sig_class == 0x18)
1006             sigstr = "sig";
1007           else if (sig->sig_class == 0x1F)
1008             sigstr = "sig";
1009           else
1010             {
1011               es_fprintf (es_stdout, "sig                             "
1012                       "[unexpected signature class 0x%02x]\n",
1013                       sig->sig_class);
1014               continue;
1015             }
1016
1017           es_fputs (sigstr, es_stdout);
1018           es_fprintf (es_stdout, "%c%c %c%c%c%c%c%c %s %s",
1019                   sigrc, (sig->sig_class - 0x10 > 0 &&
1020                           sig->sig_class - 0x10 <
1021                           4) ? '0' + sig->sig_class - 0x10 : ' ',
1022                   sig->flags.exportable ? ' ' : 'L',
1023                   sig->flags.revocable ? ' ' : 'R',
1024                   sig->flags.policy_url ? 'P' : ' ',
1025                   sig->flags.notation ? 'N' : ' ',
1026                   sig->flags.expired ? 'X' : ' ',
1027                   (sig->trust_depth > 9) ? 'T' : (sig->trust_depth >
1028                                                   0) ? '0' +
1029                   sig->trust_depth : ' ', keystr (sig->keyid),
1030                   datestr_from_sig (sig));
1031           if (opt.list_options & LIST_SHOW_SIG_EXPIRE)
1032             es_fprintf (es_stdout, " %s", expirestr_from_sig (sig));
1033           es_fprintf (es_stdout, "  ");
1034           if (sigrc == '%')
1035             es_fprintf (es_stdout, "[%s] ", g10_errstr (rc));
1036           else if (sigrc == '?')
1037             ;
1038           else if (!opt.fast_list_mode)
1039             {
1040               size_t n;
1041               char *p = get_user_id (sig->keyid, &n);
1042               print_utf8_buffer (es_stdout, p, n);
1043               xfree (p);
1044             }
1045           es_putc ('\n', es_stdout);
1046
1047           if (sig->flags.policy_url
1048               && (opt.list_options & LIST_SHOW_POLICY_URLS))
1049             show_policy_url (sig, 3, 0);
1050
1051           if (sig->flags.notation && (opt.list_options & LIST_SHOW_NOTATIONS))
1052             show_notation (sig, 3, 0,
1053                            ((opt.
1054                              list_options & LIST_SHOW_STD_NOTATIONS) ? 1 : 0)
1055                            +
1056                            ((opt.
1057                              list_options & LIST_SHOW_USER_NOTATIONS) ? 2 :
1058                             0));
1059
1060           if (sig->flags.pref_ks
1061               && (opt.list_options & LIST_SHOW_KEYSERVER_URLS))
1062             show_keyserver_url (sig, 3, 0);
1063
1064           /* fixme: check or list other sigs here */
1065         }
1066     }
1067   es_putc ('\n', es_stdout);
1068   xfree (serialno);
1069   xfree (hexgrip);
1070 }
1071
1072 void
1073 print_revokers (PKT_public_key * pk)
1074 {
1075   /* print the revoker record */
1076   if (!pk->revkey && pk->numrevkeys)
1077     BUG ();
1078   else
1079     {
1080       int i, j;
1081
1082       for (i = 0; i < pk->numrevkeys; i++)
1083         {
1084           byte *p;
1085
1086           es_fprintf (es_stdout, "rvk:::%d::::::", pk->revkey[i].algid);
1087           p = pk->revkey[i].fpr;
1088           for (j = 0; j < 20; j++, p++)
1089             es_fprintf (es_stdout, "%02X", *p);
1090           es_fprintf (es_stdout, ":%02x%s:\n", pk->revkey[i].class,
1091                   (pk->revkey[i].class & 0x40) ? "s" : "");
1092         }
1093     }
1094 }
1095
1096 static void
1097 list_keyblock_colon (KBNODE keyblock, int secret, int fpr)
1098 {
1099   int rc;
1100   KBNODE kbctx;
1101   KBNODE node;
1102   PKT_public_key *pk;
1103   u32 keyid[2];
1104   int trustletter = 0;
1105   int ulti_hack = 0;
1106   int i;
1107   char *p;
1108   char *hexgrip = NULL;
1109   char *serialno = NULL;
1110   int stubkey;
1111
1112   /* Get the keyid from the keyblock.  */
1113   node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
1114   if (!node)
1115     {
1116       log_error ("Oops; key lost!\n");
1117       dump_kbnode (keyblock);
1118       return;
1119     }
1120
1121   pk = node->pkt->pkt.public_key;
1122   if (secret || opt.with_keygrip || opt.with_key_data)
1123     {
1124       rc = hexkeygrip_from_pk (pk, &hexgrip);
1125       if (rc)
1126         log_error ("error computing a keygrip: %s\n", gpg_strerror (rc));
1127     }
1128   stubkey = 0;
1129   if (secret && agent_get_keyinfo (NULL, hexgrip, &serialno))
1130     stubkey = 1;  /* Key not found.  */
1131
1132   keyid_from_pk (pk, keyid);
1133   es_fputs (secret? "sec:":"pub:", es_stdout);
1134   if (!pk->is_valid)
1135     es_putc ('i', es_stdout);
1136   else if (pk->is_revoked)
1137     es_putc ('r', es_stdout);
1138   else if (pk->has_expired)
1139     es_putc ('e', es_stdout);
1140   else if (opt.fast_list_mode || opt.no_expensive_trust_checks)
1141     ;
1142   else
1143     {
1144       trustletter = get_validity_info (pk, NULL);
1145       if (trustletter == 'u')
1146         ulti_hack = 1;
1147       es_putc (trustletter, es_stdout);
1148     }
1149
1150   es_fprintf (es_stdout, ":%u:%d:%08lX%08lX:%s:%s::",
1151           nbits_from_pk (pk),
1152           pk->pubkey_algo,
1153           (ulong) keyid[0], (ulong) keyid[1],
1154           colon_datestr_from_pk (pk), colon_strtime (pk->expiredate));
1155
1156   if (!opt.fast_list_mode && !opt.no_expensive_trust_checks)
1157     es_putc (get_ownertrust (pk), es_stdout);
1158   es_putc (':', es_stdout);
1159
1160   es_putc (':', es_stdout);
1161   es_putc (':', es_stdout);
1162   print_capabilities (pk, keyblock);
1163   if (secret)
1164     {
1165       es_putc (':', es_stdout);         /* End of field 13. */
1166       es_putc (':', es_stdout);         /* End of field 14. */
1167       if (stubkey)
1168         es_putc ('#', es_stdout);
1169       else if (serialno)
1170         es_fputs(serialno, es_stdout);
1171       es_putc (':', es_stdout);         /* End of field 15. */
1172     }
1173   es_putc ('\n', es_stdout);
1174
1175   print_revokers (pk);
1176   if (fpr)
1177     print_fingerprint (pk, 0);
1178   if (opt.with_key_data || opt.with_keygrip)
1179     {
1180       if (hexgrip)
1181         es_fprintf (es_stdout, "grp:::::::::%s:\n", hexgrip);
1182       if (opt.with_key_data)
1183         print_key_data (pk);
1184     }
1185
1186   for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0));)
1187     {
1188       if (node->pkt->pkttype == PKT_USER_ID && !opt.fast_list_mode)
1189         {
1190           char *str;
1191           PKT_user_id *uid = node->pkt->pkt.user_id;
1192
1193           if (attrib_fp && node->pkt->pkt.user_id->attrib_data != NULL)
1194             dump_attribs (node->pkt->pkt.user_id, pk);
1195           /*
1196            * Fixme: We need a is_valid flag here too 
1197            */
1198           str = uid->attrib_data ? "uat" : "uid";
1199           if (uid->is_revoked)
1200             es_fprintf (es_stdout, "%s:r::::", str);
1201           else if (uid->is_expired)
1202             es_fprintf (es_stdout, "%s:e::::", str);
1203           else if (opt.no_expensive_trust_checks)
1204             es_fprintf (es_stdout, "%s:::::", str);
1205           else
1206             {
1207               int uid_validity;
1208
1209               if (pk && !ulti_hack)
1210                 uid_validity = get_validity_info (pk, uid);
1211               else
1212                 uid_validity = 'u';
1213               es_fprintf (es_stdout, "%s:%c::::", str, uid_validity);
1214             }
1215
1216           es_fprintf (es_stdout, "%s:", colon_strtime (uid->created));
1217           es_fprintf (es_stdout, "%s:", colon_strtime (uid->expiredate));
1218
1219           namehash_from_uid (uid);
1220
1221           for (i = 0; i < 20; i++)
1222             es_fprintf (es_stdout, "%02X", uid->namehash[i]);
1223
1224           es_fprintf (es_stdout, "::");
1225
1226           if (uid->attrib_data)
1227             es_fprintf (es_stdout, "%u %lu", uid->numattribs, uid->attrib_len);
1228           else
1229             es_write_sanitized (es_stdout, uid->name, uid->len, ":", NULL);
1230           es_putc (':', es_stdout);
1231           es_putc ('\n', es_stdout);
1232         }
1233       else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
1234         {
1235           u32 keyid2[2];
1236           PKT_public_key *pk2;
1237
1238           pk2 = node->pkt->pkt.public_key;
1239           xfree (hexgrip); hexgrip = NULL;
1240           xfree (serialno); serialno = NULL;
1241           if (secret || opt.with_keygrip || opt.with_key_data)
1242             {
1243               rc = hexkeygrip_from_pk (pk2, &hexgrip);
1244               if (rc)
1245                 log_error ("error computing a keygrip: %s\n",
1246                            gpg_strerror (rc));
1247             }
1248           stubkey = 0;
1249           if (secret && agent_get_keyinfo (NULL, hexgrip, &serialno))
1250             stubkey = 1;  /* Key not found.  */
1251
1252           keyid_from_pk (pk2, keyid2);
1253           es_fputs (secret? "ssb:":"sub:", es_stdout);
1254           if (!pk2->is_valid)
1255             es_putc ('i', es_stdout);
1256           else if (pk2->is_revoked)
1257             es_putc ('r', es_stdout);
1258           else if (pk2->has_expired)
1259             es_putc ('e', es_stdout);
1260           else if (opt.fast_list_mode || opt.no_expensive_trust_checks)
1261             ;
1262           else
1263             {
1264               /* TRUSTLETTER should always be defined here. */
1265               if (trustletter)
1266                 es_fprintf (es_stdout, "%c", trustletter);
1267             }
1268           es_fprintf (es_stdout, ":%u:%d:%08lX%08lX:%s:%s:::::",
1269                   nbits_from_pk (pk2),
1270                   pk2->pubkey_algo,
1271                   (ulong) keyid2[0], (ulong) keyid2[1],
1272                   colon_datestr_from_pk (pk2), colon_strtime (pk2->expiredate)
1273                   /* fixme: add LID and ownertrust here */
1274             );
1275           print_capabilities (pk2, NULL);
1276           if (secret)
1277             {
1278               es_putc (':', es_stdout); /* End of field 13. */
1279               es_putc (':', es_stdout); /* End of field 14. */
1280               if (stubkey)
1281                 es_putc ('#', es_stdout);
1282               else if (serialno)
1283                 es_fputs (serialno, es_stdout);
1284               es_putc (':', es_stdout); /* End of field 15. */
1285             }
1286           es_putc ('\n', es_stdout);
1287           if (fpr > 1)
1288             print_fingerprint (pk2, 0);
1289           if (opt.with_key_data || opt.with_keygrip)
1290             {
1291               if (hexgrip)
1292                 es_fprintf (es_stdout, "grp:::::::::%s:\n", hexgrip);
1293               if (opt.with_key_data)
1294                 print_key_data (pk2);
1295             }
1296         }
1297       else if (opt.list_sigs && node->pkt->pkttype == PKT_SIGNATURE)
1298         {
1299           PKT_signature *sig = node->pkt->pkt.signature;
1300           int sigrc, fprokay = 0;
1301           char *sigstr;
1302           size_t fplen;
1303           byte fparray[MAX_FINGERPRINT_LEN];
1304
1305           if (sig->sig_class == 0x20 || sig->sig_class == 0x28
1306               || sig->sig_class == 0x30)
1307             sigstr = "rev";
1308           else if ((sig->sig_class & ~3) == 0x10)
1309             sigstr = "sig";
1310           else if (sig->sig_class == 0x18)
1311             sigstr = "sig";
1312           else if (sig->sig_class == 0x1F)
1313             sigstr = "sig";
1314           else
1315             {
1316               es_fprintf (es_stdout, "sig::::::::::%02x%c:\n",
1317                       sig->sig_class, sig->flags.exportable ? 'x' : 'l');
1318               continue;
1319             }
1320
1321           if (opt.check_sigs)
1322             {
1323               PKT_public_key *signer_pk = NULL;
1324
1325               fflush (stdout);
1326               if (opt.no_sig_cache)
1327                 signer_pk = xmalloc_clear (sizeof (PKT_public_key));
1328
1329               rc = check_key_signature2 (keyblock, node, NULL, signer_pk,
1330                                          NULL, NULL, NULL);
1331               switch (gpg_err_code (rc))
1332                 {
1333                 case 0:
1334                   sigrc = '!';
1335                   break;
1336                 case GPG_ERR_BAD_SIGNATURE:
1337                   sigrc = '-';
1338                   break;
1339                 case GPG_ERR_NO_PUBKEY:
1340                 case GPG_ERR_UNUSABLE_PUBKEY:
1341                   sigrc = '?';
1342                   break;
1343                 default:
1344                   sigrc = '%';
1345                   break;
1346                 }
1347
1348               if (opt.no_sig_cache)
1349                 {
1350                   if (!rc)
1351                     {
1352                       fingerprint_from_pk (signer_pk, fparray, &fplen);
1353                       fprokay = 1;
1354                     }
1355                   free_public_key (signer_pk);
1356                 }
1357             }
1358           else
1359             {
1360               rc = 0;
1361               sigrc = ' ';
1362             }
1363           es_fputs (sigstr, es_stdout);
1364           es_putc (':', es_stdout);
1365           if (sigrc != ' ')
1366             es_putc (sigrc, es_stdout);
1367           es_fprintf (es_stdout, "::%d:%08lX%08lX:%s:%s:", sig->pubkey_algo,
1368                   (ulong) sig->keyid[0], (ulong) sig->keyid[1],
1369                   colon_datestr_from_sig (sig),
1370                   colon_expirestr_from_sig (sig));
1371
1372           if (sig->trust_depth || sig->trust_value)
1373             es_fprintf (es_stdout, "%d %d", sig->trust_depth, sig->trust_value);
1374           es_fprintf (es_stdout, ":");
1375
1376           if (sig->trust_regexp)
1377             es_write_sanitized (es_stdout, sig->trust_regexp,
1378                                 strlen (sig->trust_regexp), ":", NULL);
1379           es_fprintf (es_stdout, ":");
1380
1381           if (sigrc == '%')
1382             es_fprintf (es_stdout, "[%s] ", g10_errstr (rc));
1383           else if (sigrc == '?')
1384             ;
1385           else if (!opt.fast_list_mode)
1386             {
1387               size_t n;
1388               p = get_user_id (sig->keyid, &n);
1389               es_write_sanitized (es_stdout, p, n, ":", NULL);
1390               xfree (p);
1391             }
1392           es_fprintf (es_stdout, ":%02x%c:", sig->sig_class,
1393                   sig->flags.exportable ? 'x' : 'l');
1394
1395           if (opt.no_sig_cache && opt.check_sigs && fprokay)
1396             {
1397               es_putc (':', es_stdout);
1398
1399               for (i = 0; i < fplen; i++)
1400                 es_fprintf (es_stdout, "%02X", fparray[i]);
1401
1402               es_putc (':', es_stdout);
1403             }
1404
1405           es_fprintf (es_stdout, "\n");
1406
1407           if (opt.show_subpackets)
1408             print_subpackets_colon (sig);
1409
1410           /* fixme: check or list other sigs here */
1411         }
1412     }
1413
1414   xfree (hexgrip);
1415   xfree (serialno);
1416 }
1417
1418 /*
1419  * Reorder the keyblock so that the primary user ID (and not attribute
1420  * packet) comes first.  Fixme: Replace this by a generic sort
1421  * function.  */
1422 static void
1423 do_reorder_keyblock (KBNODE keyblock, int attr)
1424 {
1425   KBNODE primary = NULL, primary0 = NULL, primary2 = NULL;
1426   KBNODE last, node;
1427
1428   for (node = keyblock; node; primary0 = node, node = node->next)
1429     {
1430       if (node->pkt->pkttype == PKT_USER_ID &&
1431           ((attr && node->pkt->pkt.user_id->attrib_data) ||
1432            (!attr && !node->pkt->pkt.user_id->attrib_data)) &&
1433           node->pkt->pkt.user_id->is_primary)
1434         {
1435           primary = primary2 = node;
1436           for (node = node->next; node; primary2 = node, node = node->next)
1437             {
1438               if (node->pkt->pkttype == PKT_USER_ID
1439                   || node->pkt->pkttype == PKT_PUBLIC_SUBKEY
1440                   || node->pkt->pkttype == PKT_SECRET_SUBKEY)
1441                 {
1442                   break;
1443                 }
1444             }
1445           break;
1446         }
1447     }
1448   if (!primary)
1449     return; /* No primary key flag found (should not happen).  */
1450
1451   for (last = NULL, node = keyblock; node; last = node, node = node->next)
1452     {
1453       if (node->pkt->pkttype == PKT_USER_ID)
1454         break;
1455     }
1456   assert (node);
1457   assert (last);         /* The user ID is never the first packet.  */
1458   assert (primary0);     /* Ditto (this is the node before primary).  */
1459   if (node == primary)
1460     return; /* Already the first one.  */
1461
1462   last->next = primary;
1463   primary0->next = primary2->next;
1464   primary2->next = node;
1465 }
1466
1467 void
1468 reorder_keyblock (KBNODE keyblock)
1469 {
1470   do_reorder_keyblock (keyblock, 1);
1471   do_reorder_keyblock (keyblock, 0);
1472 }
1473
1474 void
1475 list_keyblock (KBNODE keyblock, int secret, int fpr, void *opaque)
1476 {
1477   reorder_keyblock (keyblock);
1478   if (opt.with_colons)
1479     list_keyblock_colon (keyblock, secret, fpr);
1480   else
1481     list_keyblock_print (keyblock, secret, fpr, opaque);
1482 }
1483
1484 /*
1485  * Function to print the finperprint.
1486  * mode 0: as used in key listings, opt.with_colons is honored
1487  *      1: print using log_info ()
1488  *      2: direct use of tty
1489  *      3: direct use of tty but only primary key.
1490  *
1491  * Modes 1 and 2 will try and print both subkey and primary key
1492  * fingerprints.  A MODE with bit 7 set is used internally.
1493  */
1494 void
1495 print_fingerprint (PKT_public_key *pk, int mode)
1496 {
1497   byte array[MAX_FINGERPRINT_LEN], *p;
1498   size_t i, n;
1499   estream_t fp;
1500   const char *text;
1501   int primary = 0;
1502
1503   if (pk->main_keyid[0] == pk->keyid[0]
1504       && pk->main_keyid[1] == pk->keyid[1])
1505     primary = 1;
1506
1507   /* Just to be safe */
1508   if ((mode & 0x80) && !primary)
1509     {
1510       log_error ("primary key is not really primary!\n");
1511       return;
1512     }
1513
1514   mode &= ~0x80;
1515
1516   if (!primary && (mode == 1 || mode == 2))
1517     {
1518       PKT_public_key *primary_pk = xmalloc_clear (sizeof (*primary_pk));
1519       get_pubkey (primary_pk, pk->main_keyid);
1520       print_fingerprint (primary_pk, mode | 0x80);
1521       free_public_key (primary_pk);
1522     }
1523
1524   if (mode == 1)
1525     {
1526       fp = log_get_stream ();
1527       if (primary)
1528         text = _("Primary key fingerprint:");
1529       else
1530         text = _("     Subkey fingerprint:");
1531     }
1532   else if (mode == 2)
1533     {
1534       fp = NULL; /* Use tty.  */
1535       if (primary)
1536         /* TRANSLATORS: this should fit into 24 bytes to that the
1537          * fingerprint data is properly aligned with the user ID */
1538         text = _(" Primary key fingerprint:");
1539       else
1540         text = _("      Subkey fingerprint:");
1541     }
1542   else if (mode == 3)
1543     {
1544       fp = NULL; /* Use tty.  */
1545       text = _("      Key fingerprint =");
1546     }
1547   else
1548     {
1549       fp = es_stdout;
1550       text = _("      Key fingerprint =");
1551     }
1552
1553   fingerprint_from_pk (pk, array, &n);
1554   p = array;
1555   if (opt.with_colons && !mode)
1556     {
1557       es_fprintf (fp, "fpr:::::::::");
1558       for (i = 0; i < n; i++, p++)
1559         es_fprintf (fp, "%02X", *p);
1560       es_putc (':', fp);
1561     }
1562   else
1563     {
1564       tty_fprintf (fp, "%s", text);
1565       if (n == 20)
1566         {
1567           for (i = 0; i < n; i++, i++, p += 2)
1568             tty_fprintf (fp, "%s %02X%02X", i==10? " ":"", *p, p[1]);
1569         }
1570       else
1571         {
1572           for (i = 0; i < n; i++, p++)
1573             tty_fprintf (fp, "%s %02X", (i && !(i % 8))? " ":"", *p);
1574         }
1575     }
1576   tty_fprintf (fp, "\n");
1577 }
1578
1579 /* Print the serial number of an OpenPGP card if available.  */
1580 static void
1581 print_card_serialno (const char *serialno)
1582 {
1583   if (!serialno)
1584     return;
1585   if (opt.with_colons)
1586     return; /* Handled elsewhere. */
1587
1588   es_fputs (_("      Card serial no. ="), es_stdout);
1589   es_putc (' ', es_stdout);
1590   if (strlen (serialno) == 32 && !strncmp (serialno, "D27600012401", 12))
1591     {
1592       /* This is an OpenPGP card.  Print the relevant part.  */
1593       /* Example: D2760001240101010001000003470000 */
1594       /*                          xxxxyyyyyyyy     */
1595       es_fprintf (es_stdout, "%.*s %.*s", 4, serialno+16, 8, serialno+20);
1596     }
1597  else
1598    es_fputs (serialno, es_stdout);
1599   es_putc ('\n', es_stdout);
1600 }
1601
1602
1603
1604 void
1605 set_attrib_fd (int fd)
1606 {
1607   static int last_fd = -1;
1608
1609   if (fd != -1 && last_fd == fd)
1610     return;
1611
1612   /* Fixme: Do we need to check for the log stream here?  */
1613   if (attrib_fp && attrib_fp != log_get_stream ())
1614     es_fclose (attrib_fp);
1615   attrib_fp = NULL;
1616   if (fd == -1)
1617     return;
1618
1619 #ifdef HAVE_DOSISH_SYSTEM
1620   setmode (fd, O_BINARY);
1621 #endif
1622   if (fd == 1)
1623     attrib_fp = es_stdout;
1624   else if (fd == 2)
1625     attrib_fp = es_stderr;
1626   else
1627     attrib_fp = es_fdopen (fd, "wb");
1628   if (!attrib_fp)
1629     {
1630       log_fatal ("can't open fd %d for attribute output: %s\n",
1631                  fd, strerror (errno));
1632     }
1633
1634   last_fd = fd;
1635 }