gpg: Fix export of ecc secret keys by adjusting check ordering.
[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 <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   if (rc && gpg_err_code (rc) != GPG_ERR_NOT_FOUND)
500     log_error ("keydb_search_next failed: %s\n", g10_errstr (rc));
501
502   if (opt.check_sigs && !opt.with_colons)
503     print_signature_stats (&stats);
504
505 leave:
506   release_kbnode (keyblock);
507   keydb_release (hd);
508 }
509
510
511 static void
512 list_one (strlist_t names, int secret, int mark_secret)
513 {
514   int rc = 0;
515   KBNODE keyblock = NULL;
516   GETKEY_CTX ctx;
517   const char *resname;
518   const char *keyring_str = _("Keyring");
519   int i;
520   struct sig_stats stats;
521
522   memset (&stats, 0, sizeof (stats));
523
524   /* fixme: using the bynames function has the disadvantage that we
525    * don't know wether one of the names given was not found.  OTOH,
526    * this function has the advantage to list the names in the
527    * sequence as defined by the keyDB and does not duplicate
528    * outputs.  A solution could be do test whether all given have
529    * been listed (this needs a way to use the keyDB search
530    * functions) or to have the search function return indicators for
531    * found names.  Yet another way is to use the keydb search
532    * facilities directly. */
533   rc = getkey_bynames (&ctx, NULL, names, secret, &keyblock);
534   if (rc)
535     {
536       log_error ("error reading key: %s\n", g10_errstr (rc));
537       get_pubkey_end (ctx);
538       return;
539     }
540
541   do
542     {
543       if ((opt.list_options & LIST_SHOW_KEYRING) && !opt.with_colons)
544         {
545           resname = keydb_get_resource_name (get_ctx_handle (ctx));
546           es_fprintf (es_stdout, "%s: %s\n", keyring_str, resname);
547           for (i = strlen (resname) + strlen (keyring_str) + 2; i; i--)
548             es_putc ('-', es_stdout);
549           es_putc ('\n', es_stdout);
550         }
551       list_keyblock (keyblock, secret, mark_secret, opt.fingerprint,
552                      (!secret && opt.check_sigs)? &stats : NULL);
553       release_kbnode (keyblock);
554     }
555   while (!getkey_next (ctx, NULL, &keyblock));
556   getkey_end (ctx);
557
558   if (opt.check_sigs && !opt.with_colons)
559     print_signature_stats (&stats);
560 }
561
562
563 static void
564 locate_one (ctrl_t ctrl, strlist_t names)
565 {
566   int rc = 0;
567   strlist_t sl;
568   GETKEY_CTX ctx = NULL;
569   KBNODE keyblock = NULL;
570   struct sig_stats stats;
571
572   memset (&stats, 0, sizeof (stats));
573
574   for (sl = names; sl; sl = sl->next)
575     {
576       rc = get_pubkey_byname (ctrl, &ctx, NULL, sl->d, &keyblock, NULL, 1, 0);
577       if (rc)
578         {
579           if (gpg_err_code (rc) != GPG_ERR_NO_PUBKEY)
580             log_error ("error reading key: %s\n", g10_errstr (rc));
581         }
582       else
583         {
584           do
585             {
586               list_keyblock (keyblock, 0, 0, opt.fingerprint,
587                              opt.check_sigs ? &stats : NULL);
588               release_kbnode (keyblock);
589             }
590           while (ctx && !get_pubkey_next (ctx, NULL, &keyblock));
591           get_pubkey_end (ctx);
592           ctx = NULL;
593         }
594     }
595
596   if (opt.check_sigs && !opt.with_colons)
597     print_signature_stats (&stats);
598 }
599
600
601 static void
602 print_key_data (PKT_public_key * pk)
603 {
604   int n = pk ? pubkey_get_npkey (pk->pubkey_algo) : 0;
605   int i;
606
607   for (i = 0; i < n; i++)
608     {
609       es_fprintf (es_stdout, "pkd:%d:%u:", i, mpi_get_nbits (pk->pkey[i]));
610       mpi_print (es_stdout, pk->pkey[i], 1);
611       es_putc (':', es_stdout);
612       es_putc ('\n', es_stdout);
613     }
614 }
615
616 static void
617 print_capabilities (PKT_public_key *pk, KBNODE keyblock)
618 {
619   unsigned int use = pk->pubkey_usage;
620   int c_printed = 0;
621
622   if (use & PUBKEY_USAGE_ENC)
623     es_putc ('e', es_stdout);
624
625   if (use & PUBKEY_USAGE_SIG)
626     {
627       es_putc ('s', es_stdout);
628       if (pk->flags.primary)
629         {
630           es_putc ('c', es_stdout);
631           /* The PUBKEY_USAGE_CERT flag was introduced later and we
632              used to always print 'c' for a primary key.  To avoid any
633              regression here we better track whether we printed 'c'
634              already.  */
635           c_printed = 1;
636         }
637     }
638
639   if ((use & PUBKEY_USAGE_CERT) && !c_printed)
640     es_putc ('c', es_stdout);
641
642   if ((use & PUBKEY_USAGE_AUTH))
643     es_putc ('a', es_stdout);
644
645   if ((use & PUBKEY_USAGE_UNKNOWN))
646     es_putc ('?', es_stdout);
647
648   if (keyblock)
649     {
650       /* Figure out the usable capabilities.  */
651       KBNODE k;
652       int enc = 0, sign = 0, cert = 0, auth = 0, disabled = 0;
653
654       for (k = keyblock; k; k = k->next)
655         {
656           if (k->pkt->pkttype == PKT_PUBLIC_KEY
657               || k->pkt->pkttype == PKT_PUBLIC_SUBKEY)
658             {
659               pk = k->pkt->pkt.public_key;
660
661               if (pk->flags.primary)
662                 disabled = pk_is_disabled (pk);
663
664               if (pk->flags.valid && !pk->flags.revoked && !pk->has_expired)
665                 {
666                   if (pk->pubkey_usage & PUBKEY_USAGE_ENC)
667                     enc = 1;
668                   if (pk->pubkey_usage & PUBKEY_USAGE_SIG)
669                     {
670                       sign = 1;
671                       if (pk->flags.primary)
672                         cert = 1;
673                     }
674                   if (pk->pubkey_usage & PUBKEY_USAGE_CERT)
675                     cert = 1;
676                   if ((pk->pubkey_usage & PUBKEY_USAGE_AUTH))
677                     auth = 1;
678                 }
679             }
680         }
681       if (enc)
682         es_putc ('E', es_stdout);
683       if (sign)
684         es_putc ('S', es_stdout);
685       if (cert)
686         es_putc ('C', es_stdout);
687       if (auth)
688         es_putc ('A', es_stdout);
689       if (disabled)
690         es_putc ('D', es_stdout);
691     }
692
693   es_putc (':', es_stdout);
694 }
695
696
697 /* FLAGS: 0x01 hashed
698           0x02 critical  */
699 static void
700 print_one_subpacket (sigsubpkttype_t type, size_t len, int flags,
701                      const byte * buf)
702 {
703   size_t i;
704
705   es_fprintf (es_stdout, "spk:%d:%u:%u:", type, flags, (unsigned int) len);
706
707   for (i = 0; i < len; i++)
708     {
709       /* printable ascii other than : and % */
710       if (buf[i] >= 32 && buf[i] <= 126 && buf[i] != ':' && buf[i] != '%')
711         es_fprintf (es_stdout, "%c", buf[i]);
712       else
713         es_fprintf (es_stdout, "%%%02X", buf[i]);
714     }
715
716   es_fprintf (es_stdout, "\n");
717 }
718
719
720 void
721 print_subpackets_colon (PKT_signature * sig)
722 {
723   byte *i;
724
725   assert (opt.show_subpackets);
726
727   for (i = opt.show_subpackets; *i; i++)
728     {
729       const byte *p;
730       size_t len;
731       int seq, crit;
732
733       seq = 0;
734
735       while ((p = enum_sig_subpkt (sig->hashed, *i, &len, &seq, &crit)))
736         print_one_subpacket (*i, len, 0x01 | (crit ? 0x02 : 0), p);
737
738       seq = 0;
739
740       while ((p = enum_sig_subpkt (sig->unhashed, *i, &len, &seq, &crit)))
741         print_one_subpacket (*i, len, 0x00 | (crit ? 0x02 : 0), p);
742     }
743 }
744
745
746 void
747 dump_attribs (const PKT_user_id *uid, PKT_public_key *pk)
748 {
749   int i;
750
751   if (!attrib_fp)
752     return;
753
754   for (i = 0; i < uid->numattribs; i++)
755     {
756       if (is_status_enabled ())
757         {
758           byte array[MAX_FINGERPRINT_LEN], *p;
759           char buf[(MAX_FINGERPRINT_LEN * 2) + 90];
760           size_t j, n;
761
762           if (!pk)
763             BUG ();
764           fingerprint_from_pk (pk, array, &n);
765
766           p = array;
767           for (j = 0; j < n; j++, p++)
768             sprintf (buf + 2 * j, "%02X", *p);
769
770           sprintf (buf + strlen (buf), " %lu %u %u %u %lu %lu %u",
771                    (ulong) uid->attribs[i].len, uid->attribs[i].type, i + 1,
772                    uid->numattribs, (ulong) uid->created,
773                    (ulong) uid->expiredate,
774                    ((uid->is_primary ? 0x01 : 0) | (uid->
775                                                     is_revoked ? 0x02 : 0) |
776                     (uid->is_expired ? 0x04 : 0)));
777           write_status_text (STATUS_ATTRIBUTE, buf);
778         }
779
780       es_fwrite (uid->attribs[i].data, uid->attribs[i].len, 1, attrib_fp);
781       es_fflush (attrib_fp);
782     }
783 }
784
785
786 static void
787 list_keyblock_print (KBNODE keyblock, int secret, int fpr, void *opaque)
788 {
789   int rc;
790   KBNODE kbctx;
791   KBNODE node;
792   PKT_public_key *pk;
793   struct sig_stats *stats = opaque;
794   int skip_sigs = 0;
795   int s2k_char;
796   char *hexgrip = NULL;
797   char *serialno = NULL;
798   char pkstrbuf[PUBKEY_STRING_SIZE];
799
800   /* Get the keyid from the keyblock.  */
801   node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
802   if (!node)
803     {
804       log_error ("Oops; key lost!\n");
805       dump_kbnode (keyblock);
806       return;
807     }
808
809   pk = node->pkt->pkt.public_key;
810
811   if (secret || opt.with_keygrip)
812     {
813       rc = hexkeygrip_from_pk (pk, &hexgrip);
814       if (rc)
815         log_error ("error computing a keygrip: %s\n", gpg_strerror (rc));
816     }
817
818   if (secret)
819     {
820       if (!agent_get_keyinfo (NULL, hexgrip, &serialno))
821         s2k_char = serialno? '>':' ';
822       else
823         s2k_char = '#';  /* Key not found.  */
824     }
825   else
826     s2k_char = ' ';
827
828   check_trustdb_stale ();
829
830
831   es_fprintf (es_stdout, "%s%c  %s/%s %s",
832               secret? "sec":"pub",
833               s2k_char,
834               pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
835               keystr_from_pk (pk), datestr_from_pk (pk));
836
837   if ((opt.list_options & LIST_SHOW_USAGE))
838     {
839       es_fprintf (es_stdout, " [%s]", usagestr_from_pk (pk, 0));
840     }
841   if (pk->flags.revoked)
842     {
843       es_fprintf (es_stdout, " [");
844       es_fprintf (es_stdout, _("revoked: %s"), revokestr_from_pk (pk));
845       es_fprintf (es_stdout, "]");
846     }
847   else if (pk->has_expired)
848     {
849       es_fprintf (es_stdout, " [");
850       es_fprintf (es_stdout, _("expired: %s"), expirestr_from_pk (pk));
851       es_fprintf (es_stdout, "]");
852     }
853   else if (pk->expiredate)
854     {
855       es_fprintf (es_stdout, " [");
856       es_fprintf (es_stdout, _("expires: %s"), expirestr_from_pk (pk));
857       es_fprintf (es_stdout, "]");
858     }
859
860 #if 0
861   /* I need to think about this some more.  It's easy enough to
862      include, but it looks sort of confusing in the listing... */
863   if (opt.list_options & LIST_SHOW_VALIDITY)
864     {
865       int validity = get_validity (pk, NULL);
866       es_fprintf (es_stdout, " [%s]", trust_value_to_string (validity));
867     }
868 #endif
869
870   if (pk->pubkey_algo >= 100)
871     es_fprintf (es_stdout, " [experimental algorithm %d]", pk->pubkey_algo);
872
873   es_fprintf (es_stdout, "\n");
874
875   if (fpr)
876     print_fingerprint (NULL, pk, 0);
877
878   if (opt.with_keygrip && hexgrip)
879     es_fprintf (es_stdout, "      Keygrip = %s\n", hexgrip);
880
881   if (serialno)
882     print_card_serialno (serialno);
883
884   if (opt.with_key_data)
885     print_key_data (pk);
886
887   for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0));)
888     {
889       if (node->pkt->pkttype == PKT_USER_ID && !opt.fast_list_mode)
890         {
891           PKT_user_id *uid = node->pkt->pkt.user_id;
892
893           if (pk && (uid->is_expired || uid->is_revoked)
894               && !(opt.list_options & LIST_SHOW_UNUSABLE_UIDS))
895             {
896               skip_sigs = 1;
897               continue;
898             }
899           else
900             skip_sigs = 0;
901
902           if (attrib_fp && uid->attrib_data != NULL)
903             dump_attribs (uid, pk);
904
905           if ((uid->is_revoked || uid->is_expired)
906               || ((opt.list_options & LIST_SHOW_UID_VALIDITY) && pk))
907             {
908               const char *validity;
909               int indent;
910
911               validity = uid_trust_string_fixed (pk, uid);
912               indent =
913                 (keystrlen () + 9) -
914                 atoi (uid_trust_string_fixed (NULL, NULL));
915
916               if (indent < 0 || indent > 40)
917                 indent = 0;
918
919               es_fprintf (es_stdout, "uid%*s%s ", indent, "", validity);
920             }
921           else
922             es_fprintf (es_stdout, "uid%*s", (int) keystrlen () + 10, "");
923
924           print_utf8_buffer (es_stdout, uid->name, uid->len);
925           es_putc ('\n', es_stdout);
926
927           if ((opt.list_options & LIST_SHOW_PHOTOS) && uid->attribs != NULL)
928             show_photos (uid->attribs, uid->numattribs, pk, uid);
929         }
930       else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
931         {
932           PKT_public_key *pk2 = node->pkt->pkt.public_key;
933
934           if ((pk2->flags.revoked || pk2->has_expired)
935               && !(opt.list_options & LIST_SHOW_UNUSABLE_SUBKEYS))
936             {
937               skip_sigs = 1;
938               continue;
939             }
940           else
941             skip_sigs = 0;
942
943           xfree (serialno); serialno = NULL;
944           xfree (hexgrip); hexgrip = NULL;
945           if (secret || opt.with_keygrip)
946             {
947               rc = hexkeygrip_from_pk (pk2, &hexgrip);
948               if (rc)
949                 log_error ("error computing a keygrip: %s\n",
950                            gpg_strerror (rc));
951             }
952           if (secret)
953             {
954               if (!agent_get_keyinfo (NULL, hexgrip, &serialno))
955                 s2k_char = serialno? '>':' ';
956               else
957                 s2k_char = '#';  /* Key not found.  */
958             }
959           else
960             s2k_char = ' ';
961
962           es_fprintf (es_stdout, "%s%c  %s/%s %s",
963                   secret? "ssb":"sub",
964                   s2k_char,
965                   pubkey_string (pk2, pkstrbuf, sizeof pkstrbuf),
966                   keystr_from_pk (pk2), datestr_from_pk (pk2));
967
968           if (pk2->pubkey_algo == PUBKEY_ALGO_ECDSA
969               || pk2->pubkey_algo == PUBKEY_ALGO_EDDSA
970               || pk2->pubkey_algo == PUBKEY_ALGO_ECDH)
971             {
972               char *curve = openpgp_oid_to_str (pk2->pkey[0]);
973               const char *name = openpgp_oid_to_curve (curve);
974               if (!*name || *name == '?')
975                 name = curve;
976               es_fprintf (es_stdout, " %s", name);
977               xfree (curve);
978             }
979
980           if ((opt.list_options & LIST_SHOW_USAGE))
981             {
982               es_fprintf (es_stdout, " [%s]", usagestr_from_pk (pk2, 0));
983             }
984           if (pk2->flags.revoked)
985             {
986               es_fprintf (es_stdout, " [");
987               es_fprintf (es_stdout, _("revoked: %s"), revokestr_from_pk (pk2));
988               es_fprintf (es_stdout, "]");
989             }
990           else if (pk2->has_expired)
991             {
992               es_fprintf (es_stdout, " [");
993               es_fprintf (es_stdout, _("expired: %s"), expirestr_from_pk (pk2));
994               es_fprintf (es_stdout, "]");
995             }
996           else if (pk2->expiredate)
997             {
998               es_fprintf (es_stdout, " [");
999               es_fprintf (es_stdout, _("expires: %s"), expirestr_from_pk (pk2));
1000               es_fprintf (es_stdout, "]");
1001             }
1002           es_putc ('\n', es_stdout);
1003           if (fpr > 1)
1004             {
1005               print_fingerprint (NULL, pk2, 0);
1006               if (serialno)
1007                 print_card_serialno (serialno);
1008             }
1009           if (opt.with_keygrip && hexgrip)
1010             es_fprintf (es_stdout, "      Keygrip = %s\n", hexgrip);
1011           if (opt.with_key_data)
1012             print_key_data (pk2);
1013         }
1014       else if (opt.list_sigs
1015                && node->pkt->pkttype == PKT_SIGNATURE && !skip_sigs)
1016         {
1017           PKT_signature *sig = node->pkt->pkt.signature;
1018           int sigrc;
1019           char *sigstr;
1020
1021           if (stats)
1022             {
1023               rc = check_key_signature (keyblock, node, NULL);
1024               switch (gpg_err_code (rc))
1025                 {
1026                 case 0:
1027                   sigrc = '!';
1028                   break;
1029                 case GPG_ERR_BAD_SIGNATURE:
1030                   stats->inv_sigs++;
1031                   sigrc = '-';
1032                   break;
1033                 case GPG_ERR_NO_PUBKEY:
1034                 case GPG_ERR_UNUSABLE_PUBKEY:
1035                   stats->no_key++;
1036                   continue;
1037                 default:
1038                   stats->oth_err++;
1039                   sigrc = '%';
1040                   break;
1041                 }
1042
1043               /* TODO: Make sure a cached sig record here still has
1044                  the pk that issued it.  See also
1045                  keyedit.c:print_and_check_one_sig */
1046             }
1047           else
1048             {
1049               rc = 0;
1050               sigrc = ' ';
1051             }
1052
1053           if (sig->sig_class == 0x20 || sig->sig_class == 0x28
1054               || sig->sig_class == 0x30)
1055             sigstr = "rev";
1056           else if ((sig->sig_class & ~3) == 0x10)
1057             sigstr = "sig";
1058           else if (sig->sig_class == 0x18)
1059             sigstr = "sig";
1060           else if (sig->sig_class == 0x1F)
1061             sigstr = "sig";
1062           else
1063             {
1064               es_fprintf (es_stdout, "sig                             "
1065                       "[unexpected signature class 0x%02x]\n",
1066                       sig->sig_class);
1067               continue;
1068             }
1069
1070           es_fputs (sigstr, es_stdout);
1071           es_fprintf (es_stdout, "%c%c %c%c%c%c%c%c %s %s",
1072                   sigrc, (sig->sig_class - 0x10 > 0 &&
1073                           sig->sig_class - 0x10 <
1074                           4) ? '0' + sig->sig_class - 0x10 : ' ',
1075                   sig->flags.exportable ? ' ' : 'L',
1076                   sig->flags.revocable ? ' ' : 'R',
1077                   sig->flags.policy_url ? 'P' : ' ',
1078                   sig->flags.notation ? 'N' : ' ',
1079                   sig->flags.expired ? 'X' : ' ',
1080                   (sig->trust_depth > 9) ? 'T' : (sig->trust_depth >
1081                                                   0) ? '0' +
1082                   sig->trust_depth : ' ', keystr (sig->keyid),
1083                   datestr_from_sig (sig));
1084           if (opt.list_options & LIST_SHOW_SIG_EXPIRE)
1085             es_fprintf (es_stdout, " %s", expirestr_from_sig (sig));
1086           es_fprintf (es_stdout, "  ");
1087           if (sigrc == '%')
1088             es_fprintf (es_stdout, "[%s] ", g10_errstr (rc));
1089           else if (sigrc == '?')
1090             ;
1091           else if (!opt.fast_list_mode)
1092             {
1093               size_t n;
1094               char *p = get_user_id (sig->keyid, &n);
1095               print_utf8_buffer (es_stdout, p, n);
1096               xfree (p);
1097             }
1098           es_putc ('\n', es_stdout);
1099
1100           if (sig->flags.policy_url
1101               && (opt.list_options & LIST_SHOW_POLICY_URLS))
1102             show_policy_url (sig, 3, 0);
1103
1104           if (sig->flags.notation && (opt.list_options & LIST_SHOW_NOTATIONS))
1105             show_notation (sig, 3, 0,
1106                            ((opt.
1107                              list_options & LIST_SHOW_STD_NOTATIONS) ? 1 : 0)
1108                            +
1109                            ((opt.
1110                              list_options & LIST_SHOW_USER_NOTATIONS) ? 2 :
1111                             0));
1112
1113           if (sig->flags.pref_ks
1114               && (opt.list_options & LIST_SHOW_KEYSERVER_URLS))
1115             show_keyserver_url (sig, 3, 0);
1116
1117           /* fixme: check or list other sigs here */
1118         }
1119     }
1120   es_putc ('\n', es_stdout);
1121   xfree (serialno);
1122   xfree (hexgrip);
1123 }
1124
1125 void
1126 print_revokers (estream_t fp, PKT_public_key * pk)
1127 {
1128   /* print the revoker record */
1129   if (!pk->revkey && pk->numrevkeys)
1130     BUG ();
1131   else
1132     {
1133       int i, j;
1134
1135       for (i = 0; i < pk->numrevkeys; i++)
1136         {
1137           byte *p;
1138
1139           es_fprintf (fp, "rvk:::%d::::::", pk->revkey[i].algid);
1140           p = pk->revkey[i].fpr;
1141           for (j = 0; j < 20; j++, p++)
1142             es_fprintf (fp, "%02X", *p);
1143           es_fprintf (fp, ":%02x%s:\n",
1144                       pk->revkey[i].class,
1145                       (pk->revkey[i].class & 0x40) ? "s" : "");
1146         }
1147     }
1148 }
1149
1150
1151 /* List a key in colon mode.  If SECRET is true this is a secret key
1152    record (i.e. requested via --list-secret-key).  If HAS_SECRET a
1153    secret key is available even if SECRET is not set.  */
1154 static void
1155 list_keyblock_colon (KBNODE keyblock, int secret, int has_secret, int fpr)
1156 {
1157   int rc;
1158   KBNODE kbctx;
1159   KBNODE node;
1160   PKT_public_key *pk;
1161   u32 keyid[2];
1162   int trustletter = 0;
1163   int ulti_hack = 0;
1164   int i;
1165   char *p;
1166   char *hexgrip = NULL;
1167   char *serialno = NULL;
1168   int stubkey;
1169
1170   /* Get the keyid from the keyblock.  */
1171   node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
1172   if (!node)
1173     {
1174       log_error ("Oops; key lost!\n");
1175       dump_kbnode (keyblock);
1176       return;
1177     }
1178
1179   pk = node->pkt->pkt.public_key;
1180   if (secret || has_secret || opt.with_keygrip || opt.with_key_data)
1181     {
1182       rc = hexkeygrip_from_pk (pk, &hexgrip);
1183       if (rc)
1184         log_error ("error computing a keygrip: %s\n", gpg_strerror (rc));
1185     }
1186   stubkey = 0;
1187   if ((secret||has_secret) && agent_get_keyinfo (NULL, hexgrip, &serialno))
1188     stubkey = 1;  /* Key not found.  */
1189
1190   keyid_from_pk (pk, keyid);
1191   es_fputs (secret? "sec:":"pub:", es_stdout);
1192   if (!pk->flags.valid)
1193     es_putc ('i', es_stdout);
1194   else if (pk->flags.revoked)
1195     es_putc ('r', es_stdout);
1196   else if (pk->has_expired)
1197     es_putc ('e', es_stdout);
1198   else if (opt.fast_list_mode || opt.no_expensive_trust_checks)
1199     ;
1200   else
1201     {
1202       trustletter = get_validity_info (pk, NULL);
1203       if (trustletter == 'u')
1204         ulti_hack = 1;
1205       es_putc (trustletter, es_stdout);
1206     }
1207
1208   es_fprintf (es_stdout, ":%u:%d:%08lX%08lX:%s:%s::",
1209           nbits_from_pk (pk),
1210           pk->pubkey_algo,
1211           (ulong) keyid[0], (ulong) keyid[1],
1212           colon_datestr_from_pk (pk), colon_strtime (pk->expiredate));
1213
1214   if (!opt.fast_list_mode && !opt.no_expensive_trust_checks)
1215     es_putc (get_ownertrust_info (pk), es_stdout);
1216   es_putc (':', es_stdout);
1217
1218   es_putc (':', es_stdout);
1219   es_putc (':', es_stdout);
1220   print_capabilities (pk, keyblock);
1221   es_putc (':', es_stdout);             /* End of field 13. */
1222   es_putc (':', es_stdout);             /* End of field 14. */
1223   if (secret || has_secret)
1224     {
1225       if (stubkey)
1226         es_putc ('#', es_stdout);
1227       else if (serialno)
1228         es_fputs (serialno, es_stdout);
1229       else if (has_secret)
1230         es_putc ('+', es_stdout);
1231     }
1232   es_putc (':', es_stdout);             /* End of field 15. */
1233   es_putc (':', es_stdout);             /* End of field 16. */
1234   if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA
1235       || pk->pubkey_algo == PUBKEY_ALGO_EDDSA
1236       || pk->pubkey_algo == PUBKEY_ALGO_ECDH)
1237     {
1238       char *curve = openpgp_oid_to_str (pk->pkey[0]);
1239       const char *name = openpgp_oid_to_curve (curve);
1240       if (!*name || *name == '?')
1241         name = curve;
1242       es_fputs (name, es_stdout);
1243       xfree (curve);
1244     }
1245   es_putc (':', es_stdout);             /* End of field 17. */
1246   es_putc ('\n', es_stdout);
1247
1248   print_revokers (es_stdout, pk);
1249   if (fpr)
1250     print_fingerprint (NULL, pk, 0);
1251   if (opt.with_key_data || opt.with_keygrip)
1252     {
1253       if (hexgrip)
1254         es_fprintf (es_stdout, "grp:::::::::%s:\n", hexgrip);
1255       if (opt.with_key_data)
1256         print_key_data (pk);
1257     }
1258
1259   for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0));)
1260     {
1261       if (node->pkt->pkttype == PKT_USER_ID && !opt.fast_list_mode)
1262         {
1263           char *str;
1264           PKT_user_id *uid = node->pkt->pkt.user_id;
1265
1266           if (attrib_fp && node->pkt->pkt.user_id->attrib_data != NULL)
1267             dump_attribs (node->pkt->pkt.user_id, pk);
1268           /*
1269            * Fixme: We need a valid flag here too
1270            */
1271           str = uid->attrib_data ? "uat" : "uid";
1272           if (uid->is_revoked)
1273             es_fprintf (es_stdout, "%s:r::::", str);
1274           else if (uid->is_expired)
1275             es_fprintf (es_stdout, "%s:e::::", str);
1276           else if (opt.no_expensive_trust_checks)
1277             es_fprintf (es_stdout, "%s:::::", str);
1278           else
1279             {
1280               int uid_validity;
1281
1282               if (pk && !ulti_hack)
1283                 uid_validity = get_validity_info (pk, uid);
1284               else
1285                 uid_validity = 'u';
1286               es_fprintf (es_stdout, "%s:%c::::", str, uid_validity);
1287             }
1288
1289           es_fprintf (es_stdout, "%s:", colon_strtime (uid->created));
1290           es_fprintf (es_stdout, "%s:", colon_strtime (uid->expiredate));
1291
1292           namehash_from_uid (uid);
1293
1294           for (i = 0; i < 20; i++)
1295             es_fprintf (es_stdout, "%02X", uid->namehash[i]);
1296
1297           es_fprintf (es_stdout, "::");
1298
1299           if (uid->attrib_data)
1300             es_fprintf (es_stdout, "%u %lu", uid->numattribs, uid->attrib_len);
1301           else
1302             es_write_sanitized (es_stdout, uid->name, uid->len, ":", NULL);
1303           es_putc (':', es_stdout);
1304           es_putc ('\n', es_stdout);
1305         }
1306       else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
1307         {
1308           u32 keyid2[2];
1309           PKT_public_key *pk2;
1310
1311           pk2 = node->pkt->pkt.public_key;
1312           xfree (hexgrip); hexgrip = NULL;
1313           xfree (serialno); serialno = NULL;
1314           if (secret || has_secret || opt.with_keygrip || opt.with_key_data)
1315             {
1316               rc = hexkeygrip_from_pk (pk2, &hexgrip);
1317               if (rc)
1318                 log_error ("error computing a keygrip: %s\n",
1319                            gpg_strerror (rc));
1320             }
1321           stubkey = 0;
1322           if ((secret||has_secret)
1323               && agent_get_keyinfo (NULL, hexgrip, &serialno))
1324             stubkey = 1;  /* Key not found.  */
1325
1326           keyid_from_pk (pk2, keyid2);
1327           es_fputs (secret? "ssb:":"sub:", es_stdout);
1328           if (!pk2->flags.valid)
1329             es_putc ('i', es_stdout);
1330           else if (pk2->flags.revoked)
1331             es_putc ('r', es_stdout);
1332           else if (pk2->has_expired)
1333             es_putc ('e', es_stdout);
1334           else if (opt.fast_list_mode || opt.no_expensive_trust_checks)
1335             ;
1336           else
1337             {
1338               /* TRUSTLETTER should always be defined here. */
1339               if (trustletter)
1340                 es_fprintf (es_stdout, "%c", trustletter);
1341             }
1342           es_fprintf (es_stdout, ":%u:%d:%08lX%08lX:%s:%s:::::",
1343                   nbits_from_pk (pk2),
1344                   pk2->pubkey_algo,
1345                   (ulong) keyid2[0], (ulong) keyid2[1],
1346                   colon_datestr_from_pk (pk2), colon_strtime (pk2->expiredate)
1347                   /* fixme: add LID and ownertrust here */
1348             );
1349           print_capabilities (pk2, NULL);
1350           es_putc (':', es_stdout);     /* End of field 13. */
1351           es_putc (':', es_stdout);     /* End of field 14. */
1352           if (secret || has_secret)
1353             {
1354               if (stubkey)
1355                 es_putc ('#', es_stdout);
1356               else if (serialno)
1357                 es_fputs (serialno, es_stdout);
1358               else if (has_secret)
1359                 es_putc ('+', es_stdout);
1360             }
1361           es_putc (':', es_stdout);     /* End of field 15. */
1362           es_putc (':', es_stdout);     /* End of field 16. */
1363           if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA
1364               || pk->pubkey_algo == PUBKEY_ALGO_EDDSA
1365               || pk->pubkey_algo == PUBKEY_ALGO_ECDH)
1366             {
1367               char *curve = openpgp_oid_to_str (pk->pkey[0]);
1368               const char *name = openpgp_oid_to_curve (curve);
1369               if (!*name || *name == '?')
1370                 name = curve;
1371               es_fputs (name, es_stdout);
1372               xfree (curve);
1373             }
1374           es_putc (':', es_stdout);     /* End of field 17. */
1375           es_putc ('\n', es_stdout);
1376           if (fpr > 1)
1377             print_fingerprint (NULL, pk2, 0);
1378           if (opt.with_key_data || opt.with_keygrip)
1379             {
1380               if (hexgrip)
1381                 es_fprintf (es_stdout, "grp:::::::::%s:\n", hexgrip);
1382               if (opt.with_key_data)
1383                 print_key_data (pk2);
1384             }
1385         }
1386       else if (opt.list_sigs && node->pkt->pkttype == PKT_SIGNATURE)
1387         {
1388           PKT_signature *sig = node->pkt->pkt.signature;
1389           int sigrc, fprokay = 0;
1390           char *sigstr;
1391           size_t fplen;
1392           byte fparray[MAX_FINGERPRINT_LEN];
1393
1394           if (sig->sig_class == 0x20 || sig->sig_class == 0x28
1395               || sig->sig_class == 0x30)
1396             sigstr = "rev";
1397           else if ((sig->sig_class & ~3) == 0x10)
1398             sigstr = "sig";
1399           else if (sig->sig_class == 0x18)
1400             sigstr = "sig";
1401           else if (sig->sig_class == 0x1F)
1402             sigstr = "sig";
1403           else
1404             {
1405               es_fprintf (es_stdout, "sig::::::::::%02x%c:\n",
1406                       sig->sig_class, sig->flags.exportable ? 'x' : 'l');
1407               continue;
1408             }
1409
1410           if (opt.check_sigs)
1411             {
1412               PKT_public_key *signer_pk = NULL;
1413
1414               fflush (stdout);
1415               if (opt.no_sig_cache)
1416                 signer_pk = xmalloc_clear (sizeof (PKT_public_key));
1417
1418               rc = check_key_signature2 (keyblock, node, NULL, signer_pk,
1419                                          NULL, NULL, NULL);
1420               switch (gpg_err_code (rc))
1421                 {
1422                 case 0:
1423                   sigrc = '!';
1424                   break;
1425                 case GPG_ERR_BAD_SIGNATURE:
1426                   sigrc = '-';
1427                   break;
1428                 case GPG_ERR_NO_PUBKEY:
1429                 case GPG_ERR_UNUSABLE_PUBKEY:
1430                   sigrc = '?';
1431                   break;
1432                 default:
1433                   sigrc = '%';
1434                   break;
1435                 }
1436
1437               if (opt.no_sig_cache)
1438                 {
1439                   if (!rc)
1440                     {
1441                       fingerprint_from_pk (signer_pk, fparray, &fplen);
1442                       fprokay = 1;
1443                     }
1444                   free_public_key (signer_pk);
1445                 }
1446             }
1447           else
1448             {
1449               rc = 0;
1450               sigrc = ' ';
1451             }
1452           es_fputs (sigstr, es_stdout);
1453           es_putc (':', es_stdout);
1454           if (sigrc != ' ')
1455             es_putc (sigrc, es_stdout);
1456           es_fprintf (es_stdout, "::%d:%08lX%08lX:%s:%s:", sig->pubkey_algo,
1457                   (ulong) sig->keyid[0], (ulong) sig->keyid[1],
1458                   colon_datestr_from_sig (sig),
1459                   colon_expirestr_from_sig (sig));
1460
1461           if (sig->trust_depth || sig->trust_value)
1462             es_fprintf (es_stdout, "%d %d", sig->trust_depth, sig->trust_value);
1463           es_fprintf (es_stdout, ":");
1464
1465           if (sig->trust_regexp)
1466             es_write_sanitized (es_stdout, sig->trust_regexp,
1467                                 strlen (sig->trust_regexp), ":", NULL);
1468           es_fprintf (es_stdout, ":");
1469
1470           if (sigrc == '%')
1471             es_fprintf (es_stdout, "[%s] ", g10_errstr (rc));
1472           else if (sigrc == '?')
1473             ;
1474           else if (!opt.fast_list_mode)
1475             {
1476               size_t n;
1477               p = get_user_id (sig->keyid, &n);
1478               es_write_sanitized (es_stdout, p, n, ":", NULL);
1479               xfree (p);
1480             }
1481           es_fprintf (es_stdout, ":%02x%c::", sig->sig_class,
1482                   sig->flags.exportable ? 'x' : 'l');
1483
1484           if (opt.no_sig_cache && opt.check_sigs && fprokay)
1485             {
1486               for (i = 0; i < fplen; i++)
1487                 es_fprintf (es_stdout, "%02X", fparray[i]);
1488             }
1489
1490           es_fprintf (es_stdout, ":::%d:\n", sig->digest_algo);
1491
1492           if (opt.show_subpackets)
1493             print_subpackets_colon (sig);
1494
1495           /* fixme: check or list other sigs here */
1496         }
1497     }
1498
1499   xfree (hexgrip);
1500   xfree (serialno);
1501 }
1502
1503 /*
1504  * Reorder the keyblock so that the primary user ID (and not attribute
1505  * packet) comes first.  Fixme: Replace this by a generic sort
1506  * function.  */
1507 static void
1508 do_reorder_keyblock (KBNODE keyblock, int attr)
1509 {
1510   KBNODE primary = NULL, primary0 = NULL, primary2 = NULL;
1511   KBNODE last, node;
1512
1513   for (node = keyblock; node; primary0 = node, node = node->next)
1514     {
1515       if (node->pkt->pkttype == PKT_USER_ID &&
1516           ((attr && node->pkt->pkt.user_id->attrib_data) ||
1517            (!attr && !node->pkt->pkt.user_id->attrib_data)) &&
1518           node->pkt->pkt.user_id->is_primary)
1519         {
1520           primary = primary2 = node;
1521           for (node = node->next; node; primary2 = node, node = node->next)
1522             {
1523               if (node->pkt->pkttype == PKT_USER_ID
1524                   || node->pkt->pkttype == PKT_PUBLIC_SUBKEY
1525                   || node->pkt->pkttype == PKT_SECRET_SUBKEY)
1526                 {
1527                   break;
1528                 }
1529             }
1530           break;
1531         }
1532     }
1533   if (!primary)
1534     return; /* No primary key flag found (should not happen).  */
1535
1536   for (last = NULL, node = keyblock; node; last = node, node = node->next)
1537     {
1538       if (node->pkt->pkttype == PKT_USER_ID)
1539         break;
1540     }
1541   assert (node);
1542   assert (last);         /* The user ID is never the first packet.  */
1543   assert (primary0);     /* Ditto (this is the node before primary).  */
1544   if (node == primary)
1545     return; /* Already the first one.  */
1546
1547   last->next = primary;
1548   primary0->next = primary2->next;
1549   primary2->next = node;
1550 }
1551
1552 void
1553 reorder_keyblock (KBNODE keyblock)
1554 {
1555   do_reorder_keyblock (keyblock, 1);
1556   do_reorder_keyblock (keyblock, 0);
1557 }
1558
1559 void
1560 list_keyblock (KBNODE keyblock, int secret, int has_secret, int fpr,
1561                void *opaque)
1562 {
1563   reorder_keyblock (keyblock);
1564   if (opt.with_colons)
1565     list_keyblock_colon (keyblock, secret, has_secret, fpr);
1566   else
1567     list_keyblock_print (keyblock, secret, fpr, opaque);
1568 }
1569
1570 /*
1571  * Function to print the finperprint.
1572  * mode 0: as used in key listings, opt.with_colons is honored
1573  *      1: print using log_info ()
1574  *      2: direct use of tty
1575  *      3: direct use of tty but only primary key.
1576  *
1577  * Modes 1 and 2 will try and print both subkey and primary key
1578  * fingerprints.  A MODE with bit 7 set is used internally.  If
1579  * OVERRIDE_FP is not NULL that stream will be used in  0 instead
1580  * of es_stdout or instead of the TTY in modes 2 and 3.
1581  */
1582 void
1583 print_fingerprint (estream_t override_fp, PKT_public_key *pk, int mode)
1584 {
1585   byte array[MAX_FINGERPRINT_LEN], *p;
1586   size_t i, n;
1587   estream_t fp;
1588   const char *text;
1589   int primary = 0;
1590
1591   if (pk->main_keyid[0] == pk->keyid[0]
1592       && pk->main_keyid[1] == pk->keyid[1])
1593     primary = 1;
1594
1595   /* Just to be safe */
1596   if ((mode & 0x80) && !primary)
1597     {
1598       log_error ("primary key is not really primary!\n");
1599       return;
1600     }
1601
1602   mode &= ~0x80;
1603
1604   if (!primary && (mode == 1 || mode == 2))
1605     {
1606       PKT_public_key *primary_pk = xmalloc_clear (sizeof (*primary_pk));
1607       get_pubkey (primary_pk, pk->main_keyid);
1608       print_fingerprint (override_fp, primary_pk, (mode | 0x80));
1609       free_public_key (primary_pk);
1610     }
1611
1612   if (mode == 1)
1613     {
1614       fp = log_get_stream ();
1615       if (primary)
1616         text = _("Primary key fingerprint:");
1617       else
1618         text = _("     Subkey fingerprint:");
1619     }
1620   else if (mode == 2)
1621     {
1622       fp = override_fp; /* Use tty or given stream.  */
1623       if (primary)
1624         /* TRANSLATORS: this should fit into 24 bytes to that the
1625          * fingerprint data is properly aligned with the user ID */
1626         text = _(" Primary key fingerprint:");
1627       else
1628         text = _("      Subkey fingerprint:");
1629     }
1630   else if (mode == 3)
1631     {
1632       fp = override_fp; /* Use tty or given stream.  */
1633       text = _("      Key fingerprint =");
1634     }
1635   else
1636     {
1637       fp = override_fp? override_fp : es_stdout;
1638       text = _("      Key fingerprint =");
1639     }
1640
1641   fingerprint_from_pk (pk, array, &n);
1642   p = array;
1643   if (opt.with_colons && !mode)
1644     {
1645       es_fprintf (fp, "fpr:::::::::");
1646       for (i = 0; i < n; i++, p++)
1647         es_fprintf (fp, "%02X", *p);
1648       es_putc (':', fp);
1649     }
1650   else
1651     {
1652       tty_fprintf (fp, "%s", text);
1653       if (n == 20)
1654         {
1655           for (i = 0; i < n; i++, i++, p += 2)
1656             tty_fprintf (fp, "%s %02X%02X", i==10? " ":"", *p, p[1]);
1657         }
1658       else
1659         {
1660           for (i = 0; i < n; i++, p++)
1661             tty_fprintf (fp, "%s %02X", (i && !(i % 8))? " ":"", *p);
1662         }
1663     }
1664   tty_fprintf (fp, "\n");
1665 }
1666
1667 /* Print the serial number of an OpenPGP card if available.  */
1668 static void
1669 print_card_serialno (const char *serialno)
1670 {
1671   if (!serialno)
1672     return;
1673   if (opt.with_colons)
1674     return; /* Handled elsewhere. */
1675
1676   es_fputs (_("      Card serial no. ="), es_stdout);
1677   es_putc (' ', es_stdout);
1678   if (strlen (serialno) == 32 && !strncmp (serialno, "D27600012401", 12))
1679     {
1680       /* This is an OpenPGP card.  Print the relevant part.  */
1681       /* Example: D2760001240101010001000003470000 */
1682       /*                          xxxxyyyyyyyy     */
1683       es_fprintf (es_stdout, "%.*s %.*s", 4, serialno+16, 8, serialno+20);
1684     }
1685  else
1686    es_fputs (serialno, es_stdout);
1687   es_putc ('\n', es_stdout);
1688 }
1689
1690
1691
1692 void
1693 set_attrib_fd (int fd)
1694 {
1695   static int last_fd = -1;
1696
1697   if (fd != -1 && last_fd == fd)
1698     return;
1699
1700   /* Fixme: Do we need to check for the log stream here?  */
1701   if (attrib_fp && attrib_fp != log_get_stream ())
1702     es_fclose (attrib_fp);
1703   attrib_fp = NULL;
1704   if (fd == -1)
1705     return;
1706
1707 #ifdef HAVE_DOSISH_SYSTEM
1708   setmode (fd, O_BINARY);
1709 #endif
1710   if (fd == 1)
1711     attrib_fp = es_stdout;
1712   else if (fd == 2)
1713     attrib_fp = es_stderr;
1714   else
1715     attrib_fp = es_fdopen (fd, "wb");
1716   if (!attrib_fp)
1717     {
1718       log_fatal ("can't open fd %d for attribute output: %s\n",
1719                  fd, strerror (errno));
1720     }
1721
1722   last_fd = fd;
1723 }