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