Imported Upstream version 2.2.17
[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, int no_local);
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 key; if
86  * in addition NO_LOCAL is set the locate does not look into the local
87  * keyring.  */
88 void
89 public_key_list (ctrl_t ctrl, strlist_t list, int locate_mode, int no_local)
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, no_local);
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           if (gpg_err_code (rc) == GPG_ERR_UNKNOWN_VERSION)
532             continue;  /* Skip keys with unknown versions.  */
533           log_error ("keydb_get_keyblock failed: %s\n", gpg_strerror (rc));
534           goto leave;
535         }
536
537       if (secret || mark_secret)
538         any_secret = !agent_probe_any_secret_key (NULL, keyblock);
539       else
540         any_secret = 0;
541
542       if (secret && !any_secret)
543         ; /* Secret key listing requested but this isn't one.  */
544       else
545         {
546           if (!opt.with_colons && !(opt.list_options & LIST_SHOW_ONLY_FPR_MBOX))
547             {
548               resname = keydb_get_resource_name (hd);
549               if (lastresname != resname)
550                 {
551                   int i;
552
553                   es_fprintf (es_stdout, "%s\n", resname);
554                   for (i = strlen (resname); i; i--)
555                     es_putc ('-', es_stdout);
556                   es_putc ('\n', es_stdout);
557                   lastresname = resname;
558                 }
559             }
560           merge_keys_and_selfsig (ctrl, keyblock);
561           list_keyblock (ctrl, keyblock, secret, any_secret, opt.fingerprint,
562                          &listctx);
563         }
564       release_kbnode (keyblock);
565       keyblock = NULL;
566     }
567   while (!(rc = keydb_search_next (hd)));
568   es_fflush (es_stdout);
569   if (rc && gpg_err_code (rc) != GPG_ERR_NOT_FOUND)
570     log_error ("keydb_search_next failed: %s\n", gpg_strerror (rc));
571   if (keydb_get_skipped_counter (hd))
572     log_info (ngettext("Warning: %lu key skipped due to its large size\n",
573                        "Warning: %lu keys skipped due to their large sizes\n",
574                        keydb_get_skipped_counter (hd)),
575               keydb_get_skipped_counter (hd));
576
577   if (opt.check_sigs && !opt.with_colons)
578     print_signature_stats (&listctx);
579
580  leave:
581   keylist_context_release (&listctx);
582   release_kbnode (keyblock);
583   keydb_release (hd);
584 }
585
586
587 static void
588 list_one (ctrl_t ctrl, strlist_t names, int secret, int mark_secret)
589 {
590   int rc = 0;
591   KBNODE keyblock = NULL;
592   GETKEY_CTX ctx;
593   const char *resname;
594   const char *keyring_str = _("Keyring");
595   int i;
596   struct keylist_context listctx;
597
598   memset (&listctx, 0, sizeof (listctx));
599   if (!secret && opt.check_sigs)
600     listctx.check_sigs = 1;
601
602   /* fixme: using the bynames function has the disadvantage that we
603    * don't know whether one of the names given was not found.  OTOH,
604    * this function has the advantage to list the names in the
605    * sequence as defined by the keyDB and does not duplicate
606    * outputs.  A solution could be do test whether all given have
607    * been listed (this needs a way to use the keyDB search
608    * functions) or to have the search function return indicators for
609    * found names.  Yet another way is to use the keydb search
610    * facilities directly. */
611   rc = getkey_bynames (ctrl, &ctx, NULL, names, secret, &keyblock);
612   if (rc)
613     {
614       log_error ("error reading key: %s\n", gpg_strerror (rc));
615       getkey_end (ctrl, ctx);
616       write_status_error ("keylist.getkey", rc);
617       return;
618     }
619
620   do
621     {
622       if ((opt.list_options & LIST_SHOW_KEYRING) && !opt.with_colons)
623         {
624           resname = keydb_get_resource_name (get_ctx_handle (ctx));
625           es_fprintf (es_stdout, "%s: %s\n", keyring_str, resname);
626           for (i = strlen (resname) + strlen (keyring_str) + 2; i; i--)
627             es_putc ('-', es_stdout);
628           es_putc ('\n', es_stdout);
629         }
630       list_keyblock (ctrl,
631                      keyblock, secret, mark_secret, opt.fingerprint, &listctx);
632       release_kbnode (keyblock);
633     }
634   while (!getkey_next (ctrl, ctx, NULL, &keyblock));
635   getkey_end (ctrl, ctx);
636
637   if (opt.check_sigs && !opt.with_colons)
638     print_signature_stats (&listctx);
639
640   keylist_context_release (&listctx);
641 }
642
643
644 static void
645 locate_one (ctrl_t ctrl, strlist_t names, int no_local)
646 {
647   int rc = 0;
648   strlist_t sl;
649   GETKEY_CTX ctx = NULL;
650   KBNODE keyblock = NULL;
651   struct keylist_context listctx;
652
653   memset (&listctx, 0, sizeof (listctx));
654   if (opt.check_sigs)
655     listctx.check_sigs = 1;
656
657   for (sl = names; sl; sl = sl->next)
658     {
659       rc = get_best_pubkey_byname (ctrl,
660                                    no_local? GET_PUBKEY_NO_LOCAL
661                                    /*    */: GET_PUBKEY_NORMAL,
662                                    &ctx, NULL, sl->d, &keyblock, 1);
663       if (rc)
664         {
665           if (gpg_err_code (rc) != GPG_ERR_NO_PUBKEY)
666             log_error ("error reading key: %s\n", gpg_strerror (rc));
667           else if (opt.verbose)
668             log_info (_("key \"%s\" not found: %s\n"),
669                       sl->d, gpg_strerror (rc));
670         }
671       else
672         {
673           do
674             {
675               list_keyblock (ctrl, keyblock, 0, 0, opt.fingerprint, &listctx);
676               release_kbnode (keyblock);
677             }
678           while (ctx && !getkey_next (ctrl, ctx, NULL, &keyblock));
679           getkey_end (ctrl, ctx);
680           ctx = NULL;
681         }
682     }
683
684   if (opt.check_sigs && !opt.with_colons)
685     print_signature_stats (&listctx);
686
687   keylist_context_release (&listctx);
688 }
689
690
691 static void
692 print_key_data (PKT_public_key * pk)
693 {
694   int n = pk ? pubkey_get_npkey (pk->pubkey_algo) : 0;
695   int i;
696
697   for (i = 0; i < n; i++)
698     {
699       es_fprintf (es_stdout, "pkd:%d:%u:", i, mpi_get_nbits (pk->pkey[i]));
700       mpi_print (es_stdout, pk->pkey[i], 1);
701       es_putc (':', es_stdout);
702       es_putc ('\n', es_stdout);
703     }
704 }
705
706 static void
707 print_capabilities (ctrl_t ctrl, PKT_public_key *pk, KBNODE keyblock)
708 {
709   unsigned int use = pk->pubkey_usage;
710   int c_printed = 0;
711
712   if (use & PUBKEY_USAGE_ENC)
713     es_putc ('e', es_stdout);
714
715   if (use & PUBKEY_USAGE_SIG)
716     {
717       es_putc ('s', es_stdout);
718       if (pk->flags.primary)
719         {
720           es_putc ('c', es_stdout);
721           /* The PUBKEY_USAGE_CERT flag was introduced later and we
722              used to always print 'c' for a primary key.  To avoid any
723              regression here we better track whether we printed 'c'
724              already.  */
725           c_printed = 1;
726         }
727     }
728
729   if ((use & PUBKEY_USAGE_CERT) && !c_printed)
730     es_putc ('c', es_stdout);
731
732   if ((use & PUBKEY_USAGE_AUTH))
733     es_putc ('a', es_stdout);
734
735   if ((use & PUBKEY_USAGE_UNKNOWN))
736     es_putc ('?', es_stdout);
737
738   if (keyblock)
739     {
740       /* Figure out the usable capabilities.  */
741       KBNODE k;
742       int enc = 0, sign = 0, cert = 0, auth = 0, disabled = 0;
743
744       for (k = keyblock; k; k = k->next)
745         {
746           if (k->pkt->pkttype == PKT_PUBLIC_KEY
747               || k->pkt->pkttype == PKT_PUBLIC_SUBKEY)
748             {
749               pk = k->pkt->pkt.public_key;
750
751               if (pk->flags.primary)
752                 disabled = pk_is_disabled (pk);
753
754               if (pk->flags.valid && !pk->flags.revoked && !pk->has_expired)
755                 {
756                   if (pk->pubkey_usage & PUBKEY_USAGE_ENC)
757                     enc = 1;
758                   if (pk->pubkey_usage & PUBKEY_USAGE_SIG)
759                     {
760                       sign = 1;
761                       if (pk->flags.primary)
762                         cert = 1;
763                     }
764                   if (pk->pubkey_usage & PUBKEY_USAGE_CERT)
765                     cert = 1;
766                   if ((pk->pubkey_usage & PUBKEY_USAGE_AUTH))
767                     auth = 1;
768                 }
769             }
770         }
771       if (enc)
772         es_putc ('E', es_stdout);
773       if (sign)
774         es_putc ('S', es_stdout);
775       if (cert)
776         es_putc ('C', es_stdout);
777       if (auth)
778         es_putc ('A', es_stdout);
779       if (disabled)
780         es_putc ('D', es_stdout);
781     }
782
783   es_putc (':', es_stdout);
784 }
785
786
787 /* FLAGS: 0x01 hashed
788           0x02 critical  */
789 static void
790 print_one_subpacket (sigsubpkttype_t type, size_t len, int flags,
791                      const byte * buf)
792 {
793   size_t i;
794
795   es_fprintf (es_stdout, "spk:%d:%u:%u:", type, flags, (unsigned int) len);
796
797   for (i = 0; i < len; i++)
798     {
799       /* printable ascii other than : and % */
800       if (buf[i] >= 32 && buf[i] <= 126 && buf[i] != ':' && buf[i] != '%')
801         es_fprintf (es_stdout, "%c", buf[i]);
802       else
803         es_fprintf (es_stdout, "%%%02X", buf[i]);
804     }
805
806   es_fprintf (es_stdout, "\n");
807 }
808
809
810 void
811 print_subpackets_colon (PKT_signature * sig)
812 {
813   byte *i;
814
815   log_assert (opt.show_subpackets);
816
817   for (i = opt.show_subpackets; *i; i++)
818     {
819       const byte *p;
820       size_t len;
821       int seq, crit;
822
823       seq = 0;
824
825       while ((p = enum_sig_subpkt (sig->hashed, *i, &len, &seq, &crit)))
826         print_one_subpacket (*i, len, 0x01 | (crit ? 0x02 : 0), p);
827
828       seq = 0;
829
830       while ((p = enum_sig_subpkt (sig->unhashed, *i, &len, &seq, &crit)))
831         print_one_subpacket (*i, len, 0x00 | (crit ? 0x02 : 0), p);
832     }
833 }
834
835
836 void
837 dump_attribs (const PKT_user_id *uid, PKT_public_key *pk)
838 {
839   int i;
840
841   if (!attrib_fp)
842     return;
843
844   for (i = 0; i < uid->numattribs; i++)
845     {
846       if (is_status_enabled ())
847         {
848           byte array[MAX_FINGERPRINT_LEN], *p;
849           char buf[(MAX_FINGERPRINT_LEN * 2) + 90];
850           size_t j, n;
851
852           if (!pk)
853             BUG ();
854           fingerprint_from_pk (pk, array, &n);
855
856           p = array;
857           for (j = 0; j < n; j++, p++)
858             sprintf (buf + 2 * j, "%02X", *p);
859
860           sprintf (buf + strlen (buf), " %lu %u %u %u %lu %lu %u",
861                    (ulong) uid->attribs[i].len, uid->attribs[i].type, i + 1,
862                    uid->numattribs, (ulong) uid->created,
863                    (ulong) uid->expiredate,
864                    ((uid->flags.primary ? 0x01 : 0) | (uid->flags.revoked ? 0x02 : 0) |
865                     (uid->flags.expired ? 0x04 : 0)));
866           write_status_text (STATUS_ATTRIBUTE, buf);
867         }
868
869       es_fwrite (uid->attribs[i].data, uid->attribs[i].len, 1, attrib_fp);
870       es_fflush (attrib_fp);
871     }
872 }
873
874
875 static void
876 list_keyblock_print (ctrl_t ctrl, kbnode_t keyblock, int secret, int fpr,
877                      struct keylist_context *listctx)
878 {
879   int rc;
880   KBNODE kbctx;
881   KBNODE node;
882   PKT_public_key *pk;
883   int skip_sigs = 0;
884   char *hexgrip = NULL;
885   char *serialno = NULL;
886
887   /* Get the keyid from the keyblock.  */
888   node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
889   if (!node)
890     {
891       log_error ("Oops; key lost!\n");
892       dump_kbnode (keyblock);
893       return;
894     }
895
896   pk = node->pkt->pkt.public_key;
897
898   if (secret || opt.with_keygrip)
899     {
900       rc = hexkeygrip_from_pk (pk, &hexgrip);
901       if (rc)
902         log_error ("error computing a keygrip: %s\n", gpg_strerror (rc));
903     }
904
905   if (secret)
906     {
907       /* Encode some info about the secret key in SECRET.  */
908       if (!agent_get_keyinfo (NULL, hexgrip, &serialno, NULL))
909         secret = serialno? 3 : 1;
910       else
911         secret = 2;  /* Key not found.  */
912     }
913
914   if (!listctx->no_validity)
915     check_trustdb_stale (ctrl);
916
917   /* Print the "pub" line and in KF_NONE mode the fingerprint.  */
918   print_key_line (ctrl, es_stdout, pk, secret);
919
920   if (fpr)
921     print_fingerprint (ctrl, NULL, pk, 0);
922
923   if (opt.with_keygrip && hexgrip)
924     es_fprintf (es_stdout, "      Keygrip = %s\n", hexgrip);
925
926   if (serialno)
927     print_card_serialno (serialno);
928
929   if (opt.with_key_data)
930     print_key_data (pk);
931
932   if (opt.with_key_origin
933       && (pk->keyorg || pk->keyupdate || pk->updateurl))
934     {
935       char updatestr[MK_DATESTR_SIZE];
936
937       es_fprintf (es_stdout, "      origin=%s last=%s %s",
938                   key_origin_string (pk->keyorg),
939                   mk_datestr (updatestr, sizeof updatestr, pk->keyupdate),
940                   pk->updateurl? "url=":"");
941       if (pk->updateurl)
942         print_utf8_string (es_stdout, pk->updateurl);
943       es_putc ('\n', es_stdout);
944     }
945
946
947   for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0));)
948     {
949       if (node->pkt->pkttype == PKT_USER_ID)
950         {
951           PKT_user_id *uid = node->pkt->pkt.user_id;
952           int indent;
953           int kl = opt.keyid_format == KF_NONE? 10 : keystrlen ();
954
955           if ((uid->flags.expired || uid->flags.revoked)
956               && !(opt.list_options & LIST_SHOW_UNUSABLE_UIDS))
957             {
958               skip_sigs = 1;
959               continue;
960             }
961           else
962             skip_sigs = 0;
963
964           if (attrib_fp && uid->attrib_data != NULL)
965             dump_attribs (uid, pk);
966
967           if ((uid->flags.revoked || uid->flags.expired)
968               || ((opt.list_options & LIST_SHOW_UID_VALIDITY)
969                   && !listctx->no_validity))
970             {
971               const char *validity;
972
973               validity = uid_trust_string_fixed (ctrl, pk, uid);
974               indent = ((kl + (opt.legacy_list_mode? 9:11))
975                         - atoi (uid_trust_string_fixed (ctrl, NULL, NULL)));
976               if (indent < 0 || indent > 40)
977                 indent = 0;
978
979               es_fprintf (es_stdout, "uid%*s%s ", indent, "", validity);
980             }
981           else
982             {
983               indent = kl + (opt.legacy_list_mode? 10:12);
984               es_fprintf (es_stdout, "uid%*s", indent, "");
985             }
986
987           print_utf8_buffer (es_stdout, uid->name, uid->len);
988           es_putc ('\n', es_stdout);
989
990           if (opt.with_wkd_hash)
991             {
992               char *mbox, *hash, *p;
993               char hashbuf[32];
994
995               mbox = mailbox_from_userid (uid->name);
996               if (mbox && (p = strchr (mbox, '@')))
997                 {
998                   *p++ = 0;
999                   gcry_md_hash_buffer (GCRY_MD_SHA1, hashbuf,
1000                                        mbox, strlen (mbox));
1001                   hash = zb32_encode (hashbuf, 8*20);
1002                   if (hash)
1003                     {
1004                       es_fprintf (es_stdout, "   %*s%s@%s\n",
1005                                   indent, "", hash, p);
1006                       xfree (hash);
1007                     }
1008                 }
1009               xfree (mbox);
1010             }
1011
1012           if (opt.with_key_origin
1013               && (uid->keyorg || uid->keyupdate || uid->updateurl))
1014             {
1015               char updatestr[MK_DATESTR_SIZE];
1016
1017               es_fprintf (es_stdout, "   %*sorigin=%s last=%s %s",
1018                           indent, "",
1019                           key_origin_string (uid->keyorg),
1020                           mk_datestr (updatestr, sizeof updatestr,
1021                                       uid->keyupdate),
1022                           uid->updateurl? "url=":"");
1023               if (uid->updateurl)
1024                 print_utf8_string (es_stdout, uid->updateurl);
1025               es_putc ('\n', es_stdout);
1026             }
1027
1028           if ((opt.list_options & LIST_SHOW_PHOTOS) && uid->attribs != NULL)
1029             show_photos (ctrl, uid->attribs, uid->numattribs, pk, uid);
1030         }
1031       else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
1032         {
1033           PKT_public_key *pk2 = node->pkt->pkt.public_key;
1034
1035           if ((pk2->flags.revoked || pk2->has_expired)
1036               && !(opt.list_options & LIST_SHOW_UNUSABLE_SUBKEYS))
1037             {
1038               skip_sigs = 1;
1039               continue;
1040             }
1041           else
1042             skip_sigs = 0;
1043
1044           xfree (serialno); serialno = NULL;
1045           xfree (hexgrip); hexgrip = NULL;
1046           if (secret || opt.with_keygrip)
1047             {
1048               rc = hexkeygrip_from_pk (pk2, &hexgrip);
1049               if (rc)
1050                 log_error ("error computing a keygrip: %s\n",
1051                            gpg_strerror (rc));
1052             }
1053           if (secret)
1054             {
1055               if (!agent_get_keyinfo (NULL, hexgrip, &serialno, NULL))
1056                 secret = serialno? 3 : 1;
1057               else
1058                 secret = 2;  /* Key not found.  */
1059             }
1060
1061           /* Print the "sub" line.  */
1062           print_key_line (ctrl, es_stdout, pk2, secret);
1063           if (fpr > 1 || opt.with_subkey_fingerprint)
1064             {
1065               print_fingerprint (ctrl, NULL, pk2, 0);
1066               if (serialno)
1067                 print_card_serialno (serialno);
1068             }
1069           if (opt.with_keygrip && hexgrip)
1070             es_fprintf (es_stdout, "      Keygrip = %s\n", hexgrip);
1071           if (opt.with_key_data)
1072             print_key_data (pk2);
1073         }
1074       else if (opt.list_sigs
1075                && node->pkt->pkttype == PKT_SIGNATURE && !skip_sigs)
1076         {
1077           PKT_signature *sig = node->pkt->pkt.signature;
1078           int sigrc;
1079           char *sigstr;
1080           char *reason_text = NULL;
1081           char *reason_comment = NULL;
1082           size_t reason_commentlen;
1083
1084           if (listctx->check_sigs)
1085             {
1086               rc = check_key_signature (ctrl, keyblock, node, NULL);
1087               switch (gpg_err_code (rc))
1088                 {
1089                 case 0:
1090                   listctx->good_sigs++;
1091                   sigrc = '!';
1092                   break;
1093                 case GPG_ERR_BAD_SIGNATURE:
1094                   listctx->inv_sigs++;
1095                   sigrc = '-';
1096                   break;
1097                 case GPG_ERR_NO_PUBKEY:
1098                 case GPG_ERR_UNUSABLE_PUBKEY:
1099                   listctx->no_key++;
1100                   continue;
1101                 default:
1102                   listctx->oth_err++;
1103                   sigrc = '%';
1104                   break;
1105                 }
1106
1107               /* TODO: Make sure a cached sig record here still has
1108                  the pk that issued it.  See also
1109                  keyedit.c:print_and_check_one_sig */
1110             }
1111           else
1112             {
1113               rc = 0;
1114               sigrc = ' ';
1115             }
1116
1117           if (sig->sig_class == 0x20 || sig->sig_class == 0x28
1118               || sig->sig_class == 0x30)
1119             {
1120               sigstr = "rev";
1121               get_revocation_reason (sig, &reason_text,
1122                                      &reason_comment, &reason_commentlen);
1123             }
1124           else if ((sig->sig_class & ~3) == 0x10)
1125             sigstr = "sig";
1126           else if (sig->sig_class == 0x18)
1127             sigstr = "sig";
1128           else if (sig->sig_class == 0x1F)
1129             sigstr = "sig";
1130           else
1131             {
1132               es_fprintf (es_stdout, "sig                             "
1133                       "[unexpected signature class 0x%02x]\n",
1134                       sig->sig_class);
1135               continue;
1136             }
1137
1138           es_fputs (sigstr, es_stdout);
1139           es_fprintf (es_stdout, "%c%c %c%c%c%c%c%c %s %s",
1140                   sigrc, (sig->sig_class - 0x10 > 0 &&
1141                           sig->sig_class - 0x10 <
1142                           4) ? '0' + sig->sig_class - 0x10 : ' ',
1143                   sig->flags.exportable ? ' ' : 'L',
1144                   sig->flags.revocable ? ' ' : 'R',
1145                   sig->flags.policy_url ? 'P' : ' ',
1146                   sig->flags.notation ? 'N' : ' ',
1147                   sig->flags.expired ? 'X' : ' ',
1148                   (sig->trust_depth > 9) ? 'T' : (sig->trust_depth >
1149                                                   0) ? '0' +
1150                   sig->trust_depth : ' ', keystr (sig->keyid),
1151                   datestr_from_sig (sig));
1152           if (opt.list_options & LIST_SHOW_SIG_EXPIRE)
1153             es_fprintf (es_stdout, " %s", expirestr_from_sig (sig));
1154           es_fprintf (es_stdout, "  ");
1155           if (sigrc == '%')
1156             es_fprintf (es_stdout, "[%s] ", gpg_strerror (rc));
1157           else if (sigrc == '?')
1158             ;
1159           else if (!opt.fast_list_mode)
1160             {
1161               size_t n;
1162               char *p = get_user_id (ctrl, sig->keyid, &n, NULL);
1163               print_utf8_buffer (es_stdout, p, n);
1164               xfree (p);
1165             }
1166           es_putc ('\n', es_stdout);
1167
1168           if (sig->flags.policy_url
1169               && (opt.list_options & LIST_SHOW_POLICY_URLS))
1170             show_policy_url (sig, 3, 0);
1171
1172           if (sig->flags.notation && (opt.list_options & LIST_SHOW_NOTATIONS))
1173             show_notation (sig, 3, 0,
1174                            ((opt.
1175                              list_options & LIST_SHOW_STD_NOTATIONS) ? 1 : 0)
1176                            +
1177                            ((opt.
1178                              list_options & LIST_SHOW_USER_NOTATIONS) ? 2 :
1179                             0));
1180
1181           if (sig->flags.pref_ks
1182               && (opt.list_options & LIST_SHOW_KEYSERVER_URLS))
1183             show_keyserver_url (sig, 3, 0);
1184
1185           if (reason_text)
1186             {
1187               es_fprintf (es_stdout, "      %s%s\n",
1188                           _("reason for revocation: "), reason_text);
1189               if (reason_comment)
1190                 {
1191                   const byte *s, *s_lf;
1192                   size_t n, n_lf;
1193
1194                   s = reason_comment;
1195                   n = reason_commentlen;
1196                   s_lf = NULL;
1197                   do
1198                     {
1199                       /* We don't want any empty lines, so we skip them.  */
1200                       for (;n && *s == '\n'; s++, n--)
1201                         ;
1202                       if (n)
1203                         {
1204                           s_lf = memchr (s, '\n', n);
1205                           n_lf = s_lf? s_lf - s : n;
1206                           es_fprintf (es_stdout, "         %s",
1207                                       _("revocation comment: "));
1208                           es_write_sanitized (es_stdout, s, n_lf, NULL, NULL);
1209                           es_putc ('\n', es_stdout);
1210                           s += n_lf; n -= n_lf;
1211                         }
1212                     } while (s_lf);
1213                 }
1214             }
1215
1216           xfree (reason_text);
1217           xfree (reason_comment);
1218
1219           /* fixme: check or list other sigs here */
1220         }
1221     }
1222   es_putc ('\n', es_stdout);
1223   xfree (serialno);
1224   xfree (hexgrip);
1225 }
1226
1227
1228 /* Do a simple key listing printing only the fingerprint and the mail
1229  * address of valid keys.  */
1230 static void
1231 list_keyblock_simple (ctrl_t ctrl, kbnode_t keyblock)
1232 {
1233   gpg_err_code_t ec;
1234   kbnode_t kbctx;
1235   kbnode_t node;
1236   char hexfpr[2*MAX_FINGERPRINT_LEN+1];
1237   char *mbox;
1238
1239   (void)ctrl;
1240
1241   node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
1242   if (!node)
1243     {
1244       log_error ("Oops; key lost!\n");
1245       dump_kbnode (keyblock);
1246       return;
1247     }
1248   hexfingerprint (node->pkt->pkt.public_key, hexfpr, sizeof hexfpr);
1249
1250   for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0));)
1251     {
1252       if (node->pkt->pkttype == PKT_USER_ID)
1253         {
1254           PKT_user_id *uid = node->pkt->pkt.user_id;
1255
1256           if (uid->attrib_data)
1257             continue;
1258
1259           if (uid->flags.expired || uid->flags.revoked)
1260             continue;
1261
1262           mbox = mailbox_from_userid (uid->name);
1263           if (!mbox)
1264             {
1265               ec = gpg_err_code_from_syserror ();
1266               if (ec != GPG_ERR_EINVAL)
1267                 log_error ("error getting mailbox from user-id: %s\n",
1268                            gpg_strerror (ec));
1269               continue;
1270             }
1271           es_fprintf (es_stdout, "%s %s\n", hexfpr, mbox);
1272           xfree (mbox);
1273         }
1274     }
1275 }
1276
1277
1278 void
1279 print_revokers (estream_t fp, PKT_public_key * pk)
1280 {
1281   /* print the revoker record */
1282   if (!pk->revkey && pk->numrevkeys)
1283     BUG ();
1284   else
1285     {
1286       int i, j;
1287
1288       for (i = 0; i < pk->numrevkeys; i++)
1289         {
1290           byte *p;
1291
1292           es_fprintf (fp, "rvk:::%d::::::", pk->revkey[i].algid);
1293           p = pk->revkey[i].fpr;
1294           for (j = 0; j < 20; j++, p++)
1295             es_fprintf (fp, "%02X", *p);
1296           es_fprintf (fp, ":%02x%s:\n",
1297                       pk->revkey[i].class,
1298                       (pk->revkey[i].class & 0x40) ? "s" : "");
1299         }
1300     }
1301 }
1302
1303
1304 /* Print the compliance flags to field 18.  PK is the public key.
1305  * KEYLENGTH is the length of the key in bits and CURVENAME is either
1306  * NULL or the name of the curve.  The latter two args are here
1307  * merely because the caller has already computed them.  */
1308 static void
1309 print_compliance_flags (PKT_public_key *pk,
1310                         unsigned int keylength, const char *curvename)
1311 {
1312   int any = 0;
1313
1314   if (!keylength)
1315     keylength = nbits_from_pk (pk);
1316
1317   if (pk->version == 5)
1318     {
1319       es_fputs (gnupg_status_compliance_flag (CO_GNUPG), es_stdout);
1320       any++;
1321     }
1322   if (gnupg_pk_is_compliant (CO_DE_VS, pk->pubkey_algo, pk->pkey,
1323                              keylength, curvename))
1324     {
1325       es_fprintf (es_stdout, any ? " %s" : "%s",
1326                   gnupg_status_compliance_flag (CO_DE_VS));
1327       any++;
1328     }
1329 }
1330
1331
1332 /* List a key in colon mode.  If SECRET is true this is a secret key
1333    record (i.e. requested via --list-secret-key).  If HAS_SECRET a
1334    secret key is available even if SECRET is not set.  */
1335 static void
1336 list_keyblock_colon (ctrl_t ctrl, kbnode_t keyblock,
1337                      int secret, int has_secret)
1338 {
1339   int rc;
1340   KBNODE kbctx;
1341   KBNODE node;
1342   PKT_public_key *pk;
1343   u32 keyid[2];
1344   int trustletter = 0;
1345   int trustletter_print;
1346   int ownertrust_print;
1347   int ulti_hack = 0;
1348   int i;
1349   char *hexgrip_buffer = NULL;
1350   const char *hexgrip = NULL;
1351   char *serialno = NULL;
1352   int stubkey;
1353   unsigned int keylength;
1354   char *curve = NULL;
1355   const char *curvename = NULL;
1356
1357   /* Get the keyid from the keyblock.  */
1358   node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
1359   if (!node)
1360     {
1361       log_error ("Oops; key lost!\n");
1362       dump_kbnode (keyblock);
1363       return;
1364     }
1365
1366   pk = node->pkt->pkt.public_key;
1367   if (secret || has_secret || opt.with_keygrip || opt.with_key_data)
1368     {
1369       rc = hexkeygrip_from_pk (pk, &hexgrip_buffer);
1370       if (rc)
1371         log_error ("error computing a keygrip: %s\n", gpg_strerror (rc));
1372       /* In the error case we print an empty string so that we have a
1373        * "grp" record for each and subkey - even if it is empty.  This
1374        * may help to prevent sync problems.  */
1375       hexgrip = hexgrip_buffer? hexgrip_buffer : "";
1376     }
1377   stubkey = 0;
1378   if ((secret || has_secret)
1379       && agent_get_keyinfo (NULL, hexgrip, &serialno, NULL))
1380     stubkey = 1;  /* Key not found.  */
1381
1382   keyid_from_pk (pk, keyid);
1383   if (!pk->flags.valid)
1384     trustletter_print = 'i';
1385   else if (pk->flags.revoked)
1386     trustletter_print = 'r';
1387   else if (pk->has_expired)
1388     trustletter_print = 'e';
1389   else if (opt.fast_list_mode || opt.no_expensive_trust_checks)
1390     trustletter_print = 0;
1391   else
1392     {
1393       trustletter = get_validity_info (ctrl, keyblock, pk, NULL);
1394       if (trustletter == 'u')
1395         ulti_hack = 1;
1396       trustletter_print = trustletter;
1397     }
1398
1399   if (!opt.fast_list_mode && !opt.no_expensive_trust_checks)
1400     ownertrust_print = get_ownertrust_info (ctrl, pk, 0);
1401   else
1402     ownertrust_print = 0;
1403
1404   keylength = nbits_from_pk (pk);
1405
1406   es_fputs (secret? "sec:":"pub:", es_stdout);
1407   if (trustletter_print)
1408     es_putc (trustletter_print, es_stdout);
1409   es_fprintf (es_stdout, ":%u:%d:%08lX%08lX:%s:%s::",
1410               keylength,
1411               pk->pubkey_algo,
1412               (ulong) keyid[0], (ulong) keyid[1],
1413               colon_datestr_from_pk (pk), colon_strtime (pk->expiredate));
1414
1415   if (ownertrust_print)
1416     es_putc (ownertrust_print, es_stdout);
1417   es_putc (':', es_stdout);
1418
1419   es_putc (':', es_stdout);
1420   es_putc (':', es_stdout);
1421   print_capabilities (ctrl, pk, keyblock);
1422   es_putc (':', es_stdout);             /* End of field 13. */
1423   es_putc (':', es_stdout);             /* End of field 14. */
1424   if (secret || has_secret)
1425     {
1426       if (stubkey)
1427         es_putc ('#', es_stdout);
1428       else if (serialno)
1429         es_fputs (serialno, es_stdout);
1430       else if (has_secret)
1431         es_putc ('+', es_stdout);
1432     }
1433   es_putc (':', es_stdout);             /* End of field 15. */
1434   es_putc (':', es_stdout);             /* End of field 16. */
1435   if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA
1436       || pk->pubkey_algo == PUBKEY_ALGO_EDDSA
1437       || pk->pubkey_algo == PUBKEY_ALGO_ECDH)
1438     {
1439       curve = openpgp_oid_to_str (pk->pkey[0]);
1440       curvename = openpgp_oid_to_curve (curve, 0);
1441       if (!curvename)
1442         curvename = curve;
1443       es_fputs (curvename, es_stdout);
1444     }
1445   es_putc (':', es_stdout);             /* End of field 17. */
1446   print_compliance_flags (pk, keylength, curvename);
1447   es_putc (':', es_stdout);             /* End of field 18 (compliance). */
1448   if (pk->keyupdate)
1449     es_fputs (colon_strtime (pk->keyupdate), es_stdout);
1450   es_putc (':', es_stdout);             /* End of field 19 (last_update). */
1451   es_fprintf (es_stdout, "%d%s", pk->keyorg, pk->updateurl? " ":"");
1452   if (pk->updateurl)
1453     es_write_sanitized (es_stdout, pk->updateurl, strlen (pk->updateurl),
1454                         ":", NULL);
1455   es_putc (':', es_stdout);             /* End of field 20 (origin). */
1456   es_putc ('\n', es_stdout);
1457
1458   print_revokers (es_stdout, pk);
1459   print_fingerprint (ctrl, NULL, pk, 0);
1460   if (hexgrip)
1461     es_fprintf (es_stdout, "grp:::::::::%s:\n", hexgrip);
1462   if (opt.with_key_data)
1463     print_key_data (pk);
1464
1465   for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0));)
1466     {
1467       if (node->pkt->pkttype == PKT_USER_ID)
1468         {
1469           PKT_user_id *uid = node->pkt->pkt.user_id;
1470           int uid_validity;
1471
1472           if (attrib_fp && uid->attrib_data != NULL)
1473             dump_attribs (uid, pk);
1474
1475           if (uid->flags.revoked)
1476             uid_validity = 'r';
1477           else if (uid->flags.expired)
1478             uid_validity = 'e';
1479           else if (opt.no_expensive_trust_checks)
1480             uid_validity = 0;
1481           else if (ulti_hack)
1482             uid_validity = 'u';
1483           else
1484             uid_validity = get_validity_info (ctrl, keyblock, pk, uid);
1485
1486           es_fputs (uid->attrib_data? "uat:":"uid:", es_stdout);
1487           if (uid_validity)
1488             es_putc (uid_validity, es_stdout);
1489           es_fputs ("::::", es_stdout);
1490
1491           es_fprintf (es_stdout, "%s:", colon_strtime (uid->created));
1492           es_fprintf (es_stdout, "%s:", colon_strtime (uid->expiredate));
1493
1494           namehash_from_uid (uid);
1495
1496           for (i = 0; i < 20; i++)
1497             es_fprintf (es_stdout, "%02X", uid->namehash[i]);
1498
1499           es_fprintf (es_stdout, "::");
1500
1501           if (uid->attrib_data)
1502             es_fprintf (es_stdout, "%u %lu", uid->numattribs, uid->attrib_len);
1503           else
1504             es_write_sanitized (es_stdout, uid->name, uid->len, ":", NULL);
1505           es_fputs (":::::::::", es_stdout);
1506           if (uid->keyupdate)
1507             es_fputs (colon_strtime (uid->keyupdate), es_stdout);
1508           es_putc (':', es_stdout);     /* End of field 19 (last_update). */
1509           es_fprintf (es_stdout, "%d%s", uid->keyorg, uid->updateurl? " ":"");
1510           if (uid->updateurl)
1511             es_write_sanitized (es_stdout,
1512                                 uid->updateurl, strlen (uid->updateurl),
1513                                 ":", NULL);
1514           es_putc (':', es_stdout);     /* End of field 20 (origin). */
1515           es_putc ('\n', es_stdout);
1516 #ifdef USE_TOFU
1517           if (!uid->attrib_data && opt.with_tofu_info
1518               && (opt.trust_model == TM_TOFU || opt.trust_model == TM_TOFU_PGP))
1519             {
1520               /* Print a "tfs" record.  */
1521               tofu_write_tfs_record (ctrl, es_stdout, pk, uid->name);
1522             }
1523 #endif /*USE_TOFU*/
1524         }
1525       else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
1526         {
1527           u32 keyid2[2];
1528           PKT_public_key *pk2;
1529           int need_hexgrip = !!hexgrip;
1530
1531           pk2 = node->pkt->pkt.public_key;
1532           xfree (hexgrip_buffer); hexgrip_buffer = NULL; hexgrip = NULL;
1533           xfree (serialno); serialno = NULL;
1534           if (need_hexgrip
1535               || secret || has_secret || opt.with_keygrip || opt.with_key_data)
1536             {
1537               rc = hexkeygrip_from_pk (pk2, &hexgrip_buffer);
1538               if (rc)
1539                 log_error ("error computing a keygrip: %s\n",
1540                            gpg_strerror (rc));
1541               hexgrip = hexgrip_buffer? hexgrip_buffer : "";
1542             }
1543           stubkey = 0;
1544           if ((secret||has_secret)
1545               && agent_get_keyinfo (NULL, hexgrip, &serialno, NULL))
1546             stubkey = 1;  /* Key not found.  */
1547
1548           keyid_from_pk (pk2, keyid2);
1549           es_fputs (secret? "ssb:":"sub:", es_stdout);
1550           if (!pk2->flags.valid)
1551             es_putc ('i', es_stdout);
1552           else if (pk2->flags.revoked)
1553             es_putc ('r', es_stdout);
1554           else if (pk2->has_expired)
1555             es_putc ('e', es_stdout);
1556           else if (opt.fast_list_mode || opt.no_expensive_trust_checks)
1557             ;
1558           else
1559             {
1560               /* TRUSTLETTER should always be defined here. */
1561               if (trustletter)
1562                 es_fprintf (es_stdout, "%c", trustletter);
1563             }
1564           keylength = nbits_from_pk (pk2);
1565           es_fprintf (es_stdout, ":%u:%d:%08lX%08lX:%s:%s:::::",
1566                       keylength,
1567                       pk2->pubkey_algo,
1568                       (ulong) keyid2[0], (ulong) keyid2[1],
1569                       colon_datestr_from_pk (pk2),
1570                       colon_strtime (pk2->expiredate));
1571           print_capabilities (ctrl, pk2, NULL);
1572           es_putc (':', es_stdout);     /* End of field 13. */
1573           es_putc (':', es_stdout);     /* End of field 14. */
1574           if (secret || has_secret)
1575             {
1576               if (stubkey)
1577                 es_putc ('#', es_stdout);
1578               else if (serialno)
1579                 es_fputs (serialno, es_stdout);
1580               else if (has_secret)
1581                 es_putc ('+', es_stdout);
1582             }
1583           es_putc (':', es_stdout);     /* End of field 15. */
1584           es_putc (':', es_stdout);     /* End of field 16. */
1585           if (pk2->pubkey_algo == PUBKEY_ALGO_ECDSA
1586               || pk2->pubkey_algo == PUBKEY_ALGO_EDDSA
1587               || pk2->pubkey_algo == PUBKEY_ALGO_ECDH)
1588             {
1589               xfree (curve);
1590               curve = openpgp_oid_to_str (pk2->pkey[0]);
1591               curvename = openpgp_oid_to_curve (curve, 0);
1592               if (!curvename)
1593                 curvename = curve;
1594               es_fputs (curvename, es_stdout);
1595             }
1596           es_putc (':', es_stdout);     /* End of field 17. */
1597           print_compliance_flags (pk2, keylength, curvename);
1598           es_putc (':', es_stdout);     /* End of field 18. */
1599           es_putc ('\n', es_stdout);
1600           print_fingerprint (ctrl, NULL, pk2, 0);
1601           if (hexgrip)
1602             es_fprintf (es_stdout, "grp:::::::::%s:\n", hexgrip);
1603           if (opt.with_key_data)
1604             print_key_data (pk2);
1605         }
1606       else if (opt.list_sigs && node->pkt->pkttype == PKT_SIGNATURE)
1607         {
1608           PKT_signature *sig = node->pkt->pkt.signature;
1609           int sigrc, fprokay = 0;
1610           char *sigstr;
1611           size_t fplen;
1612           byte fparray[MAX_FINGERPRINT_LEN];
1613           char *siguid;
1614           size_t siguidlen;
1615           char *issuer_fpr = NULL;
1616           char *reason_text = NULL;
1617           char *reason_comment = NULL;
1618           size_t reason_commentlen;
1619           int reason_code;
1620
1621           if (sig->sig_class == 0x20 || sig->sig_class == 0x28
1622               || sig->sig_class == 0x30)
1623             {
1624               sigstr = "rev";
1625               reason_code = get_revocation_reason (sig, &reason_text,
1626                                                    &reason_comment,
1627                                                    &reason_commentlen);
1628             }
1629           else if ((sig->sig_class & ~3) == 0x10)
1630             sigstr = "sig";
1631           else if (sig->sig_class == 0x18)
1632             sigstr = "sig";
1633           else if (sig->sig_class == 0x1F)
1634             sigstr = "sig";
1635           else
1636             {
1637               es_fprintf (es_stdout, "sig::::::::::%02x%c:\n",
1638                       sig->sig_class, sig->flags.exportable ? 'x' : 'l');
1639               continue;
1640             }
1641
1642           if (opt.check_sigs)
1643             {
1644               PKT_public_key *signer_pk = NULL;
1645
1646               es_fflush (es_stdout);
1647               if (opt.no_sig_cache)
1648                 signer_pk = xmalloc_clear (sizeof (PKT_public_key));
1649
1650               rc = check_key_signature2 (ctrl, keyblock, node, NULL, signer_pk,
1651                                          NULL, NULL, NULL);
1652               switch (gpg_err_code (rc))
1653                 {
1654                 case 0:
1655                   sigrc = '!';
1656                   break;
1657                 case GPG_ERR_BAD_SIGNATURE:
1658                   sigrc = '-';
1659                   break;
1660                 case GPG_ERR_NO_PUBKEY:
1661                 case GPG_ERR_UNUSABLE_PUBKEY:
1662                   sigrc = '?';
1663                   break;
1664                 default:
1665                   sigrc = '%';
1666                   break;
1667                 }
1668
1669               if (opt.no_sig_cache)
1670                 {
1671                   if (!rc)
1672                     {
1673                       fingerprint_from_pk (signer_pk, fparray, &fplen);
1674                       fprokay = 1;
1675                     }
1676                   free_public_key (signer_pk);
1677                 }
1678             }
1679           else
1680             {
1681               rc = 0;
1682               sigrc = ' '; /* Note the fix-up below in --list-sigs mode.  */
1683             }
1684
1685           if (sigrc != '%' && sigrc != '?' && !opt.fast_list_mode)
1686             {
1687               int nouid;
1688               siguid = get_user_id (ctrl, sig->keyid, &siguidlen, &nouid);
1689               if (!opt.check_sigs && nouid)
1690                 sigrc = '?';  /* No key in local keyring.  */
1691             }
1692           else
1693             {
1694               siguid = NULL;
1695               siguidlen = 0;
1696             }
1697
1698
1699           es_fputs (sigstr, es_stdout);
1700           es_putc (':', es_stdout);
1701           if (sigrc != ' ')
1702             es_putc (sigrc, es_stdout);
1703           es_fprintf (es_stdout, "::%d:%08lX%08lX:%s:%s:", sig->pubkey_algo,
1704                   (ulong) sig->keyid[0], (ulong) sig->keyid[1],
1705                   colon_datestr_from_sig (sig),
1706                   colon_expirestr_from_sig (sig));
1707
1708           if (sig->trust_depth || sig->trust_value)
1709             es_fprintf (es_stdout, "%d %d", sig->trust_depth, sig->trust_value);
1710           es_fprintf (es_stdout, ":");
1711
1712           if (sig->trust_regexp)
1713             es_write_sanitized (es_stdout, sig->trust_regexp,
1714                                 strlen (sig->trust_regexp), ":", NULL);
1715           es_fprintf (es_stdout, ":");
1716
1717           if (sigrc == '%')
1718             es_fprintf (es_stdout, "[%s] ", gpg_strerror (rc));
1719           else if (siguid)
1720             es_write_sanitized (es_stdout, siguid, siguidlen, ":", NULL);
1721
1722           es_fprintf (es_stdout, ":%02x%c", sig->sig_class,
1723                       sig->flags.exportable ? 'x' : 'l');
1724           if (reason_text)
1725             es_fprintf (es_stdout, ",%02x", reason_code);
1726           es_fputs ("::", es_stdout);
1727
1728           if (opt.no_sig_cache && opt.check_sigs && fprokay)
1729             {
1730               for (i = 0; i < fplen; i++)
1731                 es_fprintf (es_stdout, "%02X", fparray[i]);
1732             }
1733           else if ((issuer_fpr = issuer_fpr_string (sig)))
1734             es_fputs (issuer_fpr, es_stdout);
1735
1736           es_fprintf (es_stdout, ":::%d:", sig->digest_algo);
1737
1738           if (reason_comment)
1739             {
1740               es_fputs ("::::", es_stdout);
1741               es_write_sanitized (es_stdout, reason_comment, reason_commentlen,
1742                                   ":", NULL);
1743               es_putc (':', es_stdout);
1744             }
1745           es_putc ('\n', es_stdout);
1746
1747           if (opt.show_subpackets)
1748             print_subpackets_colon (sig);
1749
1750           /* fixme: check or list other sigs here */
1751           xfree (reason_text);
1752           xfree (reason_comment);
1753           xfree (siguid);
1754           xfree (issuer_fpr);
1755         }
1756     }
1757
1758   xfree (curve);
1759   xfree (hexgrip_buffer);
1760   xfree (serialno);
1761 }
1762
1763 /*
1764  * Reorder the keyblock so that the primary user ID (and not attribute
1765  * packet) comes first.  Fixme: Replace this by a generic sort
1766  * function.  */
1767 static void
1768 do_reorder_keyblock (KBNODE keyblock, int attr)
1769 {
1770   KBNODE primary = NULL, primary0 = NULL, primary2 = NULL;
1771   KBNODE last, node;
1772
1773   for (node = keyblock; node; primary0 = node, node = node->next)
1774     {
1775       if (node->pkt->pkttype == PKT_USER_ID &&
1776           ((attr && node->pkt->pkt.user_id->attrib_data) ||
1777            (!attr && !node->pkt->pkt.user_id->attrib_data)) &&
1778           node->pkt->pkt.user_id->flags.primary)
1779         {
1780           primary = primary2 = node;
1781           for (node = node->next; node; primary2 = node, node = node->next)
1782             {
1783               if (node->pkt->pkttype == PKT_USER_ID
1784                   || node->pkt->pkttype == PKT_PUBLIC_SUBKEY
1785                   || node->pkt->pkttype == PKT_SECRET_SUBKEY)
1786                 {
1787                   break;
1788                 }
1789             }
1790           break;
1791         }
1792     }
1793   if (!primary)
1794     return; /* No primary key flag found (should not happen).  */
1795
1796   for (last = NULL, node = keyblock; node; last = node, node = node->next)
1797     {
1798       if (node->pkt->pkttype == PKT_USER_ID)
1799         break;
1800     }
1801   log_assert (node);
1802   log_assert (last);     /* The user ID is never the first packet.  */
1803   log_assert (primary0); /* Ditto (this is the node before primary).  */
1804   if (node == primary)
1805     return; /* Already the first one.  */
1806
1807   last->next = primary;
1808   primary0->next = primary2->next;
1809   primary2->next = node;
1810 }
1811
1812 void
1813 reorder_keyblock (KBNODE keyblock)
1814 {
1815   do_reorder_keyblock (keyblock, 1);
1816   do_reorder_keyblock (keyblock, 0);
1817 }
1818
1819 static void
1820 list_keyblock (ctrl_t ctrl,
1821                KBNODE keyblock, int secret, int has_secret, int fpr,
1822                struct keylist_context *listctx)
1823 {
1824   reorder_keyblock (keyblock);
1825
1826   if (opt.with_colons)
1827     list_keyblock_colon (ctrl, keyblock, secret, has_secret);
1828   else if ((opt.list_options & LIST_SHOW_ONLY_FPR_MBOX))
1829     {
1830       if (!listctx->no_validity)
1831         check_trustdb_stale (ctrl);
1832       list_keyblock_simple (ctrl, keyblock);
1833     }
1834   else
1835     list_keyblock_print (ctrl, keyblock, secret, fpr, listctx);
1836
1837   if (secret)
1838     es_fflush (es_stdout);
1839 }
1840
1841
1842 /* Public function used by keygen to list a keyblock.  If NO_VALIDITY
1843  * is set the validity of a key is never shown.  */
1844 void
1845 list_keyblock_direct (ctrl_t ctrl,
1846                       kbnode_t keyblock, int secret, int has_secret, int fpr,
1847                       int no_validity)
1848 {
1849   struct keylist_context listctx;
1850
1851   memset (&listctx, 0, sizeof (listctx));
1852   listctx.no_validity = !!no_validity;
1853   list_keyblock (ctrl, keyblock, secret, has_secret, fpr, &listctx);
1854   keylist_context_release (&listctx);
1855 }
1856
1857
1858 /* Print an hex digit in ICAO spelling.  */
1859 static void
1860 print_icao_hexdigit (estream_t fp, int c)
1861 {
1862   static const char *list[16] = {
1863     "Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven",
1864     "Eight", "Niner", "Alfa", "Bravo", "Charlie", "Delta", "Echo", "Foxtrot"
1865   };
1866
1867   tty_fprintf (fp, "%s", list[c&15]);
1868 }
1869
1870
1871 /*
1872  * Function to print the finperprint.
1873  * mode 0: as used in key listings, opt.with_colons is honored
1874  *      1: print using log_info ()
1875  *      2: direct use of tty
1876  *      3: direct use of tty but only primary key.
1877  *      4: direct use of tty but only subkey.
1878  *     10: Same as 0 but with_colons etc is ignored.
1879  *     20: Same as 0 but using a compact format.
1880  *
1881  * Modes 1 and 2 will try and print both subkey and primary key
1882  * fingerprints.  A MODE with bit 7 set is used internally.  If
1883  * OVERRIDE_FP is not NULL that stream will be used in  0 instead
1884  * of es_stdout or instead of the TTY in modes 2 and 3.
1885  */
1886 void
1887 print_fingerprint (ctrl_t ctrl, estream_t override_fp,
1888                    PKT_public_key *pk, int mode)
1889 {
1890   char hexfpr[2*MAX_FINGERPRINT_LEN+1];
1891   char *p;
1892   size_t i;
1893   estream_t fp;
1894   const char *text;
1895   int primary = 0;
1896   int with_colons = opt.with_colons;
1897   int with_icao   = opt.with_icao_spelling;
1898   int compact = 0;
1899
1900   if (mode == 10)
1901     {
1902       mode = 0;
1903       with_colons = 0;
1904       with_icao = 0;
1905     }
1906   else if (mode == 20)
1907     {
1908       mode = 0;
1909       with_colons = 0;
1910       compact = 1;
1911     }
1912
1913   if (!opt.fingerprint && !opt.with_fingerprint
1914       && opt.with_subkey_fingerprint)
1915     compact = 1;
1916
1917   if (pk->main_keyid[0] == pk->keyid[0]
1918       && pk->main_keyid[1] == pk->keyid[1])
1919     primary = 1;
1920
1921   /* Just to be safe */
1922   if ((mode & 0x80) && !primary)
1923     {
1924       log_error ("primary key is not really primary!\n");
1925       return;
1926     }
1927
1928   mode &= ~0x80;
1929
1930   if (!primary && (mode == 1 || mode == 2))
1931     {
1932       PKT_public_key *primary_pk = xmalloc_clear (sizeof (*primary_pk));
1933       get_pubkey (ctrl, primary_pk, pk->main_keyid);
1934       print_fingerprint (ctrl, override_fp, primary_pk, (mode | 0x80));
1935       free_public_key (primary_pk);
1936     }
1937
1938   if (mode == 1)
1939     {
1940       fp = log_get_stream ();
1941       if (primary)
1942         text = _("Primary key fingerprint:");
1943       else
1944         text = _("     Subkey fingerprint:");
1945     }
1946   else if (mode == 2)
1947     {
1948       fp = override_fp; /* Use tty or given stream.  */
1949       if (primary)
1950         /* TRANSLATORS: this should fit into 24 bytes so that the
1951          * fingerprint data is properly aligned with the user ID */
1952         text = _(" Primary key fingerprint:");
1953       else
1954         text = _("      Subkey fingerprint:");
1955     }
1956   else if (mode == 3)
1957     {
1958       fp = override_fp; /* Use tty or given stream.  */
1959       text = _("      Key fingerprint =");
1960     }
1961   else if (mode == 4)
1962     {
1963       fp = override_fp; /* Use tty or given stream.  */
1964       text = _("      Subkey fingerprint:");
1965     }
1966   else
1967     {
1968       fp = override_fp? override_fp : es_stdout;
1969       if (opt.keyid_format == KF_NONE)
1970         {
1971           text = "     ";  /* To indent ICAO spelling.  */
1972           compact = 1;
1973         }
1974       else
1975         text = _("      Key fingerprint =");
1976     }
1977
1978   hexfingerprint (pk, hexfpr, sizeof hexfpr);
1979   if (with_colons && !mode)
1980     {
1981       es_fprintf (fp, "fpr:::::::::%s:", hexfpr);
1982     }
1983   else if (compact && !opt.fingerprint && !opt.with_fingerprint)
1984     {
1985       tty_fprintf (fp, "%*s%s", 6, "", hexfpr);
1986     }
1987   else
1988     {
1989       char fmtfpr[MAX_FORMATTED_FINGERPRINT_LEN + 1];
1990       format_hexfingerprint (hexfpr, fmtfpr, sizeof fmtfpr);
1991       if (compact)
1992         tty_fprintf (fp, "%*s%s", 6, "", fmtfpr);
1993       else
1994         tty_fprintf (fp, "%s %s", text, fmtfpr);
1995     }
1996   tty_fprintf (fp, "\n");
1997   if (!with_colons && with_icao)
1998     {
1999       ;
2000       tty_fprintf (fp, "%*s\"", (int)strlen(text)+1, "");
2001       for (i = 0, p = hexfpr; *p; i++, p++)
2002         {
2003           if (!i)
2004             ;
2005           else if (!(i%8))
2006             tty_fprintf (fp, "\n%*s ", (int)strlen(text)+1, "");
2007           else if (!(i%4))
2008             tty_fprintf (fp, "  ");
2009           else
2010             tty_fprintf (fp, " ");
2011           print_icao_hexdigit (fp, xtoi_1 (p));
2012         }
2013       tty_fprintf (fp, "\"\n");
2014     }
2015 }
2016
2017 /* Print the serial number of an OpenPGP card if available.  */
2018 static void
2019 print_card_serialno (const char *serialno)
2020 {
2021   if (!serialno)
2022     return;
2023   if (opt.with_colons)
2024     return; /* Handled elsewhere. */
2025
2026   es_fputs (_("      Card serial no. ="), es_stdout);
2027   es_putc (' ', es_stdout);
2028   if (strlen (serialno) == 32 && !strncmp (serialno, "D27600012401", 12))
2029     {
2030       /* This is an OpenPGP card.  Print the relevant part.  */
2031       /* Example: D2760001240101010001000003470000 */
2032       /*                          xxxxyyyyyyyy     */
2033       es_fprintf (es_stdout, "%.*s %.*s", 4, serialno+16, 8, serialno+20);
2034     }
2035  else
2036    es_fputs (serialno, es_stdout);
2037   es_putc ('\n', es_stdout);
2038 }
2039
2040
2041 /* Print a public or secret (sub)key line.  Example:
2042  *
2043  * pub   dsa2048 2007-12-31 [SC] [expires: 2018-12-31]
2044  *       80615870F5BAD690333686D0F2AD85AC1E42B367
2045  *
2046  * Some global options may result in a different output format.  If
2047  * SECRET is set, "sec" or "ssb" is used instead of "pub" or "sub" and
2048  * depending on the value a flag character is shown:
2049  *
2050  *    1 := ' ' Regular secret key
2051  *    2 := '#' Stub secret key
2052  *    3 := '>' Secret key is on a token.
2053  */
2054 void
2055 print_key_line (ctrl_t ctrl, estream_t fp, PKT_public_key *pk, int secret)
2056 {
2057   char pkstrbuf[PUBKEY_STRING_SIZE];
2058
2059   tty_fprintf (fp, "%s%c  %s",
2060                pk->flags.primary? (secret? "sec":"pub")
2061                /**/             : (secret? "ssb":"sub"),
2062                secret == 2? '#' : secret == 3? '>' : ' ',
2063                pubkey_string (pk, pkstrbuf, sizeof pkstrbuf));
2064   if (opt.keyid_format != KF_NONE)
2065     tty_fprintf (fp, "/%s", keystr_from_pk (pk));
2066   tty_fprintf (fp, " %s", datestr_from_pk (pk));
2067
2068   if (pk->flags.primary
2069       && !(openpgp_pk_algo_usage (pk->pubkey_algo)
2070            & (PUBKEY_USAGE_CERT| PUBKEY_USAGE_SIG|PUBKEY_USAGE_AUTH)))
2071     {
2072       /* A primary key which is really not capable to sign.  */
2073       tty_fprintf (fp, " [INVALID_ALGO]");
2074     }
2075   else if ((opt.list_options & LIST_SHOW_USAGE))
2076     {
2077       tty_fprintf (fp, " [%s]", usagestr_from_pk (pk, 0));
2078     }
2079
2080   if (pk->flags.revoked)
2081     {
2082       tty_fprintf (fp, " [");
2083       tty_fprintf (fp, _("revoked: %s"), revokestr_from_pk (pk));
2084       tty_fprintf (fp, "]");
2085     }
2086   else if (pk->has_expired)
2087     {
2088       tty_fprintf (fp, " [");
2089       tty_fprintf (fp, _("expired: %s"), expirestr_from_pk (pk));
2090       tty_fprintf (fp, "]");
2091     }
2092   else if (pk->expiredate)
2093     {
2094       tty_fprintf (fp, " [");
2095       tty_fprintf (fp, _("expires: %s"), expirestr_from_pk (pk));
2096       tty_fprintf (fp, "]");
2097     }
2098
2099 #if 0
2100   /* I need to think about this some more.  It's easy enough to
2101      include, but it looks sort of confusing in the listing... */
2102   if (opt.list_options & LIST_SHOW_VALIDITY)
2103     {
2104       int validity = get_validity (ctrl, pk, NULL, NULL, 0);
2105       tty_fprintf (fp, " [%s]", trust_value_to_string (validity));
2106     }
2107 #endif
2108
2109   if (pk->pubkey_algo >= 100)
2110     tty_fprintf (fp, " [experimental algorithm %d]", pk->pubkey_algo);
2111
2112   tty_fprintf (fp, "\n");
2113
2114   /* if the user hasn't explicitly asked for human-readable
2115      fingerprints, show compact fpr of primary key: */
2116   if (pk->flags.primary &&
2117       !opt.fingerprint && !opt.with_fingerprint)
2118     print_fingerprint (ctrl, fp, pk, 20);
2119 }
2120
2121
2122 void
2123 set_attrib_fd (int fd)
2124 {
2125   static int last_fd = -1;
2126
2127   if (fd != -1 && last_fd == fd)
2128     return;
2129
2130   /* Fixme: Do we need to check for the log stream here?  */
2131   if (attrib_fp && attrib_fp != log_get_stream ())
2132     es_fclose (attrib_fp);
2133   attrib_fp = NULL;
2134   if (fd == -1)
2135     return;
2136
2137   if (! gnupg_fd_valid (fd))
2138     log_fatal ("attribute-fd is invalid: %s\n", strerror (errno));
2139
2140 #ifdef HAVE_DOSISH_SYSTEM
2141   setmode (fd, O_BINARY);
2142 #endif
2143   if (fd == 1)
2144     attrib_fp = es_stdout;
2145   else if (fd == 2)
2146     attrib_fp = es_stderr;
2147   else
2148     attrib_fp = es_fdopen (fd, "wb");
2149   if (!attrib_fp)
2150     {
2151       log_fatal ("can't open fd %d for attribute output: %s\n",
2152                  fd, strerror (errno));
2153     }
2154
2155   last_fd = fd;
2156 }