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