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