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