Imported Upstream version 2.1.0
[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 <http://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 #include <assert.h>
28 #ifdef HAVE_DOSISH_SYSTEM
29 #include <fcntl.h>              /* for setmode() */
30 #endif
31
32 #include "gpg.h"
33 #include "options.h"
34 #include "packet.h"
35 #include "status.h"
36 #include "keydb.h"
37 #include "photoid.h"
38 #include "util.h"
39 #include "ttyio.h"
40 #include "trustdb.h"
41 #include "main.h"
42 #include "i18n.h"
43 #include "status.h"
44 #include "call-agent.h"
45
46 static void list_all (int, int);
47 static void list_one (strlist_t names, int secret, int mark_secret);
48 static void locate_one (ctrl_t ctrl, strlist_t names);
49 static void print_card_serialno (const char *serialno);
50
51 struct sig_stats
52 {
53   int inv_sigs;
54   int no_key;
55   int oth_err;
56 };
57
58 /* The stream used to write attribute packets to.  */
59 static estream_t attrib_fp;
60
61
62 /* List the keys.  If list is NULL, all available keys are listed.
63    With LOCATE_MODE set the locate algorithm is used to find a
64    key.  */
65 void
66 public_key_list (ctrl_t ctrl, strlist_t list, int locate_mode)
67 {
68 #ifndef NO_TRUST_MODELS
69   if (opt.with_colons)
70     {
71       byte trust_model, marginals, completes, cert_depth, min_cert_level;
72       ulong created, nextcheck;
73
74       read_trust_options (&trust_model, &created, &nextcheck,
75                           &marginals, &completes, &cert_depth, &min_cert_level);
76
77       es_fprintf (es_stdout, "tru:");
78
79       if (nextcheck && nextcheck <= make_timestamp ())
80         es_fprintf (es_stdout, "o");
81       if (trust_model != opt.trust_model)
82         es_fprintf (es_stdout, "t");
83       if (opt.trust_model == TM_PGP || opt.trust_model == TM_CLASSIC)
84         {
85           if (marginals != opt.marginals_needed)
86             es_fprintf (es_stdout, "m");
87           if (completes != opt.completes_needed)
88             es_fprintf (es_stdout, "c");
89           if (cert_depth != opt.max_cert_depth)
90             es_fprintf (es_stdout, "d");
91           if (min_cert_level != opt.min_cert_level)
92             es_fprintf (es_stdout, "l");
93         }
94
95       es_fprintf (es_stdout, ":%d:%lu:%lu", trust_model, created, nextcheck);
96
97       /* Only show marginals, completes, and cert_depth in the classic
98          or PGP trust models since they are not meaningful
99          otherwise. */
100
101       if (trust_model == TM_PGP || trust_model == TM_CLASSIC)
102         es_fprintf (es_stdout, ":%d:%d:%d", marginals, completes, cert_depth);
103       es_fprintf (es_stdout, "\n");
104     }
105 #endif /*!NO_TRUST_MODELS*/
106
107   /* We need to do the stale check right here because it might need to
108      update the keyring while we already have the keyring open.  This
109      is very bad for W32 because of a sharing violation. For real OSes
110      it might lead to false results if we are later listing a keyring
111      which is associated with the inode of a deleted file.  */
112   check_trustdb_stale ();
113
114   if (locate_mode)
115     locate_one (ctrl, list);
116   else if (!list)
117     list_all (0, opt.with_secret);
118   else
119     list_one (list, 0, opt.with_secret);
120 }
121
122
123 void
124 secret_key_list (ctrl_t ctrl, strlist_t list)
125 {
126   (void)ctrl;
127
128   check_trustdb_stale ();
129
130   if (!list)
131     list_all (1, 0);
132   else                          /* List by user id */
133     list_one (list, 1, 0);
134 }
135
136 void
137 print_seckey_info (PKT_public_key *pk)
138 {
139   u32 keyid[2];
140   char *p;
141   char pkstrbuf[PUBKEY_STRING_SIZE];
142
143   keyid_from_pk (pk, keyid);
144   p = get_user_id_native (keyid);
145
146   tty_printf ("\nsec  %s/%s %s %s\n",
147               pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
148               keystr (keyid), datestr_from_pk (pk), p);
149
150   xfree (p);
151 }
152
153 /* Print information about the public key.  With FP passed as NULL,
154    the tty output interface is used, otherwise output is directted to
155    the given stream.  */
156 void
157 print_pubkey_info (estream_t fp, PKT_public_key * pk)
158 {
159   u32 keyid[2];
160   char *p;
161   char pkstrbuf[PUBKEY_STRING_SIZE];
162
163   keyid_from_pk (pk, keyid);
164
165   /* If the pk was chosen by a particular user ID, that is the one to
166      print.  */
167   if (pk->user_id)
168     p = utf8_to_native (pk->user_id->name, pk->user_id->len, 0);
169   else
170     p = get_user_id_native (keyid);
171
172   if (fp)
173     tty_printf ("\n");
174   tty_fprintf (fp, "pub  %s/%s %s %s\n",
175                pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
176                keystr (keyid), datestr_from_pk (pk), p);
177   xfree (p);
178 }
179
180
181 /* Print basic information of a secret key including the card serial
182    number information.  */
183 #ifdef ENABLE_CARD_SUPPORT
184 void
185 print_card_key_info (estream_t fp, kbnode_t keyblock)
186 {
187   kbnode_t node;
188   char *hexgrip;
189   char *serialno;
190   int s2k_char;
191   char pkstrbuf[PUBKEY_STRING_SIZE];
192
193   for (node = keyblock; node; node = node->next)
194     {
195       if (node->pkt->pkttype == PKT_PUBLIC_KEY
196           || node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
197         {
198           int rc;
199           PKT_public_key *pk = node->pkt->pkt.public_key;
200
201           serialno = NULL;
202           rc = hexkeygrip_from_pk (pk, &hexgrip);
203           if (rc)
204             {
205               log_error ("error computing a keygrip: %s\n", gpg_strerror (rc));
206               s2k_char = '?';
207             }
208           else if (!agent_get_keyinfo (NULL, hexgrip, &serialno))
209             s2k_char = serialno? '>':' ';
210           else
211             s2k_char = '#';  /* Key not found.  */
212
213           tty_fprintf (fp, "%s%c  %s/%s  ",
214                        node->pkt->pkttype == PKT_PUBLIC_KEY ? "sec" : "ssb",
215                        s2k_char,
216                        pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
217                        keystr_from_pk (pk));
218           tty_fprintf (fp, _("created: %s"), datestr_from_pk (pk));
219           tty_fprintf (fp, "  ");
220           tty_fprintf (fp, _("expires: %s"), expirestr_from_pk (pk));
221           if (serialno)
222             {
223               tty_fprintf (fp, "\n                      ");
224               tty_fprintf (fp, _("card-no: "));
225               if (strlen (serialno) == 32
226                   && !strncmp (serialno, "D27600012401", 12))
227                 {
228                   /* This is an OpenPGP card.  Print the relevant part.  */
229                   /* Example: D2760001240101010001000003470000 */
230                   /*                          xxxxyyyyyyyy     */
231                   tty_fprintf (fp, "%.*s %.*s", 4, serialno+16, 8, serialno+20);
232                 }
233               else
234                 tty_fprintf (fp, "%s", serialno);
235             }
236           tty_fprintf (fp, "\n");
237           xfree (hexgrip);
238           xfree (serialno);
239         }
240     }
241 }
242 #endif /*ENABLE_CARD_SUPPORT*/
243
244
245 /* Flags = 0x01 hashed 0x02 critical.  */
246 static void
247 status_one_subpacket (sigsubpkttype_t type, size_t len, int flags,
248                       const byte * buf)
249 {
250   char status[40];
251
252   /* Don't print these. */
253   if (len > 256)
254     return;
255
256   snprintf (status, sizeof status,
257             "%d %u %u ", type, flags, (unsigned int) len);
258
259   write_status_text_and_buffer (STATUS_SIG_SUBPACKET, status, buf, len, 0);
260 }
261
262
263 /* Print a policy URL.  Allowed values for MODE are:
264  *   0 - print to stdout.
265  *   1 - use log_info and emit status messages.
266  *   2 - emit only status messages.
267  */
268 void
269 show_policy_url (PKT_signature * sig, int indent, int mode)
270 {
271   const byte *p;
272   size_t len;
273   int seq = 0, crit;
274   estream_t fp = mode ? log_get_stream () : es_stdout;
275
276   while ((p =
277           enum_sig_subpkt (sig->hashed, SIGSUBPKT_POLICY, &len, &seq, &crit)))
278     {
279       if (mode != 2)
280         {
281           int i;
282           const char *str;
283
284           for (i = 0; i < indent; i++)
285             es_putc (' ', fp);
286
287           if (crit)
288             str = _("Critical signature policy: ");
289           else
290             str = _("Signature policy: ");
291           if (mode)
292             log_info ("%s", str);
293           else
294             es_fprintf (fp, "%s", str);
295           print_utf8_buffer (fp, p, len);
296           es_fprintf (fp, "\n");
297         }
298
299       if (mode)
300         write_status_buffer (STATUS_POLICY_URL, p, len, 0);
301     }
302 }
303
304
305 /*
306   mode=0 for stdout.
307   mode=1 for log_info + status messages
308   mode=2 for status messages only
309 */
310 /* TODO: use this */
311 void
312 show_keyserver_url (PKT_signature * sig, int indent, int mode)
313 {
314   const byte *p;
315   size_t len;
316   int seq = 0, crit;
317   estream_t fp = mode ? log_get_stream () : es_stdout;
318
319   while ((p =
320           enum_sig_subpkt (sig->hashed, SIGSUBPKT_PREF_KS, &len, &seq,
321                            &crit)))
322     {
323       if (mode != 2)
324         {
325           int i;
326           const char *str;
327
328           for (i = 0; i < indent; i++)
329             es_putc (' ', es_stdout);
330
331           if (crit)
332             str = _("Critical preferred keyserver: ");
333           else
334             str = _("Preferred keyserver: ");
335           if (mode)
336             log_info ("%s", str);
337           else
338             es_fprintf (es_stdout, "%s", str);
339           print_utf8_buffer (fp, p, len);
340           es_fprintf (fp, "\n");
341         }
342
343       if (mode)
344         status_one_subpacket (SIGSUBPKT_PREF_KS, len,
345                               (crit ? 0x02 : 0) | 0x01, p);
346     }
347 }
348
349 /*
350   mode=0 for stdout.
351   mode=1 for log_info + status messages
352   mode=2 for status messages only
353
354   Defined bits in WHICH:
355     1 == standard notations
356     2 == user notations
357 */
358 void
359 show_notation (PKT_signature * sig, int indent, int mode, int which)
360 {
361   estream_t fp = mode ? log_get_stream () : es_stdout;
362   struct notation *nd, *notations;
363
364   if (which == 0)
365     which = 3;
366
367   notations = sig_to_notation (sig);
368
369   /* There may be multiple notations in the same sig. */
370   for (nd = notations; nd; nd = nd->next)
371     {
372       if (mode != 2)
373         {
374           int has_at = !!strchr (nd->name, '@');
375
376           if ((which & 1 && !has_at) || (which & 2 && has_at))
377             {
378               int i;
379               const char *str;
380
381               for (i = 0; i < indent; i++)
382                 es_putc (' ', es_stdout);
383
384               if (nd->flags.critical)
385                 str = _("Critical signature notation: ");
386               else
387                 str = _("Signature notation: ");
388               if (mode)
389                 log_info ("%s", str);
390               else
391                 es_fprintf (es_stdout, "%s", str);
392               /* This is all UTF8 */
393               print_utf8_buffer (fp, nd->name, strlen (nd->name));
394               es_fprintf (fp, "=");
395               print_utf8_buffer (fp, nd->value, strlen (nd->value));
396               es_fprintf (fp, "\n");
397             }
398         }
399
400       if (mode)
401         {
402           write_status_buffer (STATUS_NOTATION_NAME,
403                                nd->name, strlen (nd->name), 0);
404           write_status_buffer (STATUS_NOTATION_DATA,
405                                nd->value, strlen (nd->value), 50);
406         }
407     }
408
409   free_notation (notations);
410 }
411
412 static void
413 print_signature_stats (struct sig_stats *s)
414 {
415   if (s->inv_sigs == 1)
416     tty_printf (_("1 bad signature\n"));
417   else if (s->inv_sigs)
418     tty_printf (_("%d bad signatures\n"), s->inv_sigs);
419   if (s->no_key == 1)
420     tty_printf (_("1 signature not checked due to a missing key\n"));
421   else if (s->no_key)
422     tty_printf (_("%d signatures not checked due to missing keys\n"),
423                 s->no_key);
424   if (s->oth_err == 1)
425     tty_printf (_("1 signature not checked due to an error\n"));
426   else if (s->oth_err)
427     tty_printf (_("%d signatures not checked due to errors\n"), s->oth_err);
428 }
429
430
431 /* List all keys.  If SECRET is true only secret keys are listed.  If
432    MARK_SECRET is true secret keys are indicated in a public key
433    listing.  */
434 static void
435 list_all (int secret, int mark_secret)
436 {
437   KEYDB_HANDLE hd;
438   KBNODE keyblock = NULL;
439   int rc = 0;
440   int any_secret;
441   const char *lastresname, *resname;
442   struct sig_stats stats;
443
444   memset (&stats, 0, sizeof (stats));
445
446   hd = keydb_new ();
447   if (!hd)
448     rc = gpg_error (GPG_ERR_GENERAL);
449   else
450     rc = keydb_search_first (hd);
451   if (rc)
452     {
453       if (gpg_err_code (rc) != GPG_ERR_NOT_FOUND)
454         log_error ("keydb_search_first failed: %s\n", g10_errstr (rc));
455       goto leave;
456     }
457
458   lastresname = NULL;
459   do
460     {
461       rc = keydb_get_keyblock (hd, &keyblock);
462       if (rc)
463         {
464           log_error ("keydb_get_keyblock failed: %s\n", g10_errstr (rc));
465           goto leave;
466         }
467
468       if (secret || mark_secret)
469         any_secret = !agent_probe_any_secret_key (NULL, keyblock);
470       else
471         any_secret = 0;
472
473       if (secret && !any_secret)
474         ; /* Secret key listing requested but this isn't one.  */
475       else
476         {
477           if (!opt.with_colons)
478             {
479               resname = keydb_get_resource_name (hd);
480               if (lastresname != resname)
481                 {
482                   int i;
483
484                   es_fprintf (es_stdout, "%s\n", resname);
485                   for (i = strlen (resname); i; i--)
486                     es_putc ('-', es_stdout);
487                   es_putc ('\n', es_stdout);
488                   lastresname = resname;
489                 }
490             }
491           merge_keys_and_selfsig (keyblock);
492           list_keyblock (keyblock, secret, any_secret, opt.fingerprint,
493                          opt.check_sigs ? &stats : NULL);
494         }
495       release_kbnode (keyblock);
496       keyblock = NULL;
497     }
498   while (!(rc = keydb_search_next (hd)));
499   es_fflush (es_stdout);
500   if (rc && gpg_err_code (rc) != GPG_ERR_NOT_FOUND)
501     log_error ("keydb_search_next failed: %s\n", g10_errstr (rc));
502   if (keydb_get_skipped_counter (hd))
503     log_info (_("Warning: %lu key(s) skipped due to their large size\n"),
504               keydb_get_skipped_counter (hd));
505
506   if (opt.check_sigs && !opt.with_colons)
507     print_signature_stats (&stats);
508
509 leave:
510   release_kbnode (keyblock);
511   keydb_release (hd);
512 }
513
514
515 static void
516 list_one (strlist_t names, int secret, int mark_secret)
517 {
518   int rc = 0;
519   KBNODE keyblock = NULL;
520   GETKEY_CTX ctx;
521   const char *resname;
522   const char *keyring_str = _("Keyring");
523   int i;
524   struct sig_stats stats;
525
526   memset (&stats, 0, sizeof (stats));
527
528   /* fixme: using the bynames function has the disadvantage that we
529    * don't know wether one of the names given was not found.  OTOH,
530    * this function has the advantage to list the names in the
531    * sequence as defined by the keyDB and does not duplicate
532    * outputs.  A solution could be do test whether all given have
533    * been listed (this needs a way to use the keyDB search
534    * functions) or to have the search function return indicators for
535    * found names.  Yet another way is to use the keydb search
536    * facilities directly. */
537   rc = getkey_bynames (&ctx, NULL, names, secret, &keyblock);
538   if (rc)
539     {
540       log_error ("error reading key: %s\n", g10_errstr (rc));
541       get_pubkey_end (ctx);
542       return;
543     }
544
545   do
546     {
547       if ((opt.list_options & LIST_SHOW_KEYRING) && !opt.with_colons)
548         {
549           resname = keydb_get_resource_name (get_ctx_handle (ctx));
550           es_fprintf (es_stdout, "%s: %s\n", keyring_str, resname);
551           for (i = strlen (resname) + strlen (keyring_str) + 2; i; i--)
552             es_putc ('-', es_stdout);
553           es_putc ('\n', es_stdout);
554         }
555       list_keyblock (keyblock, secret, mark_secret, opt.fingerprint,
556                      (!secret && opt.check_sigs)? &stats : NULL);
557       release_kbnode (keyblock);
558     }
559   while (!getkey_next (ctx, NULL, &keyblock));
560   getkey_end (ctx);
561
562   if (opt.check_sigs && !opt.with_colons)
563     print_signature_stats (&stats);
564 }
565
566
567 static void
568 locate_one (ctrl_t ctrl, strlist_t names)
569 {
570   int rc = 0;
571   strlist_t sl;
572   GETKEY_CTX ctx = NULL;
573   KBNODE keyblock = NULL;
574   struct sig_stats stats;
575
576   memset (&stats, 0, sizeof (stats));
577
578   for (sl = names; sl; sl = sl->next)
579     {
580       rc = get_pubkey_byname (ctrl, &ctx, NULL, sl->d, &keyblock, NULL, 1, 0);
581       if (rc)
582         {
583           if (gpg_err_code (rc) != GPG_ERR_NO_PUBKEY)
584             log_error ("error reading key: %s\n", g10_errstr (rc));
585         }
586       else
587         {
588           do
589             {
590               list_keyblock (keyblock, 0, 0, opt.fingerprint,
591                              opt.check_sigs ? &stats : NULL);
592               release_kbnode (keyblock);
593             }
594           while (ctx && !get_pubkey_next (ctx, NULL, &keyblock));
595           get_pubkey_end (ctx);
596           ctx = NULL;
597         }
598     }
599
600   if (opt.check_sigs && !opt.with_colons)
601     print_signature_stats (&stats);
602 }
603
604
605 static void
606 print_key_data (PKT_public_key * pk)
607 {
608   int n = pk ? pubkey_get_npkey (pk->pubkey_algo) : 0;
609   int i;
610
611   for (i = 0; i < n; i++)
612     {
613       es_fprintf (es_stdout, "pkd:%d:%u:", i, mpi_get_nbits (pk->pkey[i]));
614       mpi_print (es_stdout, pk->pkey[i], 1);
615       es_putc (':', es_stdout);
616       es_putc ('\n', es_stdout);
617     }
618 }
619
620 static void
621 print_capabilities (PKT_public_key *pk, KBNODE keyblock)
622 {
623   unsigned int use = pk->pubkey_usage;
624   int c_printed = 0;
625
626   if (use & PUBKEY_USAGE_ENC)
627     es_putc ('e', es_stdout);
628
629   if (use & PUBKEY_USAGE_SIG)
630     {
631       es_putc ('s', es_stdout);
632       if (pk->flags.primary)
633         {
634           es_putc ('c', es_stdout);
635           /* The PUBKEY_USAGE_CERT flag was introduced later and we
636              used to always print 'c' for a primary key.  To avoid any
637              regression here we better track whether we printed 'c'
638              already.  */
639           c_printed = 1;
640         }
641     }
642
643   if ((use & PUBKEY_USAGE_CERT) && !c_printed)
644     es_putc ('c', es_stdout);
645
646   if ((use & PUBKEY_USAGE_AUTH))
647     es_putc ('a', es_stdout);
648
649   if ((use & PUBKEY_USAGE_UNKNOWN))
650     es_putc ('?', es_stdout);
651
652   if (keyblock)
653     {
654       /* Figure out the usable capabilities.  */
655       KBNODE k;
656       int enc = 0, sign = 0, cert = 0, auth = 0, disabled = 0;
657
658       for (k = keyblock; k; k = k->next)
659         {
660           if (k->pkt->pkttype == PKT_PUBLIC_KEY
661               || k->pkt->pkttype == PKT_PUBLIC_SUBKEY)
662             {
663               pk = k->pkt->pkt.public_key;
664
665               if (pk->flags.primary)
666                 disabled = pk_is_disabled (pk);
667
668               if (pk->flags.valid && !pk->flags.revoked && !pk->has_expired)
669                 {
670                   if (pk->pubkey_usage & PUBKEY_USAGE_ENC)
671                     enc = 1;
672                   if (pk->pubkey_usage & PUBKEY_USAGE_SIG)
673                     {
674                       sign = 1;
675                       if (pk->flags.primary)
676                         cert = 1;
677                     }
678                   if (pk->pubkey_usage & PUBKEY_USAGE_CERT)
679                     cert = 1;
680                   if ((pk->pubkey_usage & PUBKEY_USAGE_AUTH))
681                     auth = 1;
682                 }
683             }
684         }
685       if (enc)
686         es_putc ('E', es_stdout);
687       if (sign)
688         es_putc ('S', es_stdout);
689       if (cert)
690         es_putc ('C', es_stdout);
691       if (auth)
692         es_putc ('A', es_stdout);
693       if (disabled)
694         es_putc ('D', es_stdout);
695     }
696
697   es_putc (':', es_stdout);
698 }
699
700
701 /* FLAGS: 0x01 hashed
702           0x02 critical  */
703 static void
704 print_one_subpacket (sigsubpkttype_t type, size_t len, int flags,
705                      const byte * buf)
706 {
707   size_t i;
708
709   es_fprintf (es_stdout, "spk:%d:%u:%u:", type, flags, (unsigned int) len);
710
711   for (i = 0; i < len; i++)
712     {
713       /* printable ascii other than : and % */
714       if (buf[i] >= 32 && buf[i] <= 126 && buf[i] != ':' && buf[i] != '%')
715         es_fprintf (es_stdout, "%c", buf[i]);
716       else
717         es_fprintf (es_stdout, "%%%02X", buf[i]);
718     }
719
720   es_fprintf (es_stdout, "\n");
721 }
722
723
724 void
725 print_subpackets_colon (PKT_signature * sig)
726 {
727   byte *i;
728
729   assert (opt.show_subpackets);
730
731   for (i = opt.show_subpackets; *i; i++)
732     {
733       const byte *p;
734       size_t len;
735       int seq, crit;
736
737       seq = 0;
738
739       while ((p = enum_sig_subpkt (sig->hashed, *i, &len, &seq, &crit)))
740         print_one_subpacket (*i, len, 0x01 | (crit ? 0x02 : 0), p);
741
742       seq = 0;
743
744       while ((p = enum_sig_subpkt (sig->unhashed, *i, &len, &seq, &crit)))
745         print_one_subpacket (*i, len, 0x00 | (crit ? 0x02 : 0), p);
746     }
747 }
748
749
750 void
751 dump_attribs (const PKT_user_id *uid, PKT_public_key *pk)
752 {
753   int i;
754
755   if (!attrib_fp)
756     return;
757
758   for (i = 0; i < uid->numattribs; i++)
759     {
760       if (is_status_enabled ())
761         {
762           byte array[MAX_FINGERPRINT_LEN], *p;
763           char buf[(MAX_FINGERPRINT_LEN * 2) + 90];
764           size_t j, n;
765
766           if (!pk)
767             BUG ();
768           fingerprint_from_pk (pk, array, &n);
769
770           p = array;
771           for (j = 0; j < n; j++, p++)
772             sprintf (buf + 2 * j, "%02X", *p);
773
774           sprintf (buf + strlen (buf), " %lu %u %u %u %lu %lu %u",
775                    (ulong) uid->attribs[i].len, uid->attribs[i].type, i + 1,
776                    uid->numattribs, (ulong) uid->created,
777                    (ulong) uid->expiredate,
778                    ((uid->is_primary ? 0x01 : 0) | (uid->
779                                                     is_revoked ? 0x02 : 0) |
780                     (uid->is_expired ? 0x04 : 0)));
781           write_status_text (STATUS_ATTRIBUTE, buf);
782         }
783
784       es_fwrite (uid->attribs[i].data, uid->attribs[i].len, 1, attrib_fp);
785       es_fflush (attrib_fp);
786     }
787 }
788
789
790 static void
791 list_keyblock_print (KBNODE keyblock, int secret, int fpr, void *opaque)
792 {
793   int rc;
794   KBNODE kbctx;
795   KBNODE node;
796   PKT_public_key *pk;
797   struct sig_stats *stats = opaque;
798   int skip_sigs = 0;
799   int s2k_char;
800   char *hexgrip = NULL;
801   char *serialno = NULL;
802   char pkstrbuf[PUBKEY_STRING_SIZE];
803
804   /* Get the keyid from the keyblock.  */
805   node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
806   if (!node)
807     {
808       log_error ("Oops; key lost!\n");
809       dump_kbnode (keyblock);
810       return;
811     }
812
813   pk = node->pkt->pkt.public_key;
814
815   if (secret || opt.with_keygrip)
816     {
817       rc = hexkeygrip_from_pk (pk, &hexgrip);
818       if (rc)
819         log_error ("error computing a keygrip: %s\n", gpg_strerror (rc));
820     }
821
822   if (secret)
823     {
824       if (!agent_get_keyinfo (NULL, hexgrip, &serialno))
825         s2k_char = serialno? '>':' ';
826       else
827         s2k_char = '#';  /* Key not found.  */
828     }
829   else
830     s2k_char = ' ';
831
832   check_trustdb_stale ();
833
834
835   es_fprintf (es_stdout, "%s%c  %s/%s %s",
836               secret? "sec":"pub",
837               s2k_char,
838               pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
839               keystr_from_pk (pk), datestr_from_pk (pk));
840
841   if ((opt.list_options & LIST_SHOW_USAGE))
842     {
843       es_fprintf (es_stdout, " [%s]", usagestr_from_pk (pk, 0));
844     }
845   if (pk->flags.revoked)
846     {
847       es_fprintf (es_stdout, " [");
848       es_fprintf (es_stdout, _("revoked: %s"), revokestr_from_pk (pk));
849       es_fprintf (es_stdout, "]");
850     }
851   else if (pk->has_expired)
852     {
853       es_fprintf (es_stdout, " [");
854       es_fprintf (es_stdout, _("expired: %s"), expirestr_from_pk (pk));
855       es_fprintf (es_stdout, "]");
856     }
857   else if (pk->expiredate)
858     {
859       es_fprintf (es_stdout, " [");
860       es_fprintf (es_stdout, _("expires: %s"), expirestr_from_pk (pk));
861       es_fprintf (es_stdout, "]");
862     }
863
864 #if 0
865   /* I need to think about this some more.  It's easy enough to
866      include, but it looks sort of confusing in the listing... */
867   if (opt.list_options & LIST_SHOW_VALIDITY)
868     {
869       int validity = get_validity (pk, NULL);
870       es_fprintf (es_stdout, " [%s]", trust_value_to_string (validity));
871     }
872 #endif
873
874   if (pk->pubkey_algo >= 100)
875     es_fprintf (es_stdout, " [experimental algorithm %d]", pk->pubkey_algo);
876
877   es_fprintf (es_stdout, "\n");
878
879   if (fpr)
880     print_fingerprint (NULL, pk, 0);
881
882   if (opt.with_keygrip && hexgrip)
883     es_fprintf (es_stdout, "      Keygrip = %s\n", hexgrip);
884
885   if (serialno)
886     print_card_serialno (serialno);
887
888   if (opt.with_key_data)
889     print_key_data (pk);
890
891   for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0));)
892     {
893       if (node->pkt->pkttype == PKT_USER_ID && !opt.fast_list_mode)
894         {
895           PKT_user_id *uid = node->pkt->pkt.user_id;
896
897           if (pk && (uid->is_expired || uid->is_revoked)
898               && !(opt.list_options & LIST_SHOW_UNUSABLE_UIDS))
899             {
900               skip_sigs = 1;
901               continue;
902             }
903           else
904             skip_sigs = 0;
905
906           if (attrib_fp && uid->attrib_data != NULL)
907             dump_attribs (uid, pk);
908
909           if ((uid->is_revoked || uid->is_expired)
910               || ((opt.list_options & LIST_SHOW_UID_VALIDITY) && pk))
911             {
912               const char *validity;
913               int indent;
914
915               validity = uid_trust_string_fixed (pk, uid);
916               indent =
917                 (keystrlen () + 9) -
918                 atoi (uid_trust_string_fixed (NULL, NULL));
919
920               if (indent < 0 || indent > 40)
921                 indent = 0;
922
923               es_fprintf (es_stdout, "uid%*s%s ", indent, "", validity);
924             }
925           else
926             es_fprintf (es_stdout, "uid%*s", (int) keystrlen () + 10, "");
927
928           print_utf8_buffer (es_stdout, uid->name, uid->len);
929           es_putc ('\n', es_stdout);
930
931           if ((opt.list_options & LIST_SHOW_PHOTOS) && uid->attribs != NULL)
932             show_photos (uid->attribs, uid->numattribs, pk, uid);
933         }
934       else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
935         {
936           PKT_public_key *pk2 = node->pkt->pkt.public_key;
937
938           if ((pk2->flags.revoked || pk2->has_expired)
939               && !(opt.list_options & LIST_SHOW_UNUSABLE_SUBKEYS))
940             {
941               skip_sigs = 1;
942               continue;
943             }
944           else
945             skip_sigs = 0;
946
947           xfree (serialno); serialno = NULL;
948           xfree (hexgrip); hexgrip = NULL;
949           if (secret || opt.with_keygrip)
950             {
951               rc = hexkeygrip_from_pk (pk2, &hexgrip);
952               if (rc)
953                 log_error ("error computing a keygrip: %s\n",
954                            gpg_strerror (rc));
955             }
956           if (secret)
957             {
958               if (!agent_get_keyinfo (NULL, hexgrip, &serialno))
959                 s2k_char = serialno? '>':' ';
960               else
961                 s2k_char = '#';  /* Key not found.  */
962             }
963           else
964             s2k_char = ' ';
965
966           es_fprintf (es_stdout, "%s%c  %s/%s %s",
967                   secret? "ssb":"sub",
968                   s2k_char,
969                   pubkey_string (pk2, pkstrbuf, sizeof pkstrbuf),
970                   keystr_from_pk (pk2), datestr_from_pk (pk2));
971
972           if (pk2->pubkey_algo == PUBKEY_ALGO_ECDSA
973               || pk2->pubkey_algo == PUBKEY_ALGO_EDDSA
974               || pk2->pubkey_algo == PUBKEY_ALGO_ECDH)
975             {
976               char *curve = openpgp_oid_to_str (pk2->pkey[0]);
977               const char *name = openpgp_oid_to_curve (curve);
978               if (!*name || *name == '?')
979                 name = curve;
980               es_fprintf (es_stdout, " %s", name);
981               xfree (curve);
982             }
983
984           if ((opt.list_options & LIST_SHOW_USAGE))
985             {
986               es_fprintf (es_stdout, " [%s]", usagestr_from_pk (pk2, 0));
987             }
988           if (pk2->flags.revoked)
989             {
990               es_fprintf (es_stdout, " [");
991               es_fprintf (es_stdout, _("revoked: %s"), revokestr_from_pk (pk2));
992               es_fprintf (es_stdout, "]");
993             }
994           else if (pk2->has_expired)
995             {
996               es_fprintf (es_stdout, " [");
997               es_fprintf (es_stdout, _("expired: %s"), expirestr_from_pk (pk2));
998               es_fprintf (es_stdout, "]");
999             }
1000           else if (pk2->expiredate)
1001             {
1002               es_fprintf (es_stdout, " [");
1003               es_fprintf (es_stdout, _("expires: %s"), expirestr_from_pk (pk2));
1004               es_fprintf (es_stdout, "]");
1005             }
1006           es_putc ('\n', es_stdout);
1007           if (fpr > 1)
1008             {
1009               print_fingerprint (NULL, pk2, 0);
1010               if (serialno)
1011                 print_card_serialno (serialno);
1012             }
1013           if (opt.with_keygrip && hexgrip)
1014             es_fprintf (es_stdout, "      Keygrip = %s\n", hexgrip);
1015           if (opt.with_key_data)
1016             print_key_data (pk2);
1017         }
1018       else if (opt.list_sigs
1019                && node->pkt->pkttype == PKT_SIGNATURE && !skip_sigs)
1020         {
1021           PKT_signature *sig = node->pkt->pkt.signature;
1022           int sigrc;
1023           char *sigstr;
1024
1025           if (stats)
1026             {
1027               rc = check_key_signature (keyblock, node, NULL);
1028               switch (gpg_err_code (rc))
1029                 {
1030                 case 0:
1031                   sigrc = '!';
1032                   break;
1033                 case GPG_ERR_BAD_SIGNATURE:
1034                   stats->inv_sigs++;
1035                   sigrc = '-';
1036                   break;
1037                 case GPG_ERR_NO_PUBKEY:
1038                 case GPG_ERR_UNUSABLE_PUBKEY:
1039                   stats->no_key++;
1040                   continue;
1041                 default:
1042                   stats->oth_err++;
1043                   sigrc = '%';
1044                   break;
1045                 }
1046
1047               /* TODO: Make sure a cached sig record here still has
1048                  the pk that issued it.  See also
1049                  keyedit.c:print_and_check_one_sig */
1050             }
1051           else
1052             {
1053               rc = 0;
1054               sigrc = ' ';
1055             }
1056
1057           if (sig->sig_class == 0x20 || sig->sig_class == 0x28
1058               || sig->sig_class == 0x30)
1059             sigstr = "rev";
1060           else if ((sig->sig_class & ~3) == 0x10)
1061             sigstr = "sig";
1062           else if (sig->sig_class == 0x18)
1063             sigstr = "sig";
1064           else if (sig->sig_class == 0x1F)
1065             sigstr = "sig";
1066           else
1067             {
1068               es_fprintf (es_stdout, "sig                             "
1069                       "[unexpected signature class 0x%02x]\n",
1070                       sig->sig_class);
1071               continue;
1072             }
1073
1074           es_fputs (sigstr, es_stdout);
1075           es_fprintf (es_stdout, "%c%c %c%c%c%c%c%c %s %s",
1076                   sigrc, (sig->sig_class - 0x10 > 0 &&
1077                           sig->sig_class - 0x10 <
1078                           4) ? '0' + sig->sig_class - 0x10 : ' ',
1079                   sig->flags.exportable ? ' ' : 'L',
1080                   sig->flags.revocable ? ' ' : 'R',
1081                   sig->flags.policy_url ? 'P' : ' ',
1082                   sig->flags.notation ? 'N' : ' ',
1083                   sig->flags.expired ? 'X' : ' ',
1084                   (sig->trust_depth > 9) ? 'T' : (sig->trust_depth >
1085                                                   0) ? '0' +
1086                   sig->trust_depth : ' ', keystr (sig->keyid),
1087                   datestr_from_sig (sig));
1088           if (opt.list_options & LIST_SHOW_SIG_EXPIRE)
1089             es_fprintf (es_stdout, " %s", expirestr_from_sig (sig));
1090           es_fprintf (es_stdout, "  ");
1091           if (sigrc == '%')
1092             es_fprintf (es_stdout, "[%s] ", g10_errstr (rc));
1093           else if (sigrc == '?')
1094             ;
1095           else if (!opt.fast_list_mode)
1096             {
1097               size_t n;
1098               char *p = get_user_id (sig->keyid, &n);
1099               print_utf8_buffer (es_stdout, p, n);
1100               xfree (p);
1101             }
1102           es_putc ('\n', es_stdout);
1103
1104           if (sig->flags.policy_url
1105               && (opt.list_options & LIST_SHOW_POLICY_URLS))
1106             show_policy_url (sig, 3, 0);
1107
1108           if (sig->flags.notation && (opt.list_options & LIST_SHOW_NOTATIONS))
1109             show_notation (sig, 3, 0,
1110                            ((opt.
1111                              list_options & LIST_SHOW_STD_NOTATIONS) ? 1 : 0)
1112                            +
1113                            ((opt.
1114                              list_options & LIST_SHOW_USER_NOTATIONS) ? 2 :
1115                             0));
1116
1117           if (sig->flags.pref_ks
1118               && (opt.list_options & LIST_SHOW_KEYSERVER_URLS))
1119             show_keyserver_url (sig, 3, 0);
1120
1121           /* fixme: check or list other sigs here */
1122         }
1123     }
1124   es_putc ('\n', es_stdout);
1125   xfree (serialno);
1126   xfree (hexgrip);
1127 }
1128
1129 void
1130 print_revokers (estream_t fp, PKT_public_key * pk)
1131 {
1132   /* print the revoker record */
1133   if (!pk->revkey && pk->numrevkeys)
1134     BUG ();
1135   else
1136     {
1137       int i, j;
1138
1139       for (i = 0; i < pk->numrevkeys; i++)
1140         {
1141           byte *p;
1142
1143           es_fprintf (fp, "rvk:::%d::::::", pk->revkey[i].algid);
1144           p = pk->revkey[i].fpr;
1145           for (j = 0; j < 20; j++, p++)
1146             es_fprintf (fp, "%02X", *p);
1147           es_fprintf (fp, ":%02x%s:\n",
1148                       pk->revkey[i].class,
1149                       (pk->revkey[i].class & 0x40) ? "s" : "");
1150         }
1151     }
1152 }
1153
1154
1155 /* List a key in colon mode.  If SECRET is true this is a secret key
1156    record (i.e. requested via --list-secret-key).  If HAS_SECRET a
1157    secret key is available even if SECRET is not set.  */
1158 static void
1159 list_keyblock_colon (KBNODE keyblock, int secret, int has_secret, int fpr)
1160 {
1161   int rc;
1162   KBNODE kbctx;
1163   KBNODE node;
1164   PKT_public_key *pk;
1165   u32 keyid[2];
1166   int trustletter = 0;
1167   int ulti_hack = 0;
1168   int i;
1169   char *p;
1170   char *hexgrip = NULL;
1171   char *serialno = NULL;
1172   int stubkey;
1173
1174   /* Get the keyid from the keyblock.  */
1175   node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
1176   if (!node)
1177     {
1178       log_error ("Oops; key lost!\n");
1179       dump_kbnode (keyblock);
1180       return;
1181     }
1182
1183   pk = node->pkt->pkt.public_key;
1184   if (secret || has_secret || opt.with_keygrip || opt.with_key_data)
1185     {
1186       rc = hexkeygrip_from_pk (pk, &hexgrip);
1187       if (rc)
1188         log_error ("error computing a keygrip: %s\n", gpg_strerror (rc));
1189     }
1190   stubkey = 0;
1191   if ((secret||has_secret) && agent_get_keyinfo (NULL, hexgrip, &serialno))
1192     stubkey = 1;  /* Key not found.  */
1193
1194   keyid_from_pk (pk, keyid);
1195   es_fputs (secret? "sec:":"pub:", es_stdout);
1196   if (!pk->flags.valid)
1197     es_putc ('i', es_stdout);
1198   else if (pk->flags.revoked)
1199     es_putc ('r', es_stdout);
1200   else if (pk->has_expired)
1201     es_putc ('e', es_stdout);
1202   else if (opt.fast_list_mode || opt.no_expensive_trust_checks)
1203     ;
1204   else
1205     {
1206       trustletter = get_validity_info (pk, NULL);
1207       if (trustletter == 'u')
1208         ulti_hack = 1;
1209       es_putc (trustletter, es_stdout);
1210     }
1211
1212   es_fprintf (es_stdout, ":%u:%d:%08lX%08lX:%s:%s::",
1213           nbits_from_pk (pk),
1214           pk->pubkey_algo,
1215           (ulong) keyid[0], (ulong) keyid[1],
1216           colon_datestr_from_pk (pk), colon_strtime (pk->expiredate));
1217
1218   if (!opt.fast_list_mode && !opt.no_expensive_trust_checks)
1219     es_putc (get_ownertrust_info (pk), es_stdout);
1220   es_putc (':', es_stdout);
1221
1222   es_putc (':', es_stdout);
1223   es_putc (':', es_stdout);
1224   print_capabilities (pk, keyblock);
1225   es_putc (':', es_stdout);             /* End of field 13. */
1226   es_putc (':', es_stdout);             /* End of field 14. */
1227   if (secret || has_secret)
1228     {
1229       if (stubkey)
1230         es_putc ('#', es_stdout);
1231       else if (serialno)
1232         es_fputs (serialno, es_stdout);
1233       else if (has_secret)
1234         es_putc ('+', es_stdout);
1235     }
1236   es_putc (':', es_stdout);             /* End of field 15. */
1237   es_putc (':', es_stdout);             /* End of field 16. */
1238   if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA
1239       || pk->pubkey_algo == PUBKEY_ALGO_EDDSA
1240       || pk->pubkey_algo == PUBKEY_ALGO_ECDH)
1241     {
1242       char *curve = openpgp_oid_to_str (pk->pkey[0]);
1243       const char *name = openpgp_oid_to_curve (curve);
1244       if (!*name || *name == '?')
1245         name = curve;
1246       es_fputs (name, es_stdout);
1247       xfree (curve);
1248     }
1249   es_putc (':', es_stdout);             /* End of field 17. */
1250   es_putc ('\n', es_stdout);
1251
1252   print_revokers (es_stdout, pk);
1253   if (fpr)
1254     print_fingerprint (NULL, pk, 0);
1255   if (opt.with_key_data || opt.with_keygrip)
1256     {
1257       if (hexgrip)
1258         es_fprintf (es_stdout, "grp:::::::::%s:\n", hexgrip);
1259       if (opt.with_key_data)
1260         print_key_data (pk);
1261     }
1262
1263   for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0));)
1264     {
1265       if (node->pkt->pkttype == PKT_USER_ID && !opt.fast_list_mode)
1266         {
1267           char *str;
1268           PKT_user_id *uid = node->pkt->pkt.user_id;
1269
1270           if (attrib_fp && node->pkt->pkt.user_id->attrib_data != NULL)
1271             dump_attribs (node->pkt->pkt.user_id, pk);
1272           /*
1273            * Fixme: We need a valid flag here too
1274            */
1275           str = uid->attrib_data ? "uat" : "uid";
1276           if (uid->is_revoked)
1277             es_fprintf (es_stdout, "%s:r::::", str);
1278           else if (uid->is_expired)
1279             es_fprintf (es_stdout, "%s:e::::", str);
1280           else if (opt.no_expensive_trust_checks)
1281             es_fprintf (es_stdout, "%s:::::", str);
1282           else
1283             {
1284               int uid_validity;
1285
1286               if (pk && !ulti_hack)
1287                 uid_validity = get_validity_info (pk, uid);
1288               else
1289                 uid_validity = 'u';
1290               es_fprintf (es_stdout, "%s:%c::::", str, uid_validity);
1291             }
1292
1293           es_fprintf (es_stdout, "%s:", colon_strtime (uid->created));
1294           es_fprintf (es_stdout, "%s:", colon_strtime (uid->expiredate));
1295
1296           namehash_from_uid (uid);
1297
1298           for (i = 0; i < 20; i++)
1299             es_fprintf (es_stdout, "%02X", uid->namehash[i]);
1300
1301           es_fprintf (es_stdout, "::");
1302
1303           if (uid->attrib_data)
1304             es_fprintf (es_stdout, "%u %lu", uid->numattribs, uid->attrib_len);
1305           else
1306             es_write_sanitized (es_stdout, uid->name, uid->len, ":", NULL);
1307           es_putc (':', es_stdout);
1308           es_putc ('\n', es_stdout);
1309         }
1310       else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
1311         {
1312           u32 keyid2[2];
1313           PKT_public_key *pk2;
1314
1315           pk2 = node->pkt->pkt.public_key;
1316           xfree (hexgrip); hexgrip = NULL;
1317           xfree (serialno); serialno = NULL;
1318           if (secret || has_secret || opt.with_keygrip || opt.with_key_data)
1319             {
1320               rc = hexkeygrip_from_pk (pk2, &hexgrip);
1321               if (rc)
1322                 log_error ("error computing a keygrip: %s\n",
1323                            gpg_strerror (rc));
1324             }
1325           stubkey = 0;
1326           if ((secret||has_secret)
1327               && agent_get_keyinfo (NULL, hexgrip, &serialno))
1328             stubkey = 1;  /* Key not found.  */
1329
1330           keyid_from_pk (pk2, keyid2);
1331           es_fputs (secret? "ssb:":"sub:", es_stdout);
1332           if (!pk2->flags.valid)
1333             es_putc ('i', es_stdout);
1334           else if (pk2->flags.revoked)
1335             es_putc ('r', es_stdout);
1336           else if (pk2->has_expired)
1337             es_putc ('e', es_stdout);
1338           else if (opt.fast_list_mode || opt.no_expensive_trust_checks)
1339             ;
1340           else
1341             {
1342               /* TRUSTLETTER should always be defined here. */
1343               if (trustletter)
1344                 es_fprintf (es_stdout, "%c", trustletter);
1345             }
1346           es_fprintf (es_stdout, ":%u:%d:%08lX%08lX:%s:%s:::::",
1347                   nbits_from_pk (pk2),
1348                   pk2->pubkey_algo,
1349                   (ulong) keyid2[0], (ulong) keyid2[1],
1350                   colon_datestr_from_pk (pk2), colon_strtime (pk2->expiredate)
1351                   /* fixme: add LID and ownertrust here */
1352             );
1353           print_capabilities (pk2, NULL);
1354           es_putc (':', es_stdout);     /* End of field 13. */
1355           es_putc (':', es_stdout);     /* End of field 14. */
1356           if (secret || has_secret)
1357             {
1358               if (stubkey)
1359                 es_putc ('#', es_stdout);
1360               else if (serialno)
1361                 es_fputs (serialno, es_stdout);
1362               else if (has_secret)
1363                 es_putc ('+', es_stdout);
1364             }
1365           es_putc (':', es_stdout);     /* End of field 15. */
1366           es_putc (':', es_stdout);     /* End of field 16. */
1367           if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA
1368               || pk->pubkey_algo == PUBKEY_ALGO_EDDSA
1369               || pk->pubkey_algo == PUBKEY_ALGO_ECDH)
1370             {
1371               char *curve = openpgp_oid_to_str (pk->pkey[0]);
1372               const char *name = openpgp_oid_to_curve (curve);
1373               if (!*name || *name == '?')
1374                 name = curve;
1375               es_fputs (name, es_stdout);
1376               xfree (curve);
1377             }
1378           es_putc (':', es_stdout);     /* End of field 17. */
1379           es_putc ('\n', es_stdout);
1380           if (fpr > 1)
1381             print_fingerprint (NULL, pk2, 0);
1382           if (opt.with_key_data || opt.with_keygrip)
1383             {
1384               if (hexgrip)
1385                 es_fprintf (es_stdout, "grp:::::::::%s:\n", hexgrip);
1386               if (opt.with_key_data)
1387                 print_key_data (pk2);
1388             }
1389         }
1390       else if (opt.list_sigs && node->pkt->pkttype == PKT_SIGNATURE)
1391         {
1392           PKT_signature *sig = node->pkt->pkt.signature;
1393           int sigrc, fprokay = 0;
1394           char *sigstr;
1395           size_t fplen;
1396           byte fparray[MAX_FINGERPRINT_LEN];
1397
1398           if (sig->sig_class == 0x20 || sig->sig_class == 0x28
1399               || sig->sig_class == 0x30)
1400             sigstr = "rev";
1401           else if ((sig->sig_class & ~3) == 0x10)
1402             sigstr = "sig";
1403           else if (sig->sig_class == 0x18)
1404             sigstr = "sig";
1405           else if (sig->sig_class == 0x1F)
1406             sigstr = "sig";
1407           else
1408             {
1409               es_fprintf (es_stdout, "sig::::::::::%02x%c:\n",
1410                       sig->sig_class, sig->flags.exportable ? 'x' : 'l');
1411               continue;
1412             }
1413
1414           if (opt.check_sigs)
1415             {
1416               PKT_public_key *signer_pk = NULL;
1417
1418               fflush (stdout);
1419               if (opt.no_sig_cache)
1420                 signer_pk = xmalloc_clear (sizeof (PKT_public_key));
1421
1422               rc = check_key_signature2 (keyblock, node, NULL, signer_pk,
1423                                          NULL, NULL, NULL);
1424               switch (gpg_err_code (rc))
1425                 {
1426                 case 0:
1427                   sigrc = '!';
1428                   break;
1429                 case GPG_ERR_BAD_SIGNATURE:
1430                   sigrc = '-';
1431                   break;
1432                 case GPG_ERR_NO_PUBKEY:
1433                 case GPG_ERR_UNUSABLE_PUBKEY:
1434                   sigrc = '?';
1435                   break;
1436                 default:
1437                   sigrc = '%';
1438                   break;
1439                 }
1440
1441               if (opt.no_sig_cache)
1442                 {
1443                   if (!rc)
1444                     {
1445                       fingerprint_from_pk (signer_pk, fparray, &fplen);
1446                       fprokay = 1;
1447                     }
1448                   free_public_key (signer_pk);
1449                 }
1450             }
1451           else
1452             {
1453               rc = 0;
1454               sigrc = ' ';
1455             }
1456           es_fputs (sigstr, es_stdout);
1457           es_putc (':', es_stdout);
1458           if (sigrc != ' ')
1459             es_putc (sigrc, es_stdout);
1460           es_fprintf (es_stdout, "::%d:%08lX%08lX:%s:%s:", sig->pubkey_algo,
1461                   (ulong) sig->keyid[0], (ulong) sig->keyid[1],
1462                   colon_datestr_from_sig (sig),
1463                   colon_expirestr_from_sig (sig));
1464
1465           if (sig->trust_depth || sig->trust_value)
1466             es_fprintf (es_stdout, "%d %d", sig->trust_depth, sig->trust_value);
1467           es_fprintf (es_stdout, ":");
1468
1469           if (sig->trust_regexp)
1470             es_write_sanitized (es_stdout, sig->trust_regexp,
1471                                 strlen (sig->trust_regexp), ":", NULL);
1472           es_fprintf (es_stdout, ":");
1473
1474           if (sigrc == '%')
1475             es_fprintf (es_stdout, "[%s] ", g10_errstr (rc));
1476           else if (sigrc == '?')
1477             ;
1478           else if (!opt.fast_list_mode)
1479             {
1480               size_t n;
1481               p = get_user_id (sig->keyid, &n);
1482               es_write_sanitized (es_stdout, p, n, ":", NULL);
1483               xfree (p);
1484             }
1485           es_fprintf (es_stdout, ":%02x%c::", sig->sig_class,
1486                   sig->flags.exportable ? 'x' : 'l');
1487
1488           if (opt.no_sig_cache && opt.check_sigs && fprokay)
1489             {
1490               for (i = 0; i < fplen; i++)
1491                 es_fprintf (es_stdout, "%02X", fparray[i]);
1492             }
1493
1494           es_fprintf (es_stdout, ":::%d:\n", sig->digest_algo);
1495
1496           if (opt.show_subpackets)
1497             print_subpackets_colon (sig);
1498
1499           /* fixme: check or list other sigs here */
1500         }
1501     }
1502
1503   xfree (hexgrip);
1504   xfree (serialno);
1505 }
1506
1507 /*
1508  * Reorder the keyblock so that the primary user ID (and not attribute
1509  * packet) comes first.  Fixme: Replace this by a generic sort
1510  * function.  */
1511 static void
1512 do_reorder_keyblock (KBNODE keyblock, int attr)
1513 {
1514   KBNODE primary = NULL, primary0 = NULL, primary2 = NULL;
1515   KBNODE last, node;
1516
1517   for (node = keyblock; node; primary0 = node, node = node->next)
1518     {
1519       if (node->pkt->pkttype == PKT_USER_ID &&
1520           ((attr && node->pkt->pkt.user_id->attrib_data) ||
1521            (!attr && !node->pkt->pkt.user_id->attrib_data)) &&
1522           node->pkt->pkt.user_id->is_primary)
1523         {
1524           primary = primary2 = node;
1525           for (node = node->next; node; primary2 = node, node = node->next)
1526             {
1527               if (node->pkt->pkttype == PKT_USER_ID
1528                   || node->pkt->pkttype == PKT_PUBLIC_SUBKEY
1529                   || node->pkt->pkttype == PKT_SECRET_SUBKEY)
1530                 {
1531                   break;
1532                 }
1533             }
1534           break;
1535         }
1536     }
1537   if (!primary)
1538     return; /* No primary key flag found (should not happen).  */
1539
1540   for (last = NULL, node = keyblock; node; last = node, node = node->next)
1541     {
1542       if (node->pkt->pkttype == PKT_USER_ID)
1543         break;
1544     }
1545   assert (node);
1546   assert (last);         /* The user ID is never the first packet.  */
1547   assert (primary0);     /* Ditto (this is the node before primary).  */
1548   if (node == primary)
1549     return; /* Already the first one.  */
1550
1551   last->next = primary;
1552   primary0->next = primary2->next;
1553   primary2->next = node;
1554 }
1555
1556 void
1557 reorder_keyblock (KBNODE keyblock)
1558 {
1559   do_reorder_keyblock (keyblock, 1);
1560   do_reorder_keyblock (keyblock, 0);
1561 }
1562
1563 void
1564 list_keyblock (KBNODE keyblock, int secret, int has_secret, int fpr,
1565                void *opaque)
1566 {
1567   reorder_keyblock (keyblock);
1568   if (opt.with_colons)
1569     list_keyblock_colon (keyblock, secret, has_secret, fpr);
1570   else
1571     list_keyblock_print (keyblock, secret, fpr, opaque);
1572 }
1573
1574 /*
1575  * Function to print the finperprint.
1576  * mode 0: as used in key listings, opt.with_colons is honored
1577  *      1: print using log_info ()
1578  *      2: direct use of tty
1579  *      3: direct use of tty but only primary key.
1580  *
1581  * Modes 1 and 2 will try and print both subkey and primary key
1582  * fingerprints.  A MODE with bit 7 set is used internally.  If
1583  * OVERRIDE_FP is not NULL that stream will be used in  0 instead
1584  * of es_stdout or instead of the TTY in modes 2 and 3.
1585  */
1586 void
1587 print_fingerprint (estream_t override_fp, PKT_public_key *pk, int mode)
1588 {
1589   byte array[MAX_FINGERPRINT_LEN], *p;
1590   size_t i, n;
1591   estream_t fp;
1592   const char *text;
1593   int primary = 0;
1594
1595   if (pk->main_keyid[0] == pk->keyid[0]
1596       && pk->main_keyid[1] == pk->keyid[1])
1597     primary = 1;
1598
1599   /* Just to be safe */
1600   if ((mode & 0x80) && !primary)
1601     {
1602       log_error ("primary key is not really primary!\n");
1603       return;
1604     }
1605
1606   mode &= ~0x80;
1607
1608   if (!primary && (mode == 1 || mode == 2))
1609     {
1610       PKT_public_key *primary_pk = xmalloc_clear (sizeof (*primary_pk));
1611       get_pubkey (primary_pk, pk->main_keyid);
1612       print_fingerprint (override_fp, primary_pk, (mode | 0x80));
1613       free_public_key (primary_pk);
1614     }
1615
1616   if (mode == 1)
1617     {
1618       fp = log_get_stream ();
1619       if (primary)
1620         text = _("Primary key fingerprint:");
1621       else
1622         text = _("     Subkey fingerprint:");
1623     }
1624   else if (mode == 2)
1625     {
1626       fp = override_fp; /* Use tty or given stream.  */
1627       if (primary)
1628         /* TRANSLATORS: this should fit into 24 bytes to that the
1629          * fingerprint data is properly aligned with the user ID */
1630         text = _(" Primary key fingerprint:");
1631       else
1632         text = _("      Subkey fingerprint:");
1633     }
1634   else if (mode == 3)
1635     {
1636       fp = override_fp; /* Use tty or given stream.  */
1637       text = _("      Key fingerprint =");
1638     }
1639   else
1640     {
1641       fp = override_fp? override_fp : es_stdout;
1642       text = _("      Key fingerprint =");
1643     }
1644
1645   fingerprint_from_pk (pk, array, &n);
1646   p = array;
1647   if (opt.with_colons && !mode)
1648     {
1649       es_fprintf (fp, "fpr:::::::::");
1650       for (i = 0; i < n; i++, p++)
1651         es_fprintf (fp, "%02X", *p);
1652       es_putc (':', fp);
1653     }
1654   else
1655     {
1656       tty_fprintf (fp, "%s", text);
1657       if (n == 20)
1658         {
1659           for (i = 0; i < n; i++, i++, p += 2)
1660             tty_fprintf (fp, "%s %02X%02X", i==10? " ":"", *p, p[1]);
1661         }
1662       else
1663         {
1664           for (i = 0; i < n; i++, p++)
1665             tty_fprintf (fp, "%s %02X", (i && !(i % 8))? " ":"", *p);
1666         }
1667     }
1668   tty_fprintf (fp, "\n");
1669 }
1670
1671 /* Print the serial number of an OpenPGP card if available.  */
1672 static void
1673 print_card_serialno (const char *serialno)
1674 {
1675   if (!serialno)
1676     return;
1677   if (opt.with_colons)
1678     return; /* Handled elsewhere. */
1679
1680   es_fputs (_("      Card serial no. ="), es_stdout);
1681   es_putc (' ', es_stdout);
1682   if (strlen (serialno) == 32 && !strncmp (serialno, "D27600012401", 12))
1683     {
1684       /* This is an OpenPGP card.  Print the relevant part.  */
1685       /* Example: D2760001240101010001000003470000 */
1686       /*                          xxxxyyyyyyyy     */
1687       es_fprintf (es_stdout, "%.*s %.*s", 4, serialno+16, 8, serialno+20);
1688     }
1689  else
1690    es_fputs (serialno, es_stdout);
1691   es_putc ('\n', es_stdout);
1692 }
1693
1694
1695
1696 void
1697 set_attrib_fd (int fd)
1698 {
1699   static int last_fd = -1;
1700
1701   if (fd != -1 && last_fd == fd)
1702     return;
1703
1704   /* Fixme: Do we need to check for the log stream here?  */
1705   if (attrib_fp && attrib_fp != log_get_stream ())
1706     es_fclose (attrib_fp);
1707   attrib_fp = NULL;
1708   if (fd == -1)
1709     return;
1710
1711 #ifdef HAVE_DOSISH_SYSTEM
1712   setmode (fd, O_BINARY);
1713 #endif
1714   if (fd == 1)
1715     attrib_fp = es_stdout;
1716   else if (fd == 2)
1717     attrib_fp = es_stderr;
1718   else
1719     attrib_fp = es_fdopen (fd, "wb");
1720   if (!attrib_fp)
1721     {
1722       log_fatal ("can't open fd %d for attribute output: %s\n",
1723                  fd, strerror (errno));
1724     }
1725
1726   last_fd = fd;
1727 }