c9121a1e36f0a4f23fe206f551a3810ce7ed23d5
[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)
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, 0);
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 void
1221 print_revokers (estream_t fp, PKT_public_key * pk)
1222 {
1223   /* print the revoker record */
1224   if (!pk->revkey && pk->numrevkeys)
1225     BUG ();
1226   else
1227     {
1228       int i, j;
1229
1230       for (i = 0; i < pk->numrevkeys; i++)
1231         {
1232           byte *p;
1233
1234           es_fprintf (fp, "rvk:::%d::::::", pk->revkey[i].algid);
1235           p = pk->revkey[i].fpr;
1236           for (j = 0; j < 20; j++, p++)
1237             es_fprintf (fp, "%02X", *p);
1238           es_fprintf (fp, ":%02x%s:\n",
1239                       pk->revkey[i].class,
1240                       (pk->revkey[i].class & 0x40) ? "s" : "");
1241         }
1242     }
1243 }
1244
1245
1246 /* Print the compliance flags to field 18.  PK is the public key.
1247  * KEYLENGTH is the length of the key in bits and CURVENAME is either
1248  * NULL or the name of the curve.  The latter two args are here
1249  * merely because the caller has already computed them.  */
1250 static void
1251 print_compliance_flags (PKT_public_key *pk,
1252                         unsigned int keylength, const char *curvename)
1253 {
1254   int any = 0;
1255
1256   if (!keylength)
1257     keylength = nbits_from_pk (pk);
1258
1259   if (pk->version == 5)
1260     {
1261       es_fputs (gnupg_status_compliance_flag (CO_GNUPG), es_stdout);
1262       any++;
1263     }
1264   if (gnupg_pk_is_compliant (CO_DE_VS, pk->pubkey_algo, pk->pkey,
1265                              keylength, curvename))
1266     {
1267       es_fprintf (es_stdout, any ? " %s" : "%s",
1268                   gnupg_status_compliance_flag (CO_DE_VS));
1269       any++;
1270     }
1271 }
1272
1273
1274 /* List a key in colon mode.  If SECRET is true this is a secret key
1275    record (i.e. requested via --list-secret-key).  If HAS_SECRET a
1276    secret key is available even if SECRET is not set.  */
1277 static void
1278 list_keyblock_colon (ctrl_t ctrl, kbnode_t keyblock,
1279                      int secret, int has_secret)
1280 {
1281   int rc;
1282   KBNODE kbctx;
1283   KBNODE node;
1284   PKT_public_key *pk;
1285   u32 keyid[2];
1286   int trustletter = 0;
1287   int trustletter_print;
1288   int ownertrust_print;
1289   int ulti_hack = 0;
1290   int i;
1291   char *hexgrip_buffer = NULL;
1292   const char *hexgrip = NULL;
1293   char *serialno = NULL;
1294   int stubkey;
1295   unsigned int keylength;
1296   char *curve = NULL;
1297   const char *curvename = NULL;
1298
1299   /* Get the keyid from the keyblock.  */
1300   node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
1301   if (!node)
1302     {
1303       log_error ("Oops; key lost!\n");
1304       dump_kbnode (keyblock);
1305       return;
1306     }
1307
1308   pk = node->pkt->pkt.public_key;
1309   if (secret || has_secret || opt.with_keygrip || opt.with_key_data)
1310     {
1311       rc = hexkeygrip_from_pk (pk, &hexgrip_buffer);
1312       if (rc)
1313         log_error ("error computing a keygrip: %s\n", gpg_strerror (rc));
1314       /* In the error case we print an empty string so that we have a
1315        * "grp" record for each and subkey - even if it is empty.  This
1316        * may help to prevent sync problems.  */
1317       hexgrip = hexgrip_buffer? hexgrip_buffer : "";
1318     }
1319   stubkey = 0;
1320   if ((secret || has_secret)
1321       && agent_get_keyinfo (NULL, hexgrip, &serialno, NULL))
1322     stubkey = 1;  /* Key not found.  */
1323
1324   keyid_from_pk (pk, keyid);
1325   if (!pk->flags.valid)
1326     trustletter_print = 'i';
1327   else if (pk->flags.revoked)
1328     trustletter_print = 'r';
1329   else if (pk->has_expired)
1330     trustletter_print = 'e';
1331   else if (opt.fast_list_mode || opt.no_expensive_trust_checks)
1332     trustletter_print = 0;
1333   else
1334     {
1335       trustletter = get_validity_info (ctrl, keyblock, pk, NULL);
1336       if (trustletter == 'u')
1337         ulti_hack = 1;
1338       trustletter_print = trustletter;
1339     }
1340
1341   if (!opt.fast_list_mode && !opt.no_expensive_trust_checks)
1342     ownertrust_print = get_ownertrust_info (ctrl, pk, 0);
1343   else
1344     ownertrust_print = 0;
1345
1346   keylength = nbits_from_pk (pk);
1347
1348   es_fputs (secret? "sec:":"pub:", es_stdout);
1349   if (trustletter_print)
1350     es_putc (trustletter_print, es_stdout);
1351   es_fprintf (es_stdout, ":%u:%d:%08lX%08lX:%s:%s::",
1352               keylength,
1353               pk->pubkey_algo,
1354               (ulong) keyid[0], (ulong) keyid[1],
1355               colon_datestr_from_pk (pk), colon_strtime (pk->expiredate));
1356
1357   if (ownertrust_print)
1358     es_putc (ownertrust_print, es_stdout);
1359   es_putc (':', es_stdout);
1360
1361   es_putc (':', es_stdout);
1362   es_putc (':', es_stdout);
1363   print_capabilities (ctrl, pk, keyblock);
1364   es_putc (':', es_stdout);             /* End of field 13. */
1365   es_putc (':', es_stdout);             /* End of field 14. */
1366   if (secret || has_secret)
1367     {
1368       if (stubkey)
1369         es_putc ('#', es_stdout);
1370       else if (serialno)
1371         es_fputs (serialno, es_stdout);
1372       else if (has_secret)
1373         es_putc ('+', es_stdout);
1374     }
1375   es_putc (':', es_stdout);             /* End of field 15. */
1376   es_putc (':', es_stdout);             /* End of field 16. */
1377   if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA
1378       || pk->pubkey_algo == PUBKEY_ALGO_EDDSA
1379       || pk->pubkey_algo == PUBKEY_ALGO_ECDH)
1380     {
1381       curve = openpgp_oid_to_str (pk->pkey[0]);
1382       curvename = openpgp_oid_to_curve (curve, 0);
1383       if (!curvename)
1384         curvename = curve;
1385       es_fputs (curvename, es_stdout);
1386     }
1387   es_putc (':', es_stdout);             /* End of field 17. */
1388   print_compliance_flags (pk, keylength, curvename);
1389   es_putc (':', es_stdout);             /* End of field 18 (compliance). */
1390   if (pk->keyupdate)
1391     es_fputs (colon_strtime (pk->keyupdate), es_stdout);
1392   es_putc (':', es_stdout);             /* End of field 19 (last_update). */
1393   es_fprintf (es_stdout, "%d%s", pk->keyorg, pk->updateurl? " ":"");
1394   if (pk->updateurl)
1395     es_write_sanitized (es_stdout, pk->updateurl, strlen (pk->updateurl),
1396                         ":", NULL);
1397   es_putc (':', es_stdout);             /* End of field 20 (origin). */
1398   es_putc ('\n', es_stdout);
1399
1400   print_revokers (es_stdout, pk);
1401   print_fingerprint (ctrl, NULL, pk, 0);
1402   if (hexgrip)
1403     es_fprintf (es_stdout, "grp:::::::::%s:\n", hexgrip);
1404   if (opt.with_key_data)
1405     print_key_data (pk);
1406
1407   for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0));)
1408     {
1409       if (node->pkt->pkttype == PKT_USER_ID)
1410         {
1411           PKT_user_id *uid = node->pkt->pkt.user_id;
1412           int uid_validity;
1413
1414           if (attrib_fp && uid->attrib_data != NULL)
1415             dump_attribs (uid, pk);
1416
1417           if (uid->flags.revoked)
1418             uid_validity = 'r';
1419           else if (uid->flags.expired)
1420             uid_validity = 'e';
1421           else if (opt.no_expensive_trust_checks)
1422             uid_validity = 0;
1423           else if (ulti_hack)
1424             uid_validity = 'u';
1425           else
1426             uid_validity = get_validity_info (ctrl, keyblock, pk, uid);
1427
1428           es_fputs (uid->attrib_data? "uat:":"uid:", es_stdout);
1429           if (uid_validity)
1430             es_putc (uid_validity, es_stdout);
1431           es_fputs ("::::", es_stdout);
1432
1433           es_fprintf (es_stdout, "%s:", colon_strtime (uid->created));
1434           es_fprintf (es_stdout, "%s:", colon_strtime (uid->expiredate));
1435
1436           namehash_from_uid (uid);
1437
1438           for (i = 0; i < 20; i++)
1439             es_fprintf (es_stdout, "%02X", uid->namehash[i]);
1440
1441           es_fprintf (es_stdout, "::");
1442
1443           if (uid->attrib_data)
1444             es_fprintf (es_stdout, "%u %lu", uid->numattribs, uid->attrib_len);
1445           else
1446             es_write_sanitized (es_stdout, uid->name, uid->len, ":", NULL);
1447           es_fputs (":::::::::", es_stdout);
1448           if (uid->keyupdate)
1449             es_fputs (colon_strtime (uid->keyupdate), es_stdout);
1450           es_putc (':', es_stdout);     /* End of field 19 (last_update). */
1451           es_fprintf (es_stdout, "%d%s", uid->keyorg, uid->updateurl? " ":"");
1452           if (uid->updateurl)
1453             es_write_sanitized (es_stdout,
1454                                 uid->updateurl, strlen (uid->updateurl),
1455                                 ":", NULL);
1456           es_putc (':', es_stdout);     /* End of field 20 (origin). */
1457           es_putc ('\n', es_stdout);
1458 #ifdef USE_TOFU
1459           if (!uid->attrib_data && opt.with_tofu_info
1460               && (opt.trust_model == TM_TOFU || opt.trust_model == TM_TOFU_PGP))
1461             {
1462               /* Print a "tfs" record.  */
1463               tofu_write_tfs_record (ctrl, es_stdout, pk, uid->name);
1464             }
1465 #endif /*USE_TOFU*/
1466         }
1467       else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
1468         {
1469           u32 keyid2[2];
1470           PKT_public_key *pk2;
1471           int need_hexgrip = !!hexgrip;
1472
1473           pk2 = node->pkt->pkt.public_key;
1474           xfree (hexgrip_buffer); hexgrip_buffer = NULL; hexgrip = NULL;
1475           xfree (serialno); serialno = NULL;
1476           if (need_hexgrip
1477               || secret || has_secret || opt.with_keygrip || opt.with_key_data)
1478             {
1479               rc = hexkeygrip_from_pk (pk2, &hexgrip_buffer);
1480               if (rc)
1481                 log_error ("error computing a keygrip: %s\n",
1482                            gpg_strerror (rc));
1483               hexgrip = hexgrip_buffer? hexgrip_buffer : "";
1484             }
1485           stubkey = 0;
1486           if ((secret||has_secret)
1487               && agent_get_keyinfo (NULL, hexgrip, &serialno, NULL))
1488             stubkey = 1;  /* Key not found.  */
1489
1490           keyid_from_pk (pk2, keyid2);
1491           es_fputs (secret? "ssb:":"sub:", es_stdout);
1492           if (!pk2->flags.valid)
1493             es_putc ('i', es_stdout);
1494           else if (pk2->flags.revoked)
1495             es_putc ('r', es_stdout);
1496           else if (pk2->has_expired)
1497             es_putc ('e', es_stdout);
1498           else if (opt.fast_list_mode || opt.no_expensive_trust_checks)
1499             ;
1500           else
1501             {
1502               /* TRUSTLETTER should always be defined here. */
1503               if (trustletter)
1504                 es_fprintf (es_stdout, "%c", trustletter);
1505             }
1506           keylength = nbits_from_pk (pk2);
1507           es_fprintf (es_stdout, ":%u:%d:%08lX%08lX:%s:%s:::::",
1508                       keylength,
1509                       pk2->pubkey_algo,
1510                       (ulong) keyid2[0], (ulong) keyid2[1],
1511                       colon_datestr_from_pk (pk2),
1512                       colon_strtime (pk2->expiredate));
1513           print_capabilities (ctrl, pk2, NULL);
1514           es_putc (':', es_stdout);     /* End of field 13. */
1515           es_putc (':', es_stdout);     /* End of field 14. */
1516           if (secret || has_secret)
1517             {
1518               if (stubkey)
1519                 es_putc ('#', es_stdout);
1520               else if (serialno)
1521                 es_fputs (serialno, es_stdout);
1522               else if (has_secret)
1523                 es_putc ('+', es_stdout);
1524             }
1525           es_putc (':', es_stdout);     /* End of field 15. */
1526           es_putc (':', es_stdout);     /* End of field 16. */
1527           if (pk2->pubkey_algo == PUBKEY_ALGO_ECDSA
1528               || pk2->pubkey_algo == PUBKEY_ALGO_EDDSA
1529               || pk2->pubkey_algo == PUBKEY_ALGO_ECDH)
1530             {
1531               xfree (curve);
1532               curve = openpgp_oid_to_str (pk2->pkey[0]);
1533               curvename = openpgp_oid_to_curve (curve, 0);
1534               if (!curvename)
1535                 curvename = curve;
1536               es_fputs (curvename, es_stdout);
1537             }
1538           es_putc (':', es_stdout);     /* End of field 17. */
1539           print_compliance_flags (pk2, keylength, curvename);
1540           es_putc (':', es_stdout);     /* End of field 18. */
1541           es_putc ('\n', es_stdout);
1542           print_fingerprint (ctrl, NULL, pk2, 0);
1543           if (hexgrip)
1544             es_fprintf (es_stdout, "grp:::::::::%s:\n", hexgrip);
1545           if (opt.with_key_data)
1546             print_key_data (pk2);
1547         }
1548       else if (opt.list_sigs && node->pkt->pkttype == PKT_SIGNATURE)
1549         {
1550           PKT_signature *sig = node->pkt->pkt.signature;
1551           int sigrc, fprokay = 0;
1552           char *sigstr;
1553           size_t fplen;
1554           byte fparray[MAX_FINGERPRINT_LEN];
1555           char *siguid;
1556           size_t siguidlen;
1557           char *issuer_fpr = NULL;
1558           char *reason_text = NULL;
1559           char *reason_comment = NULL;
1560           size_t reason_commentlen;
1561           int reason_code;
1562
1563           if (sig->sig_class == 0x20 || sig->sig_class == 0x28
1564               || sig->sig_class == 0x30)
1565             {
1566               sigstr = "rev";
1567               reason_code = get_revocation_reason (sig, &reason_text,
1568                                                    &reason_comment,
1569                                                    &reason_commentlen);
1570             }
1571           else if ((sig->sig_class & ~3) == 0x10)
1572             sigstr = "sig";
1573           else if (sig->sig_class == 0x18)
1574             sigstr = "sig";
1575           else if (sig->sig_class == 0x1F)
1576             sigstr = "sig";
1577           else
1578             {
1579               es_fprintf (es_stdout, "sig::::::::::%02x%c:\n",
1580                       sig->sig_class, sig->flags.exportable ? 'x' : 'l');
1581               continue;
1582             }
1583
1584           if (opt.check_sigs)
1585             {
1586               PKT_public_key *signer_pk = NULL;
1587
1588               es_fflush (es_stdout);
1589               if (opt.no_sig_cache)
1590                 signer_pk = xmalloc_clear (sizeof (PKT_public_key));
1591
1592               rc = check_key_signature2 (ctrl, keyblock, node, NULL, signer_pk,
1593                                          NULL, NULL, NULL);
1594               switch (gpg_err_code (rc))
1595                 {
1596                 case 0:
1597                   sigrc = '!';
1598                   break;
1599                 case GPG_ERR_BAD_SIGNATURE:
1600                   sigrc = '-';
1601                   break;
1602                 case GPG_ERR_NO_PUBKEY:
1603                 case GPG_ERR_UNUSABLE_PUBKEY:
1604                   sigrc = '?';
1605                   break;
1606                 default:
1607                   sigrc = '%';
1608                   break;
1609                 }
1610
1611               if (opt.no_sig_cache)
1612                 {
1613                   if (!rc)
1614                     {
1615                       fingerprint_from_pk (signer_pk, fparray, &fplen);
1616                       fprokay = 1;
1617                     }
1618                   free_public_key (signer_pk);
1619                 }
1620             }
1621           else
1622             {
1623               rc = 0;
1624               sigrc = ' '; /* Note the fix-up below in --list-sigs mode.  */
1625             }
1626
1627           if (sigrc != '%' && sigrc != '?' && !opt.fast_list_mode)
1628             {
1629               int nouid;
1630               siguid = get_user_id (ctrl, sig->keyid, &siguidlen, &nouid);
1631               if (!opt.check_sigs && nouid)
1632                 sigrc = '?';  /* No key in local keyring.  */
1633             }
1634           else
1635             {
1636               siguid = NULL;
1637               siguidlen = 0;
1638             }
1639
1640
1641           es_fputs (sigstr, es_stdout);
1642           es_putc (':', es_stdout);
1643           if (sigrc != ' ')
1644             es_putc (sigrc, es_stdout);
1645           es_fprintf (es_stdout, "::%d:%08lX%08lX:%s:%s:", sig->pubkey_algo,
1646                   (ulong) sig->keyid[0], (ulong) sig->keyid[1],
1647                   colon_datestr_from_sig (sig),
1648                   colon_expirestr_from_sig (sig));
1649
1650           if (sig->trust_depth || sig->trust_value)
1651             es_fprintf (es_stdout, "%d %d", sig->trust_depth, sig->trust_value);
1652           es_fprintf (es_stdout, ":");
1653
1654           if (sig->trust_regexp)
1655             es_write_sanitized (es_stdout, sig->trust_regexp,
1656                                 strlen (sig->trust_regexp), ":", NULL);
1657           es_fprintf (es_stdout, ":");
1658
1659           if (sigrc == '%')
1660             es_fprintf (es_stdout, "[%s] ", gpg_strerror (rc));
1661           else if (siguid)
1662             es_write_sanitized (es_stdout, siguid, siguidlen, ":", NULL);
1663
1664           es_fprintf (es_stdout, ":%02x%c", sig->sig_class,
1665                       sig->flags.exportable ? 'x' : 'l');
1666           if (reason_text)
1667             es_fprintf (es_stdout, ",%02x", reason_code);
1668           es_fputs ("::", es_stdout);
1669
1670           if (opt.no_sig_cache && opt.check_sigs && fprokay)
1671             {
1672               for (i = 0; i < fplen; i++)
1673                 es_fprintf (es_stdout, "%02X", fparray[i]);
1674             }
1675           else if ((issuer_fpr = issuer_fpr_string (sig)))
1676             es_fputs (issuer_fpr, es_stdout);
1677
1678           es_fprintf (es_stdout, ":::%d:", sig->digest_algo);
1679
1680           if (reason_comment)
1681             {
1682               es_fputs ("::::", es_stdout);
1683               es_write_sanitized (es_stdout, reason_comment, reason_commentlen,
1684                                   ":", NULL);
1685               es_putc (':', es_stdout);
1686             }
1687           es_putc ('\n', es_stdout);
1688
1689           if (opt.show_subpackets)
1690             print_subpackets_colon (sig);
1691
1692           /* fixme: check or list other sigs here */
1693           xfree (reason_text);
1694           xfree (reason_comment);
1695           xfree (siguid);
1696           xfree (issuer_fpr);
1697         }
1698     }
1699
1700   xfree (curve);
1701   xfree (hexgrip_buffer);
1702   xfree (serialno);
1703 }
1704
1705 /*
1706  * Reorder the keyblock so that the primary user ID (and not attribute
1707  * packet) comes first.  Fixme: Replace this by a generic sort
1708  * function.  */
1709 static void
1710 do_reorder_keyblock (KBNODE keyblock, int attr)
1711 {
1712   KBNODE primary = NULL, primary0 = NULL, primary2 = NULL;
1713   KBNODE last, node;
1714
1715   for (node = keyblock; node; primary0 = node, node = node->next)
1716     {
1717       if (node->pkt->pkttype == PKT_USER_ID &&
1718           ((attr && node->pkt->pkt.user_id->attrib_data) ||
1719            (!attr && !node->pkt->pkt.user_id->attrib_data)) &&
1720           node->pkt->pkt.user_id->flags.primary)
1721         {
1722           primary = primary2 = node;
1723           for (node = node->next; node; primary2 = node, node = node->next)
1724             {
1725               if (node->pkt->pkttype == PKT_USER_ID
1726                   || node->pkt->pkttype == PKT_PUBLIC_SUBKEY
1727                   || node->pkt->pkttype == PKT_SECRET_SUBKEY)
1728                 {
1729                   break;
1730                 }
1731             }
1732           break;
1733         }
1734     }
1735   if (!primary)
1736     return; /* No primary key flag found (should not happen).  */
1737
1738   for (last = NULL, node = keyblock; node; last = node, node = node->next)
1739     {
1740       if (node->pkt->pkttype == PKT_USER_ID)
1741         break;
1742     }
1743   log_assert (node);
1744   log_assert (last);     /* The user ID is never the first packet.  */
1745   log_assert (primary0); /* Ditto (this is the node before primary).  */
1746   if (node == primary)
1747     return; /* Already the first one.  */
1748
1749   last->next = primary;
1750   primary0->next = primary2->next;
1751   primary2->next = node;
1752 }
1753
1754 void
1755 reorder_keyblock (KBNODE keyblock)
1756 {
1757   do_reorder_keyblock (keyblock, 1);
1758   do_reorder_keyblock (keyblock, 0);
1759 }
1760
1761 static void
1762 list_keyblock (ctrl_t ctrl,
1763                KBNODE keyblock, int secret, int has_secret, int fpr,
1764                struct keylist_context *listctx)
1765 {
1766   reorder_keyblock (keyblock);
1767
1768   if (opt.with_colons)
1769     list_keyblock_colon (ctrl, keyblock, secret, has_secret);
1770   else
1771     list_keyblock_print (ctrl, keyblock, secret, fpr, listctx);
1772
1773   if (secret)
1774     es_fflush (es_stdout);
1775 }
1776
1777
1778 /* Public function used by keygen to list a keyblock.  If NO_VALIDITY
1779  * is set the validity of a key is never shown.  */
1780 void
1781 list_keyblock_direct (ctrl_t ctrl,
1782                       kbnode_t keyblock, int secret, int has_secret, int fpr,
1783                       int no_validity)
1784 {
1785   struct keylist_context listctx;
1786
1787   memset (&listctx, 0, sizeof (listctx));
1788   listctx.no_validity = !!no_validity;
1789   list_keyblock (ctrl, keyblock, secret, has_secret, fpr, &listctx);
1790   keylist_context_release (&listctx);
1791 }
1792
1793
1794 /* Print an hex digit in ICAO spelling.  */
1795 static void
1796 print_icao_hexdigit (estream_t fp, int c)
1797 {
1798   static const char *list[16] = {
1799     "Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven",
1800     "Eight", "Niner", "Alfa", "Bravo", "Charlie", "Delta", "Echo", "Foxtrot"
1801   };
1802
1803   tty_fprintf (fp, "%s", list[c&15]);
1804 }
1805
1806
1807 /*
1808  * Function to print the finperprint.
1809  * mode 0: as used in key listings, opt.with_colons is honored
1810  *      1: print using log_info ()
1811  *      2: direct use of tty
1812  *      3: direct use of tty but only primary key.
1813  *      4: direct use of tty but only subkey.
1814  *     10: Same as 0 but with_colons etc is ignored.
1815  *     20: Same as 0 but using a compact format.
1816  *
1817  * Modes 1 and 2 will try and print both subkey and primary key
1818  * fingerprints.  A MODE with bit 7 set is used internally.  If
1819  * OVERRIDE_FP is not NULL that stream will be used in  0 instead
1820  * of es_stdout or instead of the TTY in modes 2 and 3.
1821  */
1822 void
1823 print_fingerprint (ctrl_t ctrl, estream_t override_fp,
1824                    PKT_public_key *pk, int mode)
1825 {
1826   char hexfpr[2*MAX_FINGERPRINT_LEN+1];
1827   char *p;
1828   size_t i;
1829   estream_t fp;
1830   const char *text;
1831   int primary = 0;
1832   int with_colons = opt.with_colons;
1833   int with_icao   = opt.with_icao_spelling;
1834   int compact = 0;
1835
1836   if (mode == 10)
1837     {
1838       mode = 0;
1839       with_colons = 0;
1840       with_icao = 0;
1841     }
1842   else if (mode == 20)
1843     {
1844       mode = 0;
1845       with_colons = 0;
1846       compact = 1;
1847     }
1848
1849   if (!opt.fingerprint && !opt.with_fingerprint
1850       && opt.with_subkey_fingerprint)
1851     compact = 1;
1852
1853   if (pk->main_keyid[0] == pk->keyid[0]
1854       && pk->main_keyid[1] == pk->keyid[1])
1855     primary = 1;
1856
1857   /* Just to be safe */
1858   if ((mode & 0x80) && !primary)
1859     {
1860       log_error ("primary key is not really primary!\n");
1861       return;
1862     }
1863
1864   mode &= ~0x80;
1865
1866   if (!primary && (mode == 1 || mode == 2))
1867     {
1868       PKT_public_key *primary_pk = xmalloc_clear (sizeof (*primary_pk));
1869       get_pubkey (ctrl, primary_pk, pk->main_keyid);
1870       print_fingerprint (ctrl, override_fp, primary_pk, (mode | 0x80));
1871       free_public_key (primary_pk);
1872     }
1873
1874   if (mode == 1)
1875     {
1876       fp = log_get_stream ();
1877       if (primary)
1878         text = _("Primary key fingerprint:");
1879       else
1880         text = _("     Subkey fingerprint:");
1881     }
1882   else if (mode == 2)
1883     {
1884       fp = override_fp; /* Use tty or given stream.  */
1885       if (primary)
1886         /* TRANSLATORS: this should fit into 24 bytes so that the
1887          * fingerprint data is properly aligned with the user ID */
1888         text = _(" Primary key fingerprint:");
1889       else
1890         text = _("      Subkey fingerprint:");
1891     }
1892   else if (mode == 3)
1893     {
1894       fp = override_fp; /* Use tty or given stream.  */
1895       text = _("      Key fingerprint =");
1896     }
1897   else if (mode == 4)
1898     {
1899       fp = override_fp; /* Use tty or given stream.  */
1900       text = _("      Subkey fingerprint:");
1901     }
1902   else
1903     {
1904       fp = override_fp? override_fp : es_stdout;
1905       if (opt.keyid_format == KF_NONE)
1906         {
1907           text = "     ";  /* To indent ICAO spelling.  */
1908           compact = 1;
1909         }
1910       else
1911         text = _("      Key fingerprint =");
1912     }
1913
1914   hexfingerprint (pk, hexfpr, sizeof hexfpr);
1915   if (with_colons && !mode)
1916     {
1917       es_fprintf (fp, "fpr:::::::::%s:", hexfpr);
1918     }
1919   else if (compact && !opt.fingerprint && !opt.with_fingerprint)
1920     {
1921       tty_fprintf (fp, "%*s%s", 6, "", hexfpr);
1922     }
1923   else
1924     {
1925       char fmtfpr[MAX_FORMATTED_FINGERPRINT_LEN + 1];
1926       format_hexfingerprint (hexfpr, fmtfpr, sizeof fmtfpr);
1927       if (compact)
1928         tty_fprintf (fp, "%*s%s", 6, "", fmtfpr);
1929       else
1930         tty_fprintf (fp, "%s %s", text, fmtfpr);
1931     }
1932   tty_fprintf (fp, "\n");
1933   if (!with_colons && with_icao)
1934     {
1935       ;
1936       tty_fprintf (fp, "%*s\"", (int)strlen(text)+1, "");
1937       for (i = 0, p = hexfpr; *p; i++, p++)
1938         {
1939           if (!i)
1940             ;
1941           else if (!(i%8))
1942             tty_fprintf (fp, "\n%*s ", (int)strlen(text)+1, "");
1943           else if (!(i%4))
1944             tty_fprintf (fp, "  ");
1945           else
1946             tty_fprintf (fp, " ");
1947           print_icao_hexdigit (fp, xtoi_1 (p));
1948         }
1949       tty_fprintf (fp, "\"\n");
1950     }
1951 }
1952
1953 /* Print the serial number of an OpenPGP card if available.  */
1954 static void
1955 print_card_serialno (const char *serialno)
1956 {
1957   if (!serialno)
1958     return;
1959   if (opt.with_colons)
1960     return; /* Handled elsewhere. */
1961
1962   es_fputs (_("      Card serial no. ="), es_stdout);
1963   es_putc (' ', es_stdout);
1964   if (strlen (serialno) == 32 && !strncmp (serialno, "D27600012401", 12))
1965     {
1966       /* This is an OpenPGP card.  Print the relevant part.  */
1967       /* Example: D2760001240101010001000003470000 */
1968       /*                          xxxxyyyyyyyy     */
1969       es_fprintf (es_stdout, "%.*s %.*s", 4, serialno+16, 8, serialno+20);
1970     }
1971  else
1972    es_fputs (serialno, es_stdout);
1973   es_putc ('\n', es_stdout);
1974 }
1975
1976
1977 /* Print a public or secret (sub)key line.  Example:
1978  *
1979  * pub   dsa2048 2007-12-31 [SC] [expires: 2018-12-31]
1980  *       80615870F5BAD690333686D0F2AD85AC1E42B367
1981  *
1982  * Some global options may result in a different output format.  If
1983  * SECRET is set, "sec" or "ssb" is used instead of "pub" or "sub" and
1984  * depending on the value a flag character is shown:
1985  *
1986  *    1 := ' ' Regular secret key
1987  *    2 := '#' Stub secret key
1988  *    3 := '>' Secret key is on a token.
1989  */
1990 void
1991 print_key_line (ctrl_t ctrl, estream_t fp, PKT_public_key *pk, int secret)
1992 {
1993   char pkstrbuf[PUBKEY_STRING_SIZE];
1994
1995   tty_fprintf (fp, "%s%c  %s",
1996                pk->flags.primary? (secret? "sec":"pub")
1997                /**/             : (secret? "ssb":"sub"),
1998                secret == 2? '#' : secret == 3? '>' : ' ',
1999                pubkey_string (pk, pkstrbuf, sizeof pkstrbuf));
2000   if (opt.keyid_format != KF_NONE)
2001     tty_fprintf (fp, "/%s", keystr_from_pk (pk));
2002   tty_fprintf (fp, " %s", datestr_from_pk (pk));
2003
2004   if ((opt.list_options & LIST_SHOW_USAGE))
2005     {
2006       tty_fprintf (fp, " [%s]", usagestr_from_pk (pk, 0));
2007     }
2008   if (pk->flags.revoked)
2009     {
2010       tty_fprintf (fp, " [");
2011       tty_fprintf (fp, _("revoked: %s"), revokestr_from_pk (pk));
2012       tty_fprintf (fp, "]");
2013     }
2014   else if (pk->has_expired)
2015     {
2016       tty_fprintf (fp, " [");
2017       tty_fprintf (fp, _("expired: %s"), expirestr_from_pk (pk));
2018       tty_fprintf (fp, "]");
2019     }
2020   else if (pk->expiredate)
2021     {
2022       tty_fprintf (fp, " [");
2023       tty_fprintf (fp, _("expires: %s"), expirestr_from_pk (pk));
2024       tty_fprintf (fp, "]");
2025     }
2026
2027 #if 0
2028   /* I need to think about this some more.  It's easy enough to
2029      include, but it looks sort of confusing in the listing... */
2030   if (opt.list_options & LIST_SHOW_VALIDITY)
2031     {
2032       int validity = get_validity (ctrl, pk, NULL, NULL, 0);
2033       tty_fprintf (fp, " [%s]", trust_value_to_string (validity));
2034     }
2035 #endif
2036
2037   if (pk->pubkey_algo >= 100)
2038     tty_fprintf (fp, " [experimental algorithm %d]", pk->pubkey_algo);
2039
2040   tty_fprintf (fp, "\n");
2041
2042   /* if the user hasn't explicitly asked for human-readable
2043      fingerprints, show compact fpr of primary key: */
2044   if (pk->flags.primary &&
2045       !opt.fingerprint && !opt.with_fingerprint)
2046     print_fingerprint (ctrl, fp, pk, 20);
2047 }
2048
2049
2050 void
2051 set_attrib_fd (int fd)
2052 {
2053   static int last_fd = -1;
2054
2055   if (fd != -1 && last_fd == fd)
2056     return;
2057
2058   /* Fixme: Do we need to check for the log stream here?  */
2059   if (attrib_fp && attrib_fp != log_get_stream ())
2060     es_fclose (attrib_fp);
2061   attrib_fp = NULL;
2062   if (fd == -1)
2063     return;
2064
2065   if (! gnupg_fd_valid (fd))
2066     log_fatal ("attribute-fd is invalid: %s\n", strerror (errno));
2067
2068 #ifdef HAVE_DOSISH_SYSTEM
2069   setmode (fd, O_BINARY);
2070 #endif
2071   if (fd == 1)
2072     attrib_fp = es_stdout;
2073   else if (fd == 2)
2074     attrib_fp = es_stderr;
2075   else
2076     attrib_fp = es_fdopen (fd, "wb");
2077   if (!attrib_fp)
2078     {
2079       log_fatal ("can't open fd %d for attribute output: %s\n",
2080                  fd, strerror (errno));
2081     }
2082
2083   last_fd = fd;
2084 }