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