Imported Upstream version 2.2.12
[platform/upstream/gpg2.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  * Copyright (C) 2013, 2014  Werner Koch
5  *
6  * This file is part of GnuPG.
7  *
8  * GnuPG is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * GnuPG is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, see <https://www.gnu.org/licenses/>.
20  */
21
22 #include <config.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <errno.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 "../common/status.h"
35 #include "keydb.h"
36 #include "photoid.h"
37 #include "../common/util.h"
38 #include "../common/ttyio.h"
39 #include "trustdb.h"
40 #include "main.h"
41 #include "../common/i18n.h"
42 #include "../common/status.h"
43 #include "call-agent.h"
44 #include "../common/mbox-util.h"
45 #include "../common/zb32.h"
46 #include "tofu.h"
47 #include "../common/compliance.h"
48
49
50 static void list_all (ctrl_t, int, int);
51 static void list_one (ctrl_t ctrl,
52                       strlist_t names, int secret, int mark_secret);
53 static void locate_one (ctrl_t ctrl, strlist_t names);
54 static void print_card_serialno (const char *serialno);
55
56 struct keylist_context
57 {
58   int check_sigs;  /* If set signatures shall be verified.  */
59   int good_sigs;   /* Counter used if CHECK_SIGS is set.  */
60   int inv_sigs;    /* Counter used if CHECK_SIGS is set.  */
61   int no_key;      /* Counter used if CHECK_SIGS is set.  */
62   int oth_err;     /* Counter used if CHECK_SIGS is set.  */
63   int no_validity; /* Do not show validity.  */
64 };
65
66
67 static void list_keyblock (ctrl_t ctrl,
68                            kbnode_t keyblock, int secret, int has_secret,
69                            int fpr, struct keylist_context *listctx);
70
71
72 /* The stream used to write attribute packets to.  */
73 static estream_t attrib_fp;
74
75
76 /* Release resources from a keylist context.  */
77 static void
78 keylist_context_release (struct keylist_context *listctx)
79 {
80   (void)listctx; /* Nothing to release.  */
81 }
82
83
84 /* List the keys.  If list is NULL, all available keys are listed.
85    With LOCATE_MODE set the locate algorithm is used to find a
86    key.  */
87 void
88 public_key_list (ctrl_t ctrl, strlist_t list, int locate_mode)
89 {
90 #ifndef NO_TRUST_MODELS
91   if (opt.with_colons)
92     {
93       byte trust_model, marginals, completes, cert_depth, min_cert_level;
94       ulong created, nextcheck;
95
96       read_trust_options (ctrl, &trust_model, &created, &nextcheck,
97                           &marginals, &completes, &cert_depth, &min_cert_level);
98
99       es_fprintf (es_stdout, "tru:");
100
101       if (nextcheck && nextcheck <= make_timestamp ())
102         es_fprintf (es_stdout, "o");
103       if (trust_model != opt.trust_model)
104         es_fprintf (es_stdout, "t");
105       if (opt.trust_model == TM_PGP || opt.trust_model == TM_CLASSIC
106           || opt.trust_model == TM_TOFU_PGP)
107         {
108           if (marginals != opt.marginals_needed)
109             es_fprintf (es_stdout, "m");
110           if (completes != opt.completes_needed)
111             es_fprintf (es_stdout, "c");
112           if (cert_depth != opt.max_cert_depth)
113             es_fprintf (es_stdout, "d");
114           if (min_cert_level != opt.min_cert_level)
115             es_fprintf (es_stdout, "l");
116         }
117
118       es_fprintf (es_stdout, ":%d:%lu:%lu", trust_model, created, nextcheck);
119
120       /* Only show marginals, completes, and cert_depth in the classic
121          or PGP trust models since they are not meaningful
122          otherwise. */
123
124       if (trust_model == TM_PGP || trust_model == TM_CLASSIC)
125         es_fprintf (es_stdout, ":%d:%d:%d", marginals, completes, cert_depth);
126       es_fprintf (es_stdout, "\n");
127     }
128 #endif /*!NO_TRUST_MODELS*/
129
130   /* We need to do the stale check right here because it might need to
131      update the keyring while we already have the keyring open.  This
132      is very bad for W32 because of a sharing violation. For real OSes
133      it might lead to false results if we are later listing a keyring
134      which is associated with the inode of a deleted file.  */
135   check_trustdb_stale (ctrl);
136
137 #ifdef USE_TOFU
138   tofu_begin_batch_update (ctrl);
139 #endif
140
141   if (locate_mode)
142     locate_one (ctrl, list);
143   else if (!list)
144     list_all (ctrl, 0, opt.with_secret);
145   else
146     list_one (ctrl, list, 0, opt.with_secret);
147
148 #ifdef USE_TOFU
149   tofu_end_batch_update (ctrl);
150 #endif
151 }
152
153
154 void
155 secret_key_list (ctrl_t ctrl, strlist_t list)
156 {
157   (void)ctrl;
158
159   check_trustdb_stale (ctrl);
160
161   if (!list)
162     list_all (ctrl, 1, 0);
163   else                          /* List by user id */
164     list_one (ctrl, list, 1, 0);
165 }
166
167 char *
168 format_seckey_info (ctrl_t ctrl, PKT_public_key *pk)
169 {
170   u32 keyid[2];
171   char *p;
172   char pkstrbuf[PUBKEY_STRING_SIZE];
173   char *info;
174
175   keyid_from_pk (pk, keyid);
176   p = get_user_id_native (ctrl, keyid);
177
178   info = xtryasprintf ("sec  %s/%s %s %s",
179                        pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
180                        keystr (keyid), datestr_from_pk (pk), p);
181
182   xfree (p);
183
184   return info;
185 }
186
187 void
188 print_seckey_info (ctrl_t ctrl, PKT_public_key *pk)
189 {
190   char *p = format_seckey_info (ctrl, pk);
191   tty_printf ("\n%s\n", p);
192   xfree (p);
193 }
194
195 /* Print information about the public key.  With FP passed as NULL,
196    the tty output interface is used, otherwise output is directed to
197    the given stream.  */
198 void
199 print_pubkey_info (ctrl_t ctrl, estream_t fp, PKT_public_key *pk)
200 {
201   u32 keyid[2];
202   char *p;
203   char pkstrbuf[PUBKEY_STRING_SIZE];
204
205   keyid_from_pk (pk, keyid);
206
207   /* If the pk was chosen by a particular user ID, that is the one to
208      print.  */
209   if (pk->user_id)
210     p = utf8_to_native (pk->user_id->name, pk->user_id->len, 0);
211   else
212     p = get_user_id_native (ctrl, keyid);
213
214   if (!fp)
215     tty_printf ("\n");
216   tty_fprintf (fp, "%s  %s/%s %s %s\n",
217                pk->flags.primary? "pub":"sub",
218                pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
219                keystr (keyid), datestr_from_pk (pk), p);
220   xfree (p);
221 }
222
223
224 /* Print basic information of a secret key including the card serial
225    number information.  */
226 #ifdef ENABLE_CARD_SUPPORT
227 void
228 print_card_key_info (estream_t fp, kbnode_t keyblock)
229 {
230   kbnode_t node;
231   char *hexgrip;
232   char *serialno;
233   int s2k_char;
234   char pkstrbuf[PUBKEY_STRING_SIZE];
235   int indent;
236
237   for (node = keyblock; node; node = node->next)
238     {
239       if (node->pkt->pkttype == PKT_PUBLIC_KEY
240           || node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
241         {
242           int rc;
243           PKT_public_key *pk = node->pkt->pkt.public_key;
244
245           serialno = NULL;
246           rc = hexkeygrip_from_pk (pk, &hexgrip);
247           if (rc)
248             {
249               log_error ("error computing a keygrip: %s\n", gpg_strerror (rc));
250               s2k_char = '?';
251             }
252           else if (!agent_get_keyinfo (NULL, hexgrip, &serialno, NULL))
253             s2k_char = serialno? '>':' ';
254           else
255             s2k_char = '#';  /* Key not found.  */
256
257           tty_fprintf (fp, "%s%c  %s/%s  %n",
258                        node->pkt->pkttype == PKT_PUBLIC_KEY ? "sec" : "ssb",
259                        s2k_char,
260                        pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
261                        keystr_from_pk (pk),
262                        &indent);
263           tty_fprintf (fp, _("created: %s"), datestr_from_pk (pk));
264           tty_fprintf (fp, "  ");
265           tty_fprintf (fp, _("expires: %s"), expirestr_from_pk (pk));
266           if (serialno)
267             {
268               tty_fprintf (fp, "\n%*s%s", indent, "", _("card-no: "));
269               if (strlen (serialno) == 32
270                   && !strncmp (serialno, "D27600012401", 12))
271                 {
272                   /* This is an OpenPGP card.  Print the relevant part.  */
273                   /* Example: D2760001240101010001000003470000 */
274                   /*                          xxxxyyyyyyyy     */
275                   tty_fprintf (fp, "%.*s %.*s", 4, serialno+16, 8, serialno+20);
276                 }
277               else
278                 tty_fprintf (fp, "%s", serialno);
279             }
280           tty_fprintf (fp, "\n");
281           xfree (hexgrip);
282           xfree (serialno);
283         }
284     }
285 }
286 #endif /*ENABLE_CARD_SUPPORT*/
287
288
289 /* Flags = 0x01 hashed 0x02 critical.  */
290 static void
291 status_one_subpacket (sigsubpkttype_t type, size_t len, int flags,
292                       const byte * buf)
293 {
294   char status[40];
295
296   /* Don't print these. */
297   if (len > 256)
298     return;
299
300   snprintf (status, sizeof status,
301             "%d %u %u ", type, flags, (unsigned int) len);
302
303   write_status_text_and_buffer (STATUS_SIG_SUBPACKET, status, buf, len, 0);
304 }
305
306
307 /* Print a policy URL.  Allowed values for MODE are:
308  *  -1 - print to the TTY
309  *   0 - print to stdout.
310  *   1 - use log_info and emit status messages.
311  *   2 - emit only status messages.
312  */
313 void
314 show_policy_url (PKT_signature * sig, int indent, int mode)
315 {
316   const byte *p;
317   size_t len;
318   int seq = 0, crit;
319   estream_t fp = mode < 0? NULL : mode ? log_get_stream () : es_stdout;
320
321   while ((p =
322           enum_sig_subpkt (sig->hashed, SIGSUBPKT_POLICY, &len, &seq, &crit)))
323     {
324       if (mode != 2)
325         {
326           const char *str;
327
328           tty_fprintf (fp, "%*s", indent, "");
329
330           if (crit)
331             str = _("Critical signature policy: ");
332           else
333             str = _("Signature policy: ");
334           if (mode > 0)
335             log_info ("%s", str);
336           else
337             tty_fprintf (fp, "%s", str);
338           tty_print_utf8_string2 (fp, p, len, 0);
339           tty_fprintf (fp, "\n");
340         }
341
342       if (mode > 0)
343         write_status_buffer (STATUS_POLICY_URL, p, len, 0);
344     }
345 }
346
347
348 /* Print a keyserver URL.  Allowed values for MODE are:
349  *  -1 - print to the TTY
350  *   0 - print to stdout.
351  *   1 - use log_info and emit status messages.
352  *   2 - emit only status messages.
353  */
354 void
355 show_keyserver_url (PKT_signature * sig, int indent, int mode)
356 {
357   const byte *p;
358   size_t len;
359   int seq = 0, crit;
360   estream_t fp = mode < 0? NULL : mode ? log_get_stream () : es_stdout;
361
362   while ((p =
363           enum_sig_subpkt (sig->hashed, SIGSUBPKT_PREF_KS, &len, &seq,
364                            &crit)))
365     {
366       if (mode != 2)
367         {
368           const char *str;
369
370           tty_fprintf (fp, "%*s", indent, "");
371
372           if (crit)
373             str = _("Critical preferred keyserver: ");
374           else
375             str = _("Preferred keyserver: ");
376           if (mode > 0)
377             log_info ("%s", str);
378           else
379             tty_fprintf (fp, "%s", str);
380           tty_print_utf8_string2 (fp, p, len, 0);
381           tty_fprintf (fp, "\n");
382         }
383
384       if (mode > 0)
385         status_one_subpacket (SIGSUBPKT_PREF_KS, len,
386                               (crit ? 0x02 : 0) | 0x01, p);
387     }
388 }
389
390
391 /* Print notation data.  Allowed values for MODE are:
392  *  -1 - print to the TTY
393  *   0 - print to stdout.
394  *   1 - use log_info and emit status messages.
395  *   2 - emit only status messages.
396  *
397  * Defined bits in WHICH:
398  *   1 - standard notations
399  *   2 - user notations
400  */
401 void
402 show_notation (PKT_signature * sig, int indent, int mode, int which)
403 {
404   estream_t fp = mode < 0? NULL : mode ? log_get_stream () : es_stdout;
405   notation_t nd, notations;
406
407   if (which == 0)
408     which = 3;
409
410   notations = sig_to_notation (sig);
411
412   /* There may be multiple notations in the same sig. */
413   for (nd = notations; nd; nd = nd->next)
414     {
415       if (mode != 2)
416         {
417           int has_at = !!strchr (nd->name, '@');
418
419           if ((which & 1 && !has_at) || (which & 2 && has_at))
420             {
421               const char *str;
422
423               tty_fprintf (fp, "%*s", indent, "");
424
425               if (nd->flags.critical)
426                 str = _("Critical signature notation: ");
427               else
428                 str = _("Signature notation: ");
429               if (mode > 0)
430                 log_info ("%s", str);
431               else
432                 tty_fprintf (fp, "%s", str);
433               /* This is all UTF8 */
434               tty_print_utf8_string2 (fp, nd->name, strlen (nd->name), 0);
435               tty_fprintf (fp, "=");
436               tty_print_utf8_string2 (fp, nd->value, strlen (nd->value), 0);
437               /* (We need to use log_printf so that the next call to a
438                   log function does not insert an extra LF.)  */
439               if (mode > 0)
440                 log_printf ("\n");
441               else
442                 tty_fprintf (fp, "\n");
443             }
444         }
445
446       if (mode > 0)
447         {
448           write_status_buffer (STATUS_NOTATION_NAME,
449                                nd->name, strlen (nd->name), 0);
450           if (nd->flags.critical || nd->flags.human)
451             write_status_text (STATUS_NOTATION_FLAGS,
452                                nd->flags.critical && nd->flags.human? "1 1" :
453                                nd->flags.critical? "1 0" : "0 1");
454           write_status_buffer (STATUS_NOTATION_DATA,
455                                nd->value, strlen (nd->value), 50);
456         }
457     }
458
459   free_notation (notations);
460 }
461
462
463 static void
464 print_signature_stats (struct keylist_context *s)
465 {
466   if (!s->check_sigs)
467     return;  /* Signature checking was not requested.  */
468
469   /* Better flush stdout so that the stats are always printed after
470    * the output.  */
471   es_fflush (es_stdout);
472
473   if (s->good_sigs)
474     log_info (ngettext("%d good signature\n",
475                        "%d good signatures\n", s->good_sigs), s->good_sigs);
476
477   if (s->inv_sigs)
478     log_info (ngettext("%d bad signature\n",
479                        "%d bad signatures\n", s->inv_sigs), s->inv_sigs);
480
481   if (s->no_key)
482     log_info (ngettext("%d signature not checked due to a missing key\n",
483                        "%d signatures not checked due to missing keys\n",
484                        s->no_key), s->no_key);
485
486   if (s->oth_err)
487     log_info (ngettext("%d signature not checked due to an error\n",
488                        "%d signatures not checked due to errors\n",
489                        s->oth_err), s->oth_err);
490 }
491
492
493 /* List all keys.  If SECRET is true only secret keys are listed.  If
494    MARK_SECRET is true secret keys are indicated in a public key
495    listing.  */
496 static void
497 list_all (ctrl_t ctrl, int secret, int mark_secret)
498 {
499   KEYDB_HANDLE hd;
500   KBNODE keyblock = NULL;
501   int rc = 0;
502   int any_secret;
503   const char *lastresname, *resname;
504   struct keylist_context listctx;
505
506   memset (&listctx, 0, sizeof (listctx));
507   if (opt.check_sigs)
508     listctx.check_sigs = 1;
509
510   hd = keydb_new ();
511   if (!hd)
512     rc = gpg_error_from_syserror ();
513   else
514     rc = keydb_search_first (hd);
515   if (rc)
516     {
517       if (gpg_err_code (rc) != GPG_ERR_NOT_FOUND)
518         log_error ("keydb_search_first failed: %s\n", gpg_strerror (rc));
519       goto leave;
520     }
521
522   lastresname = NULL;
523   do
524     {
525       rc = keydb_get_keyblock (hd, &keyblock);
526       if (rc)
527         {
528           if (gpg_err_code (rc) == GPG_ERR_LEGACY_KEY)
529             continue;  /* Skip legacy keys.  */
530           log_error ("keydb_get_keyblock failed: %s\n", gpg_strerror (rc));
531           goto leave;
532         }
533
534       if (secret || mark_secret)
535         any_secret = !agent_probe_any_secret_key (NULL, keyblock);
536       else
537         any_secret = 0;
538
539       if (secret && !any_secret)
540         ; /* Secret key listing requested but this isn't one.  */
541       else
542         {
543           if (!opt.with_colons && !(opt.list_options & LIST_SHOW_ONLY_FPR_MBOX))
544             {
545               resname = keydb_get_resource_name (hd);
546               if (lastresname != resname)
547                 {
548                   int i;
549
550                   es_fprintf (es_stdout, "%s\n", resname);
551                   for (i = strlen (resname); i; i--)
552                     es_putc ('-', es_stdout);
553                   es_putc ('\n', es_stdout);
554                   lastresname = resname;
555                 }
556             }
557           merge_keys_and_selfsig (ctrl, keyblock);
558           list_keyblock (ctrl, keyblock, secret, any_secret, opt.fingerprint,
559                          &listctx);
560         }
561       release_kbnode (keyblock);
562       keyblock = NULL;
563     }
564   while (!(rc = keydb_search_next (hd)));
565   es_fflush (es_stdout);
566   if (rc && gpg_err_code (rc) != GPG_ERR_NOT_FOUND)
567     log_error ("keydb_search_next failed: %s\n", gpg_strerror (rc));
568   if (keydb_get_skipped_counter (hd))
569     log_info (ngettext("Warning: %lu key skipped due to its large size\n",
570                        "Warning: %lu keys skipped due to their large sizes\n",
571                        keydb_get_skipped_counter (hd)),
572               keydb_get_skipped_counter (hd));
573
574   if (opt.check_sigs && !opt.with_colons)
575     print_signature_stats (&listctx);
576
577  leave:
578   keylist_context_release (&listctx);
579   release_kbnode (keyblock);
580   keydb_release (hd);
581 }
582
583
584 static void
585 list_one (ctrl_t ctrl, strlist_t names, int secret, int mark_secret)
586 {
587   int rc = 0;
588   KBNODE keyblock = NULL;
589   GETKEY_CTX ctx;
590   const char *resname;
591   const char *keyring_str = _("Keyring");
592   int i;
593   struct keylist_context listctx;
594
595   memset (&listctx, 0, sizeof (listctx));
596   if (!secret && opt.check_sigs)
597     listctx.check_sigs = 1;
598
599   /* fixme: using the bynames function has the disadvantage that we
600    * don't know whether one of the names given was not found.  OTOH,
601    * this function has the advantage to list the names in the
602    * sequence as defined by the keyDB and does not duplicate
603    * outputs.  A solution could be do test whether all given have
604    * been listed (this needs a way to use the keyDB search
605    * functions) or to have the search function return indicators for
606    * found names.  Yet another way is to use the keydb search
607    * facilities directly. */
608   rc = getkey_bynames (ctrl, &ctx, NULL, names, secret, &keyblock);
609   if (rc)
610     {
611       log_error ("error reading key: %s\n", gpg_strerror (rc));
612       getkey_end (ctrl, ctx);
613       return;
614     }
615
616   do
617     {
618       if ((opt.list_options & LIST_SHOW_KEYRING) && !opt.with_colons)
619         {
620           resname = keydb_get_resource_name (get_ctx_handle (ctx));
621           es_fprintf (es_stdout, "%s: %s\n", keyring_str, resname);
622           for (i = strlen (resname) + strlen (keyring_str) + 2; i; i--)
623             es_putc ('-', es_stdout);
624           es_putc ('\n', es_stdout);
625         }
626       list_keyblock (ctrl,
627                      keyblock, secret, mark_secret, opt.fingerprint, &listctx);
628       release_kbnode (keyblock);
629     }
630   while (!getkey_next (ctrl, ctx, NULL, &keyblock));
631   getkey_end (ctrl, ctx);
632
633   if (opt.check_sigs && !opt.with_colons)
634     print_signature_stats (&listctx);
635
636   keylist_context_release (&listctx);
637 }
638
639
640 static void
641 locate_one (ctrl_t ctrl, strlist_t names)
642 {
643   int rc = 0;
644   strlist_t sl;
645   GETKEY_CTX ctx = NULL;
646   KBNODE keyblock = NULL;
647   struct keylist_context listctx;
648
649   memset (&listctx, 0, sizeof (listctx));
650   if (opt.check_sigs)
651     listctx.check_sigs = 1;
652
653   for (sl = names; sl; sl = sl->next)
654     {
655       rc = get_best_pubkey_byname (ctrl, &ctx, NULL, sl->d, &keyblock, 1);
656       if (rc)
657         {
658           if (gpg_err_code (rc) != GPG_ERR_NO_PUBKEY)
659             log_error ("error reading key: %s\n", gpg_strerror (rc));
660           else if (opt.verbose)
661             log_info (_("key \"%s\" not found: %s\n"),
662                       sl->d, gpg_strerror (rc));
663         }
664       else
665         {
666           do
667             {
668               list_keyblock (ctrl, keyblock, 0, 0, opt.fingerprint, &listctx);
669               release_kbnode (keyblock);
670             }
671           while (ctx && !getkey_next (ctrl, ctx, NULL, &keyblock));
672           getkey_end (ctrl, ctx);
673           ctx = NULL;
674         }
675     }
676
677   if (opt.check_sigs && !opt.with_colons)
678     print_signature_stats (&listctx);
679
680   keylist_context_release (&listctx);
681 }
682
683
684 static void
685 print_key_data (PKT_public_key * pk)
686 {
687   int n = pk ? pubkey_get_npkey (pk->pubkey_algo) : 0;
688   int i;
689
690   for (i = 0; i < n; i++)
691     {
692       es_fprintf (es_stdout, "pkd:%d:%u:", i, mpi_get_nbits (pk->pkey[i]));
693       mpi_print (es_stdout, pk->pkey[i], 1);
694       es_putc (':', es_stdout);
695       es_putc ('\n', es_stdout);
696     }
697 }
698
699 static void
700 print_capabilities (ctrl_t ctrl, PKT_public_key *pk, KBNODE keyblock)
701 {
702   unsigned int use = pk->pubkey_usage;
703   int c_printed = 0;
704
705   if (use & PUBKEY_USAGE_ENC)
706     es_putc ('e', es_stdout);
707
708   if (use & PUBKEY_USAGE_SIG)
709     {
710       es_putc ('s', es_stdout);
711       if (pk->flags.primary)
712         {
713           es_putc ('c', es_stdout);
714           /* The PUBKEY_USAGE_CERT flag was introduced later and we
715              used to always print 'c' for a primary key.  To avoid any
716              regression here we better track whether we printed 'c'
717              already.  */
718           c_printed = 1;
719         }
720     }
721
722   if ((use & PUBKEY_USAGE_CERT) && !c_printed)
723     es_putc ('c', es_stdout);
724
725   if ((use & PUBKEY_USAGE_AUTH))
726     es_putc ('a', es_stdout);
727
728   if ((use & PUBKEY_USAGE_UNKNOWN))
729     es_putc ('?', es_stdout);
730
731   if (keyblock)
732     {
733       /* Figure out the usable capabilities.  */
734       KBNODE k;
735       int enc = 0, sign = 0, cert = 0, auth = 0, disabled = 0;
736
737       for (k = keyblock; k; k = k->next)
738         {
739           if (k->pkt->pkttype == PKT_PUBLIC_KEY
740               || k->pkt->pkttype == PKT_PUBLIC_SUBKEY)
741             {
742               pk = k->pkt->pkt.public_key;
743
744               if (pk->flags.primary)
745                 disabled = pk_is_disabled (pk);
746
747               if (pk->flags.valid && !pk->flags.revoked && !pk->has_expired)
748                 {
749                   if (pk->pubkey_usage & PUBKEY_USAGE_ENC)
750                     enc = 1;
751                   if (pk->pubkey_usage & PUBKEY_USAGE_SIG)
752                     {
753                       sign = 1;
754                       if (pk->flags.primary)
755                         cert = 1;
756                     }
757                   if (pk->pubkey_usage & PUBKEY_USAGE_CERT)
758                     cert = 1;
759                   if ((pk->pubkey_usage & PUBKEY_USAGE_AUTH))
760                     auth = 1;
761                 }
762             }
763         }
764       if (enc)
765         es_putc ('E', es_stdout);
766       if (sign)
767         es_putc ('S', es_stdout);
768       if (cert)
769         es_putc ('C', es_stdout);
770       if (auth)
771         es_putc ('A', es_stdout);
772       if (disabled)
773         es_putc ('D', es_stdout);
774     }
775
776   es_putc (':', es_stdout);
777 }
778
779
780 /* FLAGS: 0x01 hashed
781           0x02 critical  */
782 static void
783 print_one_subpacket (sigsubpkttype_t type, size_t len, int flags,
784                      const byte * buf)
785 {
786   size_t i;
787
788   es_fprintf (es_stdout, "spk:%d:%u:%u:", type, flags, (unsigned int) len);
789
790   for (i = 0; i < len; i++)
791     {
792       /* printable ascii other than : and % */
793       if (buf[i] >= 32 && buf[i] <= 126 && buf[i] != ':' && buf[i] != '%')
794         es_fprintf (es_stdout, "%c", buf[i]);
795       else
796         es_fprintf (es_stdout, "%%%02X", buf[i]);
797     }
798
799   es_fprintf (es_stdout, "\n");
800 }
801
802
803 void
804 print_subpackets_colon (PKT_signature * sig)
805 {
806   byte *i;
807
808   log_assert (opt.show_subpackets);
809
810   for (i = opt.show_subpackets; *i; i++)
811     {
812       const byte *p;
813       size_t len;
814       int seq, crit;
815
816       seq = 0;
817
818       while ((p = enum_sig_subpkt (sig->hashed, *i, &len, &seq, &crit)))
819         print_one_subpacket (*i, len, 0x01 | (crit ? 0x02 : 0), p);
820
821       seq = 0;
822
823       while ((p = enum_sig_subpkt (sig->unhashed, *i, &len, &seq, &crit)))
824         print_one_subpacket (*i, len, 0x00 | (crit ? 0x02 : 0), p);
825     }
826 }
827
828
829 void
830 dump_attribs (const PKT_user_id *uid, PKT_public_key *pk)
831 {
832   int i;
833
834   if (!attrib_fp)
835     return;
836
837   for (i = 0; i < uid->numattribs; i++)
838     {
839       if (is_status_enabled ())
840         {
841           byte array[MAX_FINGERPRINT_LEN], *p;
842           char buf[(MAX_FINGERPRINT_LEN * 2) + 90];
843           size_t j, n;
844
845           if (!pk)
846             BUG ();
847           fingerprint_from_pk (pk, array, &n);
848
849           p = array;
850           for (j = 0; j < n; j++, p++)
851             sprintf (buf + 2 * j, "%02X", *p);
852
853           sprintf (buf + strlen (buf), " %lu %u %u %u %lu %lu %u",
854                    (ulong) uid->attribs[i].len, uid->attribs[i].type, i + 1,
855                    uid->numattribs, (ulong) uid->created,
856                    (ulong) uid->expiredate,
857                    ((uid->flags.primary ? 0x01 : 0) | (uid->flags.revoked ? 0x02 : 0) |
858                     (uid->flags.expired ? 0x04 : 0)));
859           write_status_text (STATUS_ATTRIBUTE, buf);
860         }
861
862       es_fwrite (uid->attribs[i].data, uid->attribs[i].len, 1, attrib_fp);
863       es_fflush (attrib_fp);
864     }
865 }
866
867
868 static void
869 list_keyblock_print (ctrl_t ctrl, kbnode_t keyblock, int secret, int fpr,
870                      struct keylist_context *listctx)
871 {
872   int rc;
873   KBNODE kbctx;
874   KBNODE node;
875   PKT_public_key *pk;
876   int skip_sigs = 0;
877   char *hexgrip = NULL;
878   char *serialno = NULL;
879
880   /* Get the keyid from the keyblock.  */
881   node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
882   if (!node)
883     {
884       log_error ("Oops; key lost!\n");
885       dump_kbnode (keyblock);
886       return;
887     }
888
889   pk = node->pkt->pkt.public_key;
890
891   if (secret || opt.with_keygrip)
892     {
893       rc = hexkeygrip_from_pk (pk, &hexgrip);
894       if (rc)
895         log_error ("error computing a keygrip: %s\n", gpg_strerror (rc));
896     }
897
898   if (secret)
899     {
900       /* Encode some info about the secret key in SECRET.  */
901       if (!agent_get_keyinfo (NULL, hexgrip, &serialno, NULL))
902         secret = serialno? 3 : 1;
903       else
904         secret = 2;  /* Key not found.  */
905     }
906
907   if (!listctx->no_validity)
908     check_trustdb_stale (ctrl);
909
910   /* Print the "pub" line and in KF_NONE mode the fingerprint.  */
911   print_key_line (ctrl, es_stdout, pk, secret);
912
913   if (fpr)
914     print_fingerprint (ctrl, NULL, pk, 0);
915
916   if (opt.with_keygrip && hexgrip)
917     es_fprintf (es_stdout, "      Keygrip = %s\n", hexgrip);
918
919   if (serialno)
920     print_card_serialno (serialno);
921
922   if (opt.with_key_data)
923     print_key_data (pk);
924
925   if (opt.with_key_origin
926       && (pk->keyorg || pk->keyupdate || pk->updateurl))
927     {
928       char updatestr[MK_DATESTR_SIZE];
929
930       es_fprintf (es_stdout, "      origin=%s last=%s %s",
931                   key_origin_string (pk->keyorg),
932                   mk_datestr (updatestr, sizeof updatestr, pk->keyupdate),
933                   pk->updateurl? "url=":"");
934       if (pk->updateurl)
935         print_utf8_string (es_stdout, pk->updateurl);
936       es_putc ('\n', es_stdout);
937     }
938
939
940   for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0));)
941     {
942       if (node->pkt->pkttype == PKT_USER_ID)
943         {
944           PKT_user_id *uid = node->pkt->pkt.user_id;
945           int indent;
946           int kl = opt.keyid_format == KF_NONE? 10 : keystrlen ();
947
948           if ((uid->flags.expired || uid->flags.revoked)
949               && !(opt.list_options & LIST_SHOW_UNUSABLE_UIDS))
950             {
951               skip_sigs = 1;
952               continue;
953             }
954           else
955             skip_sigs = 0;
956
957           if (attrib_fp && uid->attrib_data != NULL)
958             dump_attribs (uid, pk);
959
960           if ((uid->flags.revoked || uid->flags.expired)
961               || ((opt.list_options & LIST_SHOW_UID_VALIDITY)
962                   && !listctx->no_validity))
963             {
964               const char *validity;
965
966               validity = uid_trust_string_fixed (ctrl, pk, uid);
967               indent = ((kl + (opt.legacy_list_mode? 9:11))
968                         - atoi (uid_trust_string_fixed (ctrl, NULL, NULL)));
969               if (indent < 0 || indent > 40)
970                 indent = 0;
971
972               es_fprintf (es_stdout, "uid%*s%s ", indent, "", validity);
973             }
974           else
975             {
976               indent = kl + (opt.legacy_list_mode? 10:12);
977               es_fprintf (es_stdout, "uid%*s", indent, "");
978             }
979
980           print_utf8_buffer (es_stdout, uid->name, uid->len);
981           es_putc ('\n', es_stdout);
982
983           if (opt.with_wkd_hash)
984             {
985               char *mbox, *hash, *p;
986               char hashbuf[32];
987
988               mbox = mailbox_from_userid (uid->name);
989               if (mbox && (p = strchr (mbox, '@')))
990                 {
991                   *p++ = 0;
992                   gcry_md_hash_buffer (GCRY_MD_SHA1, hashbuf,
993                                        mbox, strlen (mbox));
994                   hash = zb32_encode (hashbuf, 8*20);
995                   if (hash)
996                     {
997                       es_fprintf (es_stdout, "   %*s%s@%s\n",
998                                   indent, "", hash, p);
999                       xfree (hash);
1000                     }
1001                 }
1002               xfree (mbox);
1003             }
1004
1005           if (opt.with_key_origin
1006               && (uid->keyorg || uid->keyupdate || uid->updateurl))
1007             {
1008               char updatestr[MK_DATESTR_SIZE];
1009
1010               es_fprintf (es_stdout, "   %*sorigin=%s last=%s %s",
1011                           indent, "",
1012                           key_origin_string (uid->keyorg),
1013                           mk_datestr (updatestr, sizeof updatestr,
1014                                       uid->keyupdate),
1015                           uid->updateurl? "url=":"");
1016               if (uid->updateurl)
1017                 print_utf8_string (es_stdout, uid->updateurl);
1018               es_putc ('\n', es_stdout);
1019             }
1020
1021           if ((opt.list_options & LIST_SHOW_PHOTOS) && uid->attribs != NULL)
1022             show_photos (ctrl, uid->attribs, uid->numattribs, pk, uid);
1023         }
1024       else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
1025         {
1026           PKT_public_key *pk2 = node->pkt->pkt.public_key;
1027
1028           if ((pk2->flags.revoked || pk2->has_expired)
1029               && !(opt.list_options & LIST_SHOW_UNUSABLE_SUBKEYS))
1030             {
1031               skip_sigs = 1;
1032               continue;
1033             }
1034           else
1035             skip_sigs = 0;
1036
1037           xfree (serialno); serialno = NULL;
1038           xfree (hexgrip); hexgrip = NULL;
1039           if (secret || opt.with_keygrip)
1040             {
1041               rc = hexkeygrip_from_pk (pk2, &hexgrip);
1042               if (rc)
1043                 log_error ("error computing a keygrip: %s\n",
1044                            gpg_strerror (rc));
1045             }
1046           if (secret)
1047             {
1048               if (!agent_get_keyinfo (NULL, hexgrip, &serialno, NULL))
1049                 secret = serialno? 3 : 1;
1050               else
1051                 secret = 2;  /* Key not found.  */
1052             }
1053
1054           /* Print the "sub" line.  */
1055           print_key_line (ctrl, es_stdout, pk2, secret);
1056           if (fpr > 1 || opt.with_subkey_fingerprint)
1057             {
1058               print_fingerprint (ctrl, NULL, pk2, 0);
1059               if (serialno)
1060                 print_card_serialno (serialno);
1061             }
1062           if (opt.with_keygrip && hexgrip)
1063             es_fprintf (es_stdout, "      Keygrip = %s\n", hexgrip);
1064           if (opt.with_key_data)
1065             print_key_data (pk2);
1066         }
1067       else if (opt.list_sigs
1068                && node->pkt->pkttype == PKT_SIGNATURE && !skip_sigs)
1069         {
1070           PKT_signature *sig = node->pkt->pkt.signature;
1071           int sigrc;
1072           char *sigstr;
1073           char *reason_text = NULL;
1074           char *reason_comment = NULL;
1075           size_t reason_commentlen;
1076
1077           if (listctx->check_sigs)
1078             {
1079               rc = check_key_signature (ctrl, keyblock, node, NULL);
1080               switch (gpg_err_code (rc))
1081                 {
1082                 case 0:
1083                   listctx->good_sigs++;
1084                   sigrc = '!';
1085                   break;
1086                 case GPG_ERR_BAD_SIGNATURE:
1087                   listctx->inv_sigs++;
1088                   sigrc = '-';
1089                   break;
1090                 case GPG_ERR_NO_PUBKEY:
1091                 case GPG_ERR_UNUSABLE_PUBKEY:
1092                   listctx->no_key++;
1093                   continue;
1094                 default:
1095                   listctx->oth_err++;
1096                   sigrc = '%';
1097                   break;
1098                 }
1099
1100               /* TODO: Make sure a cached sig record here still has
1101                  the pk that issued it.  See also
1102                  keyedit.c:print_and_check_one_sig */
1103             }
1104           else
1105             {
1106               rc = 0;
1107               sigrc = ' ';
1108             }
1109
1110           if (sig->sig_class == 0x20 || sig->sig_class == 0x28
1111               || sig->sig_class == 0x30)
1112             {
1113               sigstr = "rev";
1114               get_revocation_reason (sig, &reason_text,
1115                                      &reason_comment, &reason_commentlen);
1116             }
1117           else if ((sig->sig_class & ~3) == 0x10)
1118             sigstr = "sig";
1119           else if (sig->sig_class == 0x18)
1120             sigstr = "sig";
1121           else if (sig->sig_class == 0x1F)
1122             sigstr = "sig";
1123           else
1124             {
1125               es_fprintf (es_stdout, "sig                             "
1126                       "[unexpected signature class 0x%02x]\n",
1127                       sig->sig_class);
1128               continue;
1129             }
1130
1131           es_fputs (sigstr, es_stdout);
1132           es_fprintf (es_stdout, "%c%c %c%c%c%c%c%c %s %s",
1133                   sigrc, (sig->sig_class - 0x10 > 0 &&
1134                           sig->sig_class - 0x10 <
1135                           4) ? '0' + sig->sig_class - 0x10 : ' ',
1136                   sig->flags.exportable ? ' ' : 'L',
1137                   sig->flags.revocable ? ' ' : 'R',
1138                   sig->flags.policy_url ? 'P' : ' ',
1139                   sig->flags.notation ? 'N' : ' ',
1140                   sig->flags.expired ? 'X' : ' ',
1141                   (sig->trust_depth > 9) ? 'T' : (sig->trust_depth >
1142                                                   0) ? '0' +
1143                   sig->trust_depth : ' ', keystr (sig->keyid),
1144                   datestr_from_sig (sig));
1145           if (opt.list_options & LIST_SHOW_SIG_EXPIRE)
1146             es_fprintf (es_stdout, " %s", expirestr_from_sig (sig));
1147           es_fprintf (es_stdout, "  ");
1148           if (sigrc == '%')
1149             es_fprintf (es_stdout, "[%s] ", gpg_strerror (rc));
1150           else if (sigrc == '?')
1151             ;
1152           else if (!opt.fast_list_mode)
1153             {
1154               size_t n;
1155               char *p = get_user_id (ctrl, sig->keyid, &n, NULL);
1156               print_utf8_buffer (es_stdout, p, n);
1157               xfree (p);
1158             }
1159           es_putc ('\n', es_stdout);
1160
1161           if (sig->flags.policy_url
1162               && (opt.list_options & LIST_SHOW_POLICY_URLS))
1163             show_policy_url (sig, 3, 0);
1164
1165           if (sig->flags.notation && (opt.list_options & LIST_SHOW_NOTATIONS))
1166             show_notation (sig, 3, 0,
1167                            ((opt.
1168                              list_options & LIST_SHOW_STD_NOTATIONS) ? 1 : 0)
1169                            +
1170                            ((opt.
1171                              list_options & LIST_SHOW_USER_NOTATIONS) ? 2 :
1172                             0));
1173
1174           if (sig->flags.pref_ks
1175               && (opt.list_options & LIST_SHOW_KEYSERVER_URLS))
1176             show_keyserver_url (sig, 3, 0);
1177
1178           if (reason_text)
1179             {
1180               es_fprintf (es_stdout, "      %s%s\n",
1181                           _("reason for revocation: "), reason_text);
1182               if (reason_comment)
1183                 {
1184                   const byte *s, *s_lf;
1185                   size_t n, n_lf;
1186
1187                   s = reason_comment;
1188                   n = reason_commentlen;
1189                   s_lf = NULL;
1190                   do
1191                     {
1192                       /* We don't want any empty lines, so we skip them.  */
1193                       for (;n && *s == '\n'; s++, n--)
1194                         ;
1195                       if (n)
1196                         {
1197                           s_lf = memchr (s, '\n', n);
1198                           n_lf = s_lf? s_lf - s : n;
1199                           es_fprintf (es_stdout, "         %s",
1200                                       _("revocation comment: "));
1201                           es_write_sanitized (es_stdout, s, n_lf, NULL, NULL);
1202                           es_putc ('\n', es_stdout);
1203                           s += n_lf; n -= n_lf;
1204                         }
1205                     } while (s_lf);
1206                 }
1207             }
1208
1209           xfree (reason_text);
1210           xfree (reason_comment);
1211
1212           /* fixme: check or list other sigs here */
1213         }
1214     }
1215   es_putc ('\n', es_stdout);
1216   xfree (serialno);
1217   xfree (hexgrip);
1218 }
1219
1220
1221 /* Do a simple key listing printing only the fingerprint and the mail
1222  * address of valid keys.  */
1223 static void
1224 list_keyblock_simple (ctrl_t ctrl, kbnode_t keyblock)
1225 {
1226   gpg_err_code_t ec;
1227   kbnode_t kbctx;
1228   kbnode_t node;
1229   char hexfpr[2*MAX_FINGERPRINT_LEN+1];
1230   char *mbox;
1231
1232   (void)ctrl;
1233
1234   node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
1235   if (!node)
1236     {
1237       log_error ("Oops; key lost!\n");
1238       dump_kbnode (keyblock);
1239       return;
1240     }
1241   hexfingerprint (node->pkt->pkt.public_key, hexfpr, sizeof hexfpr);
1242
1243   for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0));)
1244     {
1245       if (node->pkt->pkttype == PKT_USER_ID)
1246         {
1247           PKT_user_id *uid = node->pkt->pkt.user_id;
1248
1249           if (uid->attrib_data)
1250             continue;
1251
1252           if (uid->flags.expired || uid->flags.revoked)
1253             continue;
1254
1255           mbox = mailbox_from_userid (uid->name);
1256           if (!mbox)
1257             {
1258               ec = gpg_err_code_from_syserror ();
1259               if (ec != GPG_ERR_EINVAL)
1260                 log_error ("error getting mailbox from user-id: %s\n",
1261                            gpg_strerror (ec));
1262               continue;
1263             }
1264           es_fprintf (es_stdout, "%s %s\n", hexfpr, mbox);
1265           xfree (mbox);
1266         }
1267     }
1268 }
1269
1270
1271 void
1272 print_revokers (estream_t fp, PKT_public_key * pk)
1273 {
1274   /* print the revoker record */
1275   if (!pk->revkey && pk->numrevkeys)
1276     BUG ();
1277   else
1278     {
1279       int i, j;
1280
1281       for (i = 0; i < pk->numrevkeys; i++)
1282         {
1283           byte *p;
1284
1285           es_fprintf (fp, "rvk:::%d::::::", pk->revkey[i].algid);
1286           p = pk->revkey[i].fpr;
1287           for (j = 0; j < 20; j++, p++)
1288             es_fprintf (fp, "%02X", *p);
1289           es_fprintf (fp, ":%02x%s:\n",
1290                       pk->revkey[i].class,
1291                       (pk->revkey[i].class & 0x40) ? "s" : "");
1292         }
1293     }
1294 }
1295
1296
1297 /* Print the compliance flags to field 18.  PK is the public key.
1298  * KEYLENGTH is the length of the key in bits and CURVENAME is either
1299  * NULL or the name of the curve.  The latter two args are here
1300  * merely because the caller has already computed them.  */
1301 static void
1302 print_compliance_flags (PKT_public_key *pk,
1303                         unsigned int keylength, const char *curvename)
1304 {
1305   int any = 0;
1306
1307   if (!keylength)
1308     keylength = nbits_from_pk (pk);
1309
1310   if (pk->version == 5)
1311     {
1312       es_fputs (gnupg_status_compliance_flag (CO_GNUPG), es_stdout);
1313       any++;
1314     }
1315   if (gnupg_pk_is_compliant (CO_DE_VS, pk->pubkey_algo, pk->pkey,
1316                              keylength, curvename))
1317     {
1318       es_fprintf (es_stdout, any ? " %s" : "%s",
1319                   gnupg_status_compliance_flag (CO_DE_VS));
1320       any++;
1321     }
1322 }
1323
1324
1325 /* List a key in colon mode.  If SECRET is true this is a secret key
1326    record (i.e. requested via --list-secret-key).  If HAS_SECRET a
1327    secret key is available even if SECRET is not set.  */
1328 static void
1329 list_keyblock_colon (ctrl_t ctrl, kbnode_t keyblock,
1330                      int secret, int has_secret)
1331 {
1332   int rc;
1333   KBNODE kbctx;
1334   KBNODE node;
1335   PKT_public_key *pk;
1336   u32 keyid[2];
1337   int trustletter = 0;
1338   int trustletter_print;
1339   int ownertrust_print;
1340   int ulti_hack = 0;
1341   int i;
1342   char *hexgrip_buffer = NULL;
1343   const char *hexgrip = NULL;
1344   char *serialno = NULL;
1345   int stubkey;
1346   unsigned int keylength;
1347   char *curve = NULL;
1348   const char *curvename = NULL;
1349
1350   /* Get the keyid from the keyblock.  */
1351   node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
1352   if (!node)
1353     {
1354       log_error ("Oops; key lost!\n");
1355       dump_kbnode (keyblock);
1356       return;
1357     }
1358
1359   pk = node->pkt->pkt.public_key;
1360   if (secret || has_secret || opt.with_keygrip || opt.with_key_data)
1361     {
1362       rc = hexkeygrip_from_pk (pk, &hexgrip_buffer);
1363       if (rc)
1364         log_error ("error computing a keygrip: %s\n", gpg_strerror (rc));
1365       /* In the error case we print an empty string so that we have a
1366        * "grp" record for each and subkey - even if it is empty.  This
1367        * may help to prevent sync problems.  */
1368       hexgrip = hexgrip_buffer? hexgrip_buffer : "";
1369     }
1370   stubkey = 0;
1371   if ((secret || has_secret)
1372       && agent_get_keyinfo (NULL, hexgrip, &serialno, NULL))
1373     stubkey = 1;  /* Key not found.  */
1374
1375   keyid_from_pk (pk, keyid);
1376   if (!pk->flags.valid)
1377     trustletter_print = 'i';
1378   else if (pk->flags.revoked)
1379     trustletter_print = 'r';
1380   else if (pk->has_expired)
1381     trustletter_print = 'e';
1382   else if (opt.fast_list_mode || opt.no_expensive_trust_checks)
1383     trustletter_print = 0;
1384   else
1385     {
1386       trustletter = get_validity_info (ctrl, keyblock, pk, NULL);
1387       if (trustletter == 'u')
1388         ulti_hack = 1;
1389       trustletter_print = trustletter;
1390     }
1391
1392   if (!opt.fast_list_mode && !opt.no_expensive_trust_checks)
1393     ownertrust_print = get_ownertrust_info (ctrl, pk, 0);
1394   else
1395     ownertrust_print = 0;
1396
1397   keylength = nbits_from_pk (pk);
1398
1399   es_fputs (secret? "sec:":"pub:", es_stdout);
1400   if (trustletter_print)
1401     es_putc (trustletter_print, es_stdout);
1402   es_fprintf (es_stdout, ":%u:%d:%08lX%08lX:%s:%s::",
1403               keylength,
1404               pk->pubkey_algo,
1405               (ulong) keyid[0], (ulong) keyid[1],
1406               colon_datestr_from_pk (pk), colon_strtime (pk->expiredate));
1407
1408   if (ownertrust_print)
1409     es_putc (ownertrust_print, es_stdout);
1410   es_putc (':', es_stdout);
1411
1412   es_putc (':', es_stdout);
1413   es_putc (':', es_stdout);
1414   print_capabilities (ctrl, pk, keyblock);
1415   es_putc (':', es_stdout);             /* End of field 13. */
1416   es_putc (':', es_stdout);             /* End of field 14. */
1417   if (secret || has_secret)
1418     {
1419       if (stubkey)
1420         es_putc ('#', es_stdout);
1421       else if (serialno)
1422         es_fputs (serialno, es_stdout);
1423       else if (has_secret)
1424         es_putc ('+', es_stdout);
1425     }
1426   es_putc (':', es_stdout);             /* End of field 15. */
1427   es_putc (':', es_stdout);             /* End of field 16. */
1428   if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA
1429       || pk->pubkey_algo == PUBKEY_ALGO_EDDSA
1430       || pk->pubkey_algo == PUBKEY_ALGO_ECDH)
1431     {
1432       curve = openpgp_oid_to_str (pk->pkey[0]);
1433       curvename = openpgp_oid_to_curve (curve, 0);
1434       if (!curvename)
1435         curvename = curve;
1436       es_fputs (curvename, es_stdout);
1437     }
1438   es_putc (':', es_stdout);             /* End of field 17. */
1439   print_compliance_flags (pk, keylength, curvename);
1440   es_putc (':', es_stdout);             /* End of field 18 (compliance). */
1441   if (pk->keyupdate)
1442     es_fputs (colon_strtime (pk->keyupdate), es_stdout);
1443   es_putc (':', es_stdout);             /* End of field 19 (last_update). */
1444   es_fprintf (es_stdout, "%d%s", pk->keyorg, pk->updateurl? " ":"");
1445   if (pk->updateurl)
1446     es_write_sanitized (es_stdout, pk->updateurl, strlen (pk->updateurl),
1447                         ":", NULL);
1448   es_putc (':', es_stdout);             /* End of field 20 (origin). */
1449   es_putc ('\n', es_stdout);
1450
1451   print_revokers (es_stdout, pk);
1452   print_fingerprint (ctrl, NULL, pk, 0);
1453   if (hexgrip)
1454     es_fprintf (es_stdout, "grp:::::::::%s:\n", hexgrip);
1455   if (opt.with_key_data)
1456     print_key_data (pk);
1457
1458   for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0));)
1459     {
1460       if (node->pkt->pkttype == PKT_USER_ID)
1461         {
1462           PKT_user_id *uid = node->pkt->pkt.user_id;
1463           int uid_validity;
1464
1465           if (attrib_fp && uid->attrib_data != NULL)
1466             dump_attribs (uid, pk);
1467
1468           if (uid->flags.revoked)
1469             uid_validity = 'r';
1470           else if (uid->flags.expired)
1471             uid_validity = 'e';
1472           else if (opt.no_expensive_trust_checks)
1473             uid_validity = 0;
1474           else if (ulti_hack)
1475             uid_validity = 'u';
1476           else
1477             uid_validity = get_validity_info (ctrl, keyblock, pk, uid);
1478
1479           es_fputs (uid->attrib_data? "uat:":"uid:", es_stdout);
1480           if (uid_validity)
1481             es_putc (uid_validity, es_stdout);
1482           es_fputs ("::::", es_stdout);
1483
1484           es_fprintf (es_stdout, "%s:", colon_strtime (uid->created));
1485           es_fprintf (es_stdout, "%s:", colon_strtime (uid->expiredate));
1486
1487           namehash_from_uid (uid);
1488
1489           for (i = 0; i < 20; i++)
1490             es_fprintf (es_stdout, "%02X", uid->namehash[i]);
1491
1492           es_fprintf (es_stdout, "::");
1493
1494           if (uid->attrib_data)
1495             es_fprintf (es_stdout, "%u %lu", uid->numattribs, uid->attrib_len);
1496           else
1497             es_write_sanitized (es_stdout, uid->name, uid->len, ":", NULL);
1498           es_fputs (":::::::::", es_stdout);
1499           if (uid->keyupdate)
1500             es_fputs (colon_strtime (uid->keyupdate), es_stdout);
1501           es_putc (':', es_stdout);     /* End of field 19 (last_update). */
1502           es_fprintf (es_stdout, "%d%s", uid->keyorg, uid->updateurl? " ":"");
1503           if (uid->updateurl)
1504             es_write_sanitized (es_stdout,
1505                                 uid->updateurl, strlen (uid->updateurl),
1506                                 ":", NULL);
1507           es_putc (':', es_stdout);     /* End of field 20 (origin). */
1508           es_putc ('\n', es_stdout);
1509 #ifdef USE_TOFU
1510           if (!uid->attrib_data && opt.with_tofu_info
1511               && (opt.trust_model == TM_TOFU || opt.trust_model == TM_TOFU_PGP))
1512             {
1513               /* Print a "tfs" record.  */
1514               tofu_write_tfs_record (ctrl, es_stdout, pk, uid->name);
1515             }
1516 #endif /*USE_TOFU*/
1517         }
1518       else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
1519         {
1520           u32 keyid2[2];
1521           PKT_public_key *pk2;
1522           int need_hexgrip = !!hexgrip;
1523
1524           pk2 = node->pkt->pkt.public_key;
1525           xfree (hexgrip_buffer); hexgrip_buffer = NULL; hexgrip = NULL;
1526           xfree (serialno); serialno = NULL;
1527           if (need_hexgrip
1528               || secret || has_secret || opt.with_keygrip || opt.with_key_data)
1529             {
1530               rc = hexkeygrip_from_pk (pk2, &hexgrip_buffer);
1531               if (rc)
1532                 log_error ("error computing a keygrip: %s\n",
1533                            gpg_strerror (rc));
1534               hexgrip = hexgrip_buffer? hexgrip_buffer : "";
1535             }
1536           stubkey = 0;
1537           if ((secret||has_secret)
1538               && agent_get_keyinfo (NULL, hexgrip, &serialno, NULL))
1539             stubkey = 1;  /* Key not found.  */
1540
1541           keyid_from_pk (pk2, keyid2);
1542           es_fputs (secret? "ssb:":"sub:", es_stdout);
1543           if (!pk2->flags.valid)
1544             es_putc ('i', es_stdout);
1545           else if (pk2->flags.revoked)
1546             es_putc ('r', es_stdout);
1547           else if (pk2->has_expired)
1548             es_putc ('e', es_stdout);
1549           else if (opt.fast_list_mode || opt.no_expensive_trust_checks)
1550             ;
1551           else
1552             {
1553               /* TRUSTLETTER should always be defined here. */
1554               if (trustletter)
1555                 es_fprintf (es_stdout, "%c", trustletter);
1556             }
1557           keylength = nbits_from_pk (pk2);
1558           es_fprintf (es_stdout, ":%u:%d:%08lX%08lX:%s:%s:::::",
1559                       keylength,
1560                       pk2->pubkey_algo,
1561                       (ulong) keyid2[0], (ulong) keyid2[1],
1562                       colon_datestr_from_pk (pk2),
1563                       colon_strtime (pk2->expiredate));
1564           print_capabilities (ctrl, pk2, NULL);
1565           es_putc (':', es_stdout);     /* End of field 13. */
1566           es_putc (':', es_stdout);     /* End of field 14. */
1567           if (secret || has_secret)
1568             {
1569               if (stubkey)
1570                 es_putc ('#', es_stdout);
1571               else if (serialno)
1572                 es_fputs (serialno, es_stdout);
1573               else if (has_secret)
1574                 es_putc ('+', es_stdout);
1575             }
1576           es_putc (':', es_stdout);     /* End of field 15. */
1577           es_putc (':', es_stdout);     /* End of field 16. */
1578           if (pk2->pubkey_algo == PUBKEY_ALGO_ECDSA
1579               || pk2->pubkey_algo == PUBKEY_ALGO_EDDSA
1580               || pk2->pubkey_algo == PUBKEY_ALGO_ECDH)
1581             {
1582               xfree (curve);
1583               curve = openpgp_oid_to_str (pk2->pkey[0]);
1584               curvename = openpgp_oid_to_curve (curve, 0);
1585               if (!curvename)
1586                 curvename = curve;
1587               es_fputs (curvename, es_stdout);
1588             }
1589           es_putc (':', es_stdout);     /* End of field 17. */
1590           print_compliance_flags (pk2, keylength, curvename);
1591           es_putc (':', es_stdout);     /* End of field 18. */
1592           es_putc ('\n', es_stdout);
1593           print_fingerprint (ctrl, NULL, pk2, 0);
1594           if (hexgrip)
1595             es_fprintf (es_stdout, "grp:::::::::%s:\n", hexgrip);
1596           if (opt.with_key_data)
1597             print_key_data (pk2);
1598         }
1599       else if (opt.list_sigs && node->pkt->pkttype == PKT_SIGNATURE)
1600         {
1601           PKT_signature *sig = node->pkt->pkt.signature;
1602           int sigrc, fprokay = 0;
1603           char *sigstr;
1604           size_t fplen;
1605           byte fparray[MAX_FINGERPRINT_LEN];
1606           char *siguid;
1607           size_t siguidlen;
1608           char *issuer_fpr = NULL;
1609           char *reason_text = NULL;
1610           char *reason_comment = NULL;
1611           size_t reason_commentlen;
1612           int reason_code;
1613
1614           if (sig->sig_class == 0x20 || sig->sig_class == 0x28
1615               || sig->sig_class == 0x30)
1616             {
1617               sigstr = "rev";
1618               reason_code = get_revocation_reason (sig, &reason_text,
1619                                                    &reason_comment,
1620                                                    &reason_commentlen);
1621             }
1622           else if ((sig->sig_class & ~3) == 0x10)
1623             sigstr = "sig";
1624           else if (sig->sig_class == 0x18)
1625             sigstr = "sig";
1626           else if (sig->sig_class == 0x1F)
1627             sigstr = "sig";
1628           else
1629             {
1630               es_fprintf (es_stdout, "sig::::::::::%02x%c:\n",
1631                       sig->sig_class, sig->flags.exportable ? 'x' : 'l');
1632               continue;
1633             }
1634
1635           if (opt.check_sigs)
1636             {
1637               PKT_public_key *signer_pk = NULL;
1638
1639               es_fflush (es_stdout);
1640               if (opt.no_sig_cache)
1641                 signer_pk = xmalloc_clear (sizeof (PKT_public_key));
1642
1643               rc = check_key_signature2 (ctrl, keyblock, node, NULL, signer_pk,
1644                                          NULL, NULL, NULL);
1645               switch (gpg_err_code (rc))
1646                 {
1647                 case 0:
1648                   sigrc = '!';
1649                   break;
1650                 case GPG_ERR_BAD_SIGNATURE:
1651                   sigrc = '-';
1652                   break;
1653                 case GPG_ERR_NO_PUBKEY:
1654                 case GPG_ERR_UNUSABLE_PUBKEY:
1655                   sigrc = '?';
1656                   break;
1657                 default:
1658                   sigrc = '%';
1659                   break;
1660                 }
1661
1662               if (opt.no_sig_cache)
1663                 {
1664                   if (!rc)
1665                     {
1666                       fingerprint_from_pk (signer_pk, fparray, &fplen);
1667                       fprokay = 1;
1668                     }
1669                   free_public_key (signer_pk);
1670                 }
1671             }
1672           else
1673             {
1674               rc = 0;
1675               sigrc = ' '; /* Note the fix-up below in --list-sigs mode.  */
1676             }
1677
1678           if (sigrc != '%' && sigrc != '?' && !opt.fast_list_mode)
1679             {
1680               int nouid;
1681               siguid = get_user_id (ctrl, sig->keyid, &siguidlen, &nouid);
1682               if (!opt.check_sigs && nouid)
1683                 sigrc = '?';  /* No key in local keyring.  */
1684             }
1685           else
1686             {
1687               siguid = NULL;
1688               siguidlen = 0;
1689             }
1690
1691
1692           es_fputs (sigstr, es_stdout);
1693           es_putc (':', es_stdout);
1694           if (sigrc != ' ')
1695             es_putc (sigrc, es_stdout);
1696           es_fprintf (es_stdout, "::%d:%08lX%08lX:%s:%s:", sig->pubkey_algo,
1697                   (ulong) sig->keyid[0], (ulong) sig->keyid[1],
1698                   colon_datestr_from_sig (sig),
1699                   colon_expirestr_from_sig (sig));
1700
1701           if (sig->trust_depth || sig->trust_value)
1702             es_fprintf (es_stdout, "%d %d", sig->trust_depth, sig->trust_value);
1703           es_fprintf (es_stdout, ":");
1704
1705           if (sig->trust_regexp)
1706             es_write_sanitized (es_stdout, sig->trust_regexp,
1707                                 strlen (sig->trust_regexp), ":", NULL);
1708           es_fprintf (es_stdout, ":");
1709
1710           if (sigrc == '%')
1711             es_fprintf (es_stdout, "[%s] ", gpg_strerror (rc));
1712           else if (siguid)
1713             es_write_sanitized (es_stdout, siguid, siguidlen, ":", NULL);
1714
1715           es_fprintf (es_stdout, ":%02x%c", sig->sig_class,
1716                       sig->flags.exportable ? 'x' : 'l');
1717           if (reason_text)
1718             es_fprintf (es_stdout, ",%02x", reason_code);
1719           es_fputs ("::", es_stdout);
1720
1721           if (opt.no_sig_cache && opt.check_sigs && fprokay)
1722             {
1723               for (i = 0; i < fplen; i++)
1724                 es_fprintf (es_stdout, "%02X", fparray[i]);
1725             }
1726           else if ((issuer_fpr = issuer_fpr_string (sig)))
1727             es_fputs (issuer_fpr, es_stdout);
1728
1729           es_fprintf (es_stdout, ":::%d:", sig->digest_algo);
1730
1731           if (reason_comment)
1732             {
1733               es_fputs ("::::", es_stdout);
1734               es_write_sanitized (es_stdout, reason_comment, reason_commentlen,
1735                                   ":", NULL);
1736               es_putc (':', es_stdout);
1737             }
1738           es_putc ('\n', es_stdout);
1739
1740           if (opt.show_subpackets)
1741             print_subpackets_colon (sig);
1742
1743           /* fixme: check or list other sigs here */
1744           xfree (reason_text);
1745           xfree (reason_comment);
1746           xfree (siguid);
1747           xfree (issuer_fpr);
1748         }
1749     }
1750
1751   xfree (curve);
1752   xfree (hexgrip_buffer);
1753   xfree (serialno);
1754 }
1755
1756 /*
1757  * Reorder the keyblock so that the primary user ID (and not attribute
1758  * packet) comes first.  Fixme: Replace this by a generic sort
1759  * function.  */
1760 static void
1761 do_reorder_keyblock (KBNODE keyblock, int attr)
1762 {
1763   KBNODE primary = NULL, primary0 = NULL, primary2 = NULL;
1764   KBNODE last, node;
1765
1766   for (node = keyblock; node; primary0 = node, node = node->next)
1767     {
1768       if (node->pkt->pkttype == PKT_USER_ID &&
1769           ((attr && node->pkt->pkt.user_id->attrib_data) ||
1770            (!attr && !node->pkt->pkt.user_id->attrib_data)) &&
1771           node->pkt->pkt.user_id->flags.primary)
1772         {
1773           primary = primary2 = node;
1774           for (node = node->next; node; primary2 = node, node = node->next)
1775             {
1776               if (node->pkt->pkttype == PKT_USER_ID
1777                   || node->pkt->pkttype == PKT_PUBLIC_SUBKEY
1778                   || node->pkt->pkttype == PKT_SECRET_SUBKEY)
1779                 {
1780                   break;
1781                 }
1782             }
1783           break;
1784         }
1785     }
1786   if (!primary)
1787     return; /* No primary key flag found (should not happen).  */
1788
1789   for (last = NULL, node = keyblock; node; last = node, node = node->next)
1790     {
1791       if (node->pkt->pkttype == PKT_USER_ID)
1792         break;
1793     }
1794   log_assert (node);
1795   log_assert (last);     /* The user ID is never the first packet.  */
1796   log_assert (primary0); /* Ditto (this is the node before primary).  */
1797   if (node == primary)
1798     return; /* Already the first one.  */
1799
1800   last->next = primary;
1801   primary0->next = primary2->next;
1802   primary2->next = node;
1803 }
1804
1805 void
1806 reorder_keyblock (KBNODE keyblock)
1807 {
1808   do_reorder_keyblock (keyblock, 1);
1809   do_reorder_keyblock (keyblock, 0);
1810 }
1811
1812 static void
1813 list_keyblock (ctrl_t ctrl,
1814                KBNODE keyblock, int secret, int has_secret, int fpr,
1815                struct keylist_context *listctx)
1816 {
1817   reorder_keyblock (keyblock);
1818
1819   if (opt.with_colons)
1820     list_keyblock_colon (ctrl, keyblock, secret, has_secret);
1821   else if ((opt.list_options & LIST_SHOW_ONLY_FPR_MBOX))
1822     {
1823       if (!listctx->no_validity)
1824         check_trustdb_stale (ctrl);
1825       list_keyblock_simple (ctrl, keyblock);
1826     }
1827   else
1828     list_keyblock_print (ctrl, keyblock, secret, fpr, listctx);
1829
1830   if (secret)
1831     es_fflush (es_stdout);
1832 }
1833
1834
1835 /* Public function used by keygen to list a keyblock.  If NO_VALIDITY
1836  * is set the validity of a key is never shown.  */
1837 void
1838 list_keyblock_direct (ctrl_t ctrl,
1839                       kbnode_t keyblock, int secret, int has_secret, int fpr,
1840                       int no_validity)
1841 {
1842   struct keylist_context listctx;
1843
1844   memset (&listctx, 0, sizeof (listctx));
1845   listctx.no_validity = !!no_validity;
1846   list_keyblock (ctrl, keyblock, secret, has_secret, fpr, &listctx);
1847   keylist_context_release (&listctx);
1848 }
1849
1850
1851 /* Print an hex digit in ICAO spelling.  */
1852 static void
1853 print_icao_hexdigit (estream_t fp, int c)
1854 {
1855   static const char *list[16] = {
1856     "Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven",
1857     "Eight", "Niner", "Alfa", "Bravo", "Charlie", "Delta", "Echo", "Foxtrot"
1858   };
1859
1860   tty_fprintf (fp, "%s", list[c&15]);
1861 }
1862
1863
1864 /*
1865  * Function to print the finperprint.
1866  * mode 0: as used in key listings, opt.with_colons is honored
1867  *      1: print using log_info ()
1868  *      2: direct use of tty
1869  *      3: direct use of tty but only primary key.
1870  *      4: direct use of tty but only subkey.
1871  *     10: Same as 0 but with_colons etc is ignored.
1872  *     20: Same as 0 but using a compact format.
1873  *
1874  * Modes 1 and 2 will try and print both subkey and primary key
1875  * fingerprints.  A MODE with bit 7 set is used internally.  If
1876  * OVERRIDE_FP is not NULL that stream will be used in  0 instead
1877  * of es_stdout or instead of the TTY in modes 2 and 3.
1878  */
1879 void
1880 print_fingerprint (ctrl_t ctrl, estream_t override_fp,
1881                    PKT_public_key *pk, int mode)
1882 {
1883   char hexfpr[2*MAX_FINGERPRINT_LEN+1];
1884   char *p;
1885   size_t i;
1886   estream_t fp;
1887   const char *text;
1888   int primary = 0;
1889   int with_colons = opt.with_colons;
1890   int with_icao   = opt.with_icao_spelling;
1891   int compact = 0;
1892
1893   if (mode == 10)
1894     {
1895       mode = 0;
1896       with_colons = 0;
1897       with_icao = 0;
1898     }
1899   else if (mode == 20)
1900     {
1901       mode = 0;
1902       with_colons = 0;
1903       compact = 1;
1904     }
1905
1906   if (!opt.fingerprint && !opt.with_fingerprint
1907       && opt.with_subkey_fingerprint)
1908     compact = 1;
1909
1910   if (pk->main_keyid[0] == pk->keyid[0]
1911       && pk->main_keyid[1] == pk->keyid[1])
1912     primary = 1;
1913
1914   /* Just to be safe */
1915   if ((mode & 0x80) && !primary)
1916     {
1917       log_error ("primary key is not really primary!\n");
1918       return;
1919     }
1920
1921   mode &= ~0x80;
1922
1923   if (!primary && (mode == 1 || mode == 2))
1924     {
1925       PKT_public_key *primary_pk = xmalloc_clear (sizeof (*primary_pk));
1926       get_pubkey (ctrl, primary_pk, pk->main_keyid);
1927       print_fingerprint (ctrl, override_fp, primary_pk, (mode | 0x80));
1928       free_public_key (primary_pk);
1929     }
1930
1931   if (mode == 1)
1932     {
1933       fp = log_get_stream ();
1934       if (primary)
1935         text = _("Primary key fingerprint:");
1936       else
1937         text = _("     Subkey fingerprint:");
1938     }
1939   else if (mode == 2)
1940     {
1941       fp = override_fp; /* Use tty or given stream.  */
1942       if (primary)
1943         /* TRANSLATORS: this should fit into 24 bytes so that the
1944          * fingerprint data is properly aligned with the user ID */
1945         text = _(" Primary key fingerprint:");
1946       else
1947         text = _("      Subkey fingerprint:");
1948     }
1949   else if (mode == 3)
1950     {
1951       fp = override_fp; /* Use tty or given stream.  */
1952       text = _("      Key fingerprint =");
1953     }
1954   else if (mode == 4)
1955     {
1956       fp = override_fp; /* Use tty or given stream.  */
1957       text = _("      Subkey fingerprint:");
1958     }
1959   else
1960     {
1961       fp = override_fp? override_fp : es_stdout;
1962       if (opt.keyid_format == KF_NONE)
1963         {
1964           text = "     ";  /* To indent ICAO spelling.  */
1965           compact = 1;
1966         }
1967       else
1968         text = _("      Key fingerprint =");
1969     }
1970
1971   hexfingerprint (pk, hexfpr, sizeof hexfpr);
1972   if (with_colons && !mode)
1973     {
1974       es_fprintf (fp, "fpr:::::::::%s:", hexfpr);
1975     }
1976   else if (compact && !opt.fingerprint && !opt.with_fingerprint)
1977     {
1978       tty_fprintf (fp, "%*s%s", 6, "", hexfpr);
1979     }
1980   else
1981     {
1982       char fmtfpr[MAX_FORMATTED_FINGERPRINT_LEN + 1];
1983       format_hexfingerprint (hexfpr, fmtfpr, sizeof fmtfpr);
1984       if (compact)
1985         tty_fprintf (fp, "%*s%s", 6, "", fmtfpr);
1986       else
1987         tty_fprintf (fp, "%s %s", text, fmtfpr);
1988     }
1989   tty_fprintf (fp, "\n");
1990   if (!with_colons && with_icao)
1991     {
1992       ;
1993       tty_fprintf (fp, "%*s\"", (int)strlen(text)+1, "");
1994       for (i = 0, p = hexfpr; *p; i++, p++)
1995         {
1996           if (!i)
1997             ;
1998           else if (!(i%8))
1999             tty_fprintf (fp, "\n%*s ", (int)strlen(text)+1, "");
2000           else if (!(i%4))
2001             tty_fprintf (fp, "  ");
2002           else
2003             tty_fprintf (fp, " ");
2004           print_icao_hexdigit (fp, xtoi_1 (p));
2005         }
2006       tty_fprintf (fp, "\"\n");
2007     }
2008 }
2009
2010 /* Print the serial number of an OpenPGP card if available.  */
2011 static void
2012 print_card_serialno (const char *serialno)
2013 {
2014   if (!serialno)
2015     return;
2016   if (opt.with_colons)
2017     return; /* Handled elsewhere. */
2018
2019   es_fputs (_("      Card serial no. ="), es_stdout);
2020   es_putc (' ', es_stdout);
2021   if (strlen (serialno) == 32 && !strncmp (serialno, "D27600012401", 12))
2022     {
2023       /* This is an OpenPGP card.  Print the relevant part.  */
2024       /* Example: D2760001240101010001000003470000 */
2025       /*                          xxxxyyyyyyyy     */
2026       es_fprintf (es_stdout, "%.*s %.*s", 4, serialno+16, 8, serialno+20);
2027     }
2028  else
2029    es_fputs (serialno, es_stdout);
2030   es_putc ('\n', es_stdout);
2031 }
2032
2033
2034 /* Print a public or secret (sub)key line.  Example:
2035  *
2036  * pub   dsa2048 2007-12-31 [SC] [expires: 2018-12-31]
2037  *       80615870F5BAD690333686D0F2AD85AC1E42B367
2038  *
2039  * Some global options may result in a different output format.  If
2040  * SECRET is set, "sec" or "ssb" is used instead of "pub" or "sub" and
2041  * depending on the value a flag character is shown:
2042  *
2043  *    1 := ' ' Regular secret key
2044  *    2 := '#' Stub secret key
2045  *    3 := '>' Secret key is on a token.
2046  */
2047 void
2048 print_key_line (ctrl_t ctrl, estream_t fp, PKT_public_key *pk, int secret)
2049 {
2050   char pkstrbuf[PUBKEY_STRING_SIZE];
2051
2052   tty_fprintf (fp, "%s%c  %s",
2053                pk->flags.primary? (secret? "sec":"pub")
2054                /**/             : (secret? "ssb":"sub"),
2055                secret == 2? '#' : secret == 3? '>' : ' ',
2056                pubkey_string (pk, pkstrbuf, sizeof pkstrbuf));
2057   if (opt.keyid_format != KF_NONE)
2058     tty_fprintf (fp, "/%s", keystr_from_pk (pk));
2059   tty_fprintf (fp, " %s", datestr_from_pk (pk));
2060
2061   if ((opt.list_options & LIST_SHOW_USAGE))
2062     {
2063       tty_fprintf (fp, " [%s]", usagestr_from_pk (pk, 0));
2064     }
2065   if (pk->flags.revoked)
2066     {
2067       tty_fprintf (fp, " [");
2068       tty_fprintf (fp, _("revoked: %s"), revokestr_from_pk (pk));
2069       tty_fprintf (fp, "]");
2070     }
2071   else if (pk->has_expired)
2072     {
2073       tty_fprintf (fp, " [");
2074       tty_fprintf (fp, _("expired: %s"), expirestr_from_pk (pk));
2075       tty_fprintf (fp, "]");
2076     }
2077   else if (pk->expiredate)
2078     {
2079       tty_fprintf (fp, " [");
2080       tty_fprintf (fp, _("expires: %s"), expirestr_from_pk (pk));
2081       tty_fprintf (fp, "]");
2082     }
2083
2084 #if 0
2085   /* I need to think about this some more.  It's easy enough to
2086      include, but it looks sort of confusing in the listing... */
2087   if (opt.list_options & LIST_SHOW_VALIDITY)
2088     {
2089       int validity = get_validity (ctrl, pk, NULL, NULL, 0);
2090       tty_fprintf (fp, " [%s]", trust_value_to_string (validity));
2091     }
2092 #endif
2093
2094   if (pk->pubkey_algo >= 100)
2095     tty_fprintf (fp, " [experimental algorithm %d]", pk->pubkey_algo);
2096
2097   tty_fprintf (fp, "\n");
2098
2099   /* if the user hasn't explicitly asked for human-readable
2100      fingerprints, show compact fpr of primary key: */
2101   if (pk->flags.primary &&
2102       !opt.fingerprint && !opt.with_fingerprint)
2103     print_fingerprint (ctrl, fp, pk, 20);
2104 }
2105
2106
2107 void
2108 set_attrib_fd (int fd)
2109 {
2110   static int last_fd = -1;
2111
2112   if (fd != -1 && last_fd == fd)
2113     return;
2114
2115   /* Fixme: Do we need to check for the log stream here?  */
2116   if (attrib_fp && attrib_fp != log_get_stream ())
2117     es_fclose (attrib_fp);
2118   attrib_fp = NULL;
2119   if (fd == -1)
2120     return;
2121
2122   if (! gnupg_fd_valid (fd))
2123     log_fatal ("attribute-fd is invalid: %s\n", strerror (errno));
2124
2125 #ifdef HAVE_DOSISH_SYSTEM
2126   setmode (fd, O_BINARY);
2127 #endif
2128   if (fd == 1)
2129     attrib_fp = es_stdout;
2130   else if (fd == 2)
2131     attrib_fp = es_stderr;
2132   else
2133     attrib_fp = es_fdopen (fd, "wb");
2134   if (!attrib_fp)
2135     {
2136       log_fatal ("can't open fd %d for attribute output: %s\n",
2137                  fd, strerror (errno));
2138     }
2139
2140   last_fd = fd;
2141 }