7d9fe230c862afff2c5a288c560d1f6489459176
[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 (pk->flags.revoked)
838     {
839       es_fprintf (es_stdout, " [");
840       es_fprintf (es_stdout, _("revoked: %s"), revokestr_from_pk (pk));
841       es_fprintf (es_stdout, "]");
842     }
843   else if (pk->has_expired)
844     {
845       es_fprintf (es_stdout, " [");
846       es_fprintf (es_stdout, _("expired: %s"), expirestr_from_pk (pk));
847       es_fprintf (es_stdout, "]");
848     }
849   else if (pk->expiredate)
850     {
851       es_fprintf (es_stdout, " [");
852       es_fprintf (es_stdout, _("expires: %s"), expirestr_from_pk (pk));
853       es_fprintf (es_stdout, "]");
854     }
855
856 #if 0
857   /* I need to think about this some more.  It's easy enough to
858      include, but it looks sort of confusing in the listing... */
859   if (opt.list_options & LIST_SHOW_VALIDITY)
860     {
861       int validity = get_validity (pk, NULL);
862       es_fprintf (es_stdout, " [%s]", trust_value_to_string (validity));
863     }
864 #endif
865
866   if (pk->pubkey_algo >= 100)
867     es_fprintf (es_stdout, " [experimental algorithm %d]", pk->pubkey_algo);
868
869   es_fprintf (es_stdout, "\n");
870
871   if (fpr)
872     print_fingerprint (NULL, pk, 0);
873
874   if (opt.with_keygrip && hexgrip)
875     es_fprintf (es_stdout, "      Keygrip = %s\n", hexgrip);
876
877   if (serialno)
878     print_card_serialno (serialno);
879
880   if (opt.with_key_data)
881     print_key_data (pk);
882
883   for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0));)
884     {
885       if (node->pkt->pkttype == PKT_USER_ID && !opt.fast_list_mode)
886         {
887           PKT_user_id *uid = node->pkt->pkt.user_id;
888
889           if (pk && (uid->is_expired || uid->is_revoked)
890               && !(opt.list_options & LIST_SHOW_UNUSABLE_UIDS))
891             {
892               skip_sigs = 1;
893               continue;
894             }
895           else
896             skip_sigs = 0;
897
898           if (attrib_fp && uid->attrib_data != NULL)
899             dump_attribs (uid, pk);
900
901           if ((uid->is_revoked || uid->is_expired)
902               || ((opt.list_options & LIST_SHOW_UID_VALIDITY) && pk))
903             {
904               const char *validity;
905               int indent;
906
907               validity = uid_trust_string_fixed (pk, uid);
908               indent =
909                 (keystrlen () + 9) -
910                 atoi (uid_trust_string_fixed (NULL, NULL));
911
912               if (indent < 0 || indent > 40)
913                 indent = 0;
914
915               es_fprintf (es_stdout, "uid%*s%s ", indent, "", validity);
916             }
917           else
918             es_fprintf (es_stdout, "uid%*s", (int) keystrlen () + 10, "");
919
920           print_utf8_buffer (es_stdout, uid->name, uid->len);
921           es_putc ('\n', es_stdout);
922
923           if ((opt.list_options & LIST_SHOW_PHOTOS) && uid->attribs != NULL)
924             show_photos (uid->attribs, uid->numattribs, pk, uid);
925         }
926       else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
927         {
928           PKT_public_key *pk2 = node->pkt->pkt.public_key;
929
930           if ((pk2->flags.revoked || pk2->has_expired)
931               && !(opt.list_options & LIST_SHOW_UNUSABLE_SUBKEYS))
932             {
933               skip_sigs = 1;
934               continue;
935             }
936           else
937             skip_sigs = 0;
938
939           xfree (serialno); serialno = NULL;
940           xfree (hexgrip); hexgrip = NULL;
941           if (secret || opt.with_keygrip)
942             {
943               rc = hexkeygrip_from_pk (pk2, &hexgrip);
944               if (rc)
945                 log_error ("error computing a keygrip: %s\n",
946                            gpg_strerror (rc));
947             }
948           if (secret)
949             {
950               if (!agent_get_keyinfo (NULL, hexgrip, &serialno))
951                 s2k_char = serialno? '>':' ';
952               else
953                 s2k_char = '#';  /* Key not found.  */
954             }
955           else
956             s2k_char = ' ';
957
958           es_fprintf (es_stdout, "%s%c  %s/%s %s",
959                   secret? "ssb":"sub",
960                   s2k_char,
961                   pubkey_string (pk2, pkstrbuf, sizeof pkstrbuf),
962                   keystr_from_pk (pk2), datestr_from_pk (pk2));
963
964           if (pk2->pubkey_algo == PUBKEY_ALGO_ECDSA
965               || pk2->pubkey_algo == PUBKEY_ALGO_EDDSA
966               || pk2->pubkey_algo == PUBKEY_ALGO_ECDH)
967             {
968               char *curve = openpgp_oid_to_str (pk2->pkey[0]);
969               const char *name = openpgp_oid_to_curve (curve);
970               if (!*name || *name == '?')
971                 name = curve;
972               es_fprintf (es_stdout, " %s", name);
973               xfree (curve);
974             }
975
976           if (pk2->flags.revoked)
977             {
978               es_fprintf (es_stdout, " [");
979               es_fprintf (es_stdout, _("revoked: %s"), revokestr_from_pk (pk2));
980               es_fprintf (es_stdout, "]");
981             }
982           else if (pk2->has_expired)
983             {
984               es_fprintf (es_stdout, " [");
985               es_fprintf (es_stdout, _("expired: %s"), expirestr_from_pk (pk2));
986               es_fprintf (es_stdout, "]");
987             }
988           else if (pk2->expiredate)
989             {
990               es_fprintf (es_stdout, " [");
991               es_fprintf (es_stdout, _("expires: %s"), expirestr_from_pk (pk2));
992               es_fprintf (es_stdout, "]");
993             }
994           es_putc ('\n', es_stdout);
995           if (fpr > 1)
996             {
997               print_fingerprint (NULL, pk2, 0);
998               if (serialno)
999                 print_card_serialno (serialno);
1000             }
1001           if (opt.with_keygrip && hexgrip)
1002             es_fprintf (es_stdout, "      Keygrip = %s\n", hexgrip);
1003           if (opt.with_key_data)
1004             print_key_data (pk2);
1005         }
1006       else if (opt.list_sigs
1007                && node->pkt->pkttype == PKT_SIGNATURE && !skip_sigs)
1008         {
1009           PKT_signature *sig = node->pkt->pkt.signature;
1010           int sigrc;
1011           char *sigstr;
1012
1013           if (stats)
1014             {
1015               rc = check_key_signature (keyblock, node, NULL);
1016               switch (gpg_err_code (rc))
1017                 {
1018                 case 0:
1019                   sigrc = '!';
1020                   break;
1021                 case GPG_ERR_BAD_SIGNATURE:
1022                   stats->inv_sigs++;
1023                   sigrc = '-';
1024                   break;
1025                 case GPG_ERR_NO_PUBKEY:
1026                 case GPG_ERR_UNUSABLE_PUBKEY:
1027                   stats->no_key++;
1028                   continue;
1029                 default:
1030                   stats->oth_err++;
1031                   sigrc = '%';
1032                   break;
1033                 }
1034
1035               /* TODO: Make sure a cached sig record here still has
1036                  the pk that issued it.  See also
1037                  keyedit.c:print_and_check_one_sig */
1038             }
1039           else
1040             {
1041               rc = 0;
1042               sigrc = ' ';
1043             }
1044
1045           if (sig->sig_class == 0x20 || sig->sig_class == 0x28
1046               || sig->sig_class == 0x30)
1047             sigstr = "rev";
1048           else if ((sig->sig_class & ~3) == 0x10)
1049             sigstr = "sig";
1050           else if (sig->sig_class == 0x18)
1051             sigstr = "sig";
1052           else if (sig->sig_class == 0x1F)
1053             sigstr = "sig";
1054           else
1055             {
1056               es_fprintf (es_stdout, "sig                             "
1057                       "[unexpected signature class 0x%02x]\n",
1058                       sig->sig_class);
1059               continue;
1060             }
1061
1062           es_fputs (sigstr, es_stdout);
1063           es_fprintf (es_stdout, "%c%c %c%c%c%c%c%c %s %s",
1064                   sigrc, (sig->sig_class - 0x10 > 0 &&
1065                           sig->sig_class - 0x10 <
1066                           4) ? '0' + sig->sig_class - 0x10 : ' ',
1067                   sig->flags.exportable ? ' ' : 'L',
1068                   sig->flags.revocable ? ' ' : 'R',
1069                   sig->flags.policy_url ? 'P' : ' ',
1070                   sig->flags.notation ? 'N' : ' ',
1071                   sig->flags.expired ? 'X' : ' ',
1072                   (sig->trust_depth > 9) ? 'T' : (sig->trust_depth >
1073                                                   0) ? '0' +
1074                   sig->trust_depth : ' ', keystr (sig->keyid),
1075                   datestr_from_sig (sig));
1076           if (opt.list_options & LIST_SHOW_SIG_EXPIRE)
1077             es_fprintf (es_stdout, " %s", expirestr_from_sig (sig));
1078           es_fprintf (es_stdout, "  ");
1079           if (sigrc == '%')
1080             es_fprintf (es_stdout, "[%s] ", g10_errstr (rc));
1081           else if (sigrc == '?')
1082             ;
1083           else if (!opt.fast_list_mode)
1084             {
1085               size_t n;
1086               char *p = get_user_id (sig->keyid, &n);
1087               print_utf8_buffer (es_stdout, p, n);
1088               xfree (p);
1089             }
1090           es_putc ('\n', es_stdout);
1091
1092           if (sig->flags.policy_url
1093               && (opt.list_options & LIST_SHOW_POLICY_URLS))
1094             show_policy_url (sig, 3, 0);
1095
1096           if (sig->flags.notation && (opt.list_options & LIST_SHOW_NOTATIONS))
1097             show_notation (sig, 3, 0,
1098                            ((opt.
1099                              list_options & LIST_SHOW_STD_NOTATIONS) ? 1 : 0)
1100                            +
1101                            ((opt.
1102                              list_options & LIST_SHOW_USER_NOTATIONS) ? 2 :
1103                             0));
1104
1105           if (sig->flags.pref_ks
1106               && (opt.list_options & LIST_SHOW_KEYSERVER_URLS))
1107             show_keyserver_url (sig, 3, 0);
1108
1109           /* fixme: check or list other sigs here */
1110         }
1111     }
1112   es_putc ('\n', es_stdout);
1113   xfree (serialno);
1114   xfree (hexgrip);
1115 }
1116
1117 void
1118 print_revokers (estream_t fp, PKT_public_key * pk)
1119 {
1120   /* print the revoker record */
1121   if (!pk->revkey && pk->numrevkeys)
1122     BUG ();
1123   else
1124     {
1125       int i, j;
1126
1127       for (i = 0; i < pk->numrevkeys; i++)
1128         {
1129           byte *p;
1130
1131           es_fprintf (fp, "rvk:::%d::::::", pk->revkey[i].algid);
1132           p = pk->revkey[i].fpr;
1133           for (j = 0; j < 20; j++, p++)
1134             es_fprintf (fp, "%02X", *p);
1135           es_fprintf (fp, ":%02x%s:\n",
1136                       pk->revkey[i].class,
1137                       (pk->revkey[i].class & 0x40) ? "s" : "");
1138         }
1139     }
1140 }
1141
1142
1143 /* List a key in colon mode.  If SECRET is true this is a secret key
1144    record (i.e. requested via --list-secret-key).  If HAS_SECRET a
1145    secret key is available even if SECRET is not set.  */
1146 static void
1147 list_keyblock_colon (KBNODE keyblock, int secret, int has_secret, int fpr)
1148 {
1149   int rc;
1150   KBNODE kbctx;
1151   KBNODE node;
1152   PKT_public_key *pk;
1153   u32 keyid[2];
1154   int trustletter = 0;
1155   int ulti_hack = 0;
1156   int i;
1157   char *p;
1158   char *hexgrip = NULL;
1159   char *serialno = NULL;
1160   int stubkey;
1161
1162   /* Get the keyid from the keyblock.  */
1163   node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
1164   if (!node)
1165     {
1166       log_error ("Oops; key lost!\n");
1167       dump_kbnode (keyblock);
1168       return;
1169     }
1170
1171   pk = node->pkt->pkt.public_key;
1172   if (secret || has_secret || opt.with_keygrip || opt.with_key_data)
1173     {
1174       rc = hexkeygrip_from_pk (pk, &hexgrip);
1175       if (rc)
1176         log_error ("error computing a keygrip: %s\n", gpg_strerror (rc));
1177     }
1178   stubkey = 0;
1179   if ((secret||has_secret) && agent_get_keyinfo (NULL, hexgrip, &serialno))
1180     stubkey = 1;  /* Key not found.  */
1181
1182   keyid_from_pk (pk, keyid);
1183   es_fputs (secret? "sec:":"pub:", es_stdout);
1184   if (!pk->flags.valid)
1185     es_putc ('i', es_stdout);
1186   else if (pk->flags.revoked)
1187     es_putc ('r', es_stdout);
1188   else if (pk->has_expired)
1189     es_putc ('e', es_stdout);
1190   else if (opt.fast_list_mode || opt.no_expensive_trust_checks)
1191     ;
1192   else
1193     {
1194       trustletter = get_validity_info (pk, NULL);
1195       if (trustletter == 'u')
1196         ulti_hack = 1;
1197       es_putc (trustletter, es_stdout);
1198     }
1199
1200   es_fprintf (es_stdout, ":%u:%d:%08lX%08lX:%s:%s::",
1201           nbits_from_pk (pk),
1202           pk->pubkey_algo,
1203           (ulong) keyid[0], (ulong) keyid[1],
1204           colon_datestr_from_pk (pk), colon_strtime (pk->expiredate));
1205
1206   if (!opt.fast_list_mode && !opt.no_expensive_trust_checks)
1207     es_putc (get_ownertrust_info (pk), es_stdout);
1208   es_putc (':', es_stdout);
1209
1210   es_putc (':', es_stdout);
1211   es_putc (':', es_stdout);
1212   print_capabilities (pk, keyblock);
1213   es_putc (':', es_stdout);             /* End of field 13. */
1214   es_putc (':', es_stdout);             /* End of field 14. */
1215   if (secret || has_secret)
1216     {
1217       if (stubkey)
1218         es_putc ('#', es_stdout);
1219       else if (serialno)
1220         es_fputs (serialno, es_stdout);
1221       else if (has_secret)
1222         es_putc ('+', es_stdout);
1223     }
1224   es_putc (':', es_stdout);             /* End of field 15. */
1225   es_putc (':', es_stdout);             /* End of field 16. */
1226   if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA
1227       || pk->pubkey_algo == PUBKEY_ALGO_EDDSA
1228       || pk->pubkey_algo == PUBKEY_ALGO_ECDH)
1229     {
1230       char *curve = openpgp_oid_to_str (pk->pkey[0]);
1231       const char *name = openpgp_oid_to_curve (curve);
1232       if (!*name || *name == '?')
1233         name = curve;
1234       es_fputs (name, es_stdout);
1235       xfree (curve);
1236     }
1237   es_putc (':', es_stdout);             /* End of field 17. */
1238   es_putc ('\n', es_stdout);
1239
1240   print_revokers (es_stdout, pk);
1241   if (fpr)
1242     print_fingerprint (NULL, pk, 0);
1243   if (opt.with_key_data || opt.with_keygrip)
1244     {
1245       if (hexgrip)
1246         es_fprintf (es_stdout, "grp:::::::::%s:\n", hexgrip);
1247       if (opt.with_key_data)
1248         print_key_data (pk);
1249     }
1250
1251   for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0));)
1252     {
1253       if (node->pkt->pkttype == PKT_USER_ID && !opt.fast_list_mode)
1254         {
1255           char *str;
1256           PKT_user_id *uid = node->pkt->pkt.user_id;
1257
1258           if (attrib_fp && node->pkt->pkt.user_id->attrib_data != NULL)
1259             dump_attribs (node->pkt->pkt.user_id, pk);
1260           /*
1261            * Fixme: We need a valid flag here too
1262            */
1263           str = uid->attrib_data ? "uat" : "uid";
1264           if (uid->is_revoked)
1265             es_fprintf (es_stdout, "%s:r::::", str);
1266           else if (uid->is_expired)
1267             es_fprintf (es_stdout, "%s:e::::", str);
1268           else if (opt.no_expensive_trust_checks)
1269             es_fprintf (es_stdout, "%s:::::", str);
1270           else
1271             {
1272               int uid_validity;
1273
1274               if (pk && !ulti_hack)
1275                 uid_validity = get_validity_info (pk, uid);
1276               else
1277                 uid_validity = 'u';
1278               es_fprintf (es_stdout, "%s:%c::::", str, uid_validity);
1279             }
1280
1281           es_fprintf (es_stdout, "%s:", colon_strtime (uid->created));
1282           es_fprintf (es_stdout, "%s:", colon_strtime (uid->expiredate));
1283
1284           namehash_from_uid (uid);
1285
1286           for (i = 0; i < 20; i++)
1287             es_fprintf (es_stdout, "%02X", uid->namehash[i]);
1288
1289           es_fprintf (es_stdout, "::");
1290
1291           if (uid->attrib_data)
1292             es_fprintf (es_stdout, "%u %lu", uid->numattribs, uid->attrib_len);
1293           else
1294             es_write_sanitized (es_stdout, uid->name, uid->len, ":", NULL);
1295           es_putc (':', es_stdout);
1296           es_putc ('\n', es_stdout);
1297         }
1298       else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
1299         {
1300           u32 keyid2[2];
1301           PKT_public_key *pk2;
1302
1303           pk2 = node->pkt->pkt.public_key;
1304           xfree (hexgrip); hexgrip = NULL;
1305           xfree (serialno); serialno = NULL;
1306           if (secret || has_secret || opt.with_keygrip || opt.with_key_data)
1307             {
1308               rc = hexkeygrip_from_pk (pk2, &hexgrip);
1309               if (rc)
1310                 log_error ("error computing a keygrip: %s\n",
1311                            gpg_strerror (rc));
1312             }
1313           stubkey = 0;
1314           if ((secret||has_secret)
1315               && agent_get_keyinfo (NULL, hexgrip, &serialno))
1316             stubkey = 1;  /* Key not found.  */
1317
1318           keyid_from_pk (pk2, keyid2);
1319           es_fputs (secret? "ssb:":"sub:", es_stdout);
1320           if (!pk2->flags.valid)
1321             es_putc ('i', es_stdout);
1322           else if (pk2->flags.revoked)
1323             es_putc ('r', es_stdout);
1324           else if (pk2->has_expired)
1325             es_putc ('e', es_stdout);
1326           else if (opt.fast_list_mode || opt.no_expensive_trust_checks)
1327             ;
1328           else
1329             {
1330               /* TRUSTLETTER should always be defined here. */
1331               if (trustletter)
1332                 es_fprintf (es_stdout, "%c", trustletter);
1333             }
1334           es_fprintf (es_stdout, ":%u:%d:%08lX%08lX:%s:%s:::::",
1335                   nbits_from_pk (pk2),
1336                   pk2->pubkey_algo,
1337                   (ulong) keyid2[0], (ulong) keyid2[1],
1338                   colon_datestr_from_pk (pk2), colon_strtime (pk2->expiredate)
1339                   /* fixme: add LID and ownertrust here */
1340             );
1341           print_capabilities (pk2, NULL);
1342           es_putc (':', es_stdout);     /* End of field 13. */
1343           es_putc (':', es_stdout);     /* End of field 14. */
1344           if (secret || has_secret)
1345             {
1346               if (stubkey)
1347                 es_putc ('#', es_stdout);
1348               else if (serialno)
1349                 es_fputs (serialno, es_stdout);
1350               else if (has_secret)
1351                 es_putc ('+', es_stdout);
1352             }
1353           es_putc (':', es_stdout);     /* End of field 15. */
1354           es_putc (':', es_stdout);     /* End of field 16. */
1355           if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA
1356               || pk->pubkey_algo == PUBKEY_ALGO_EDDSA
1357               || pk->pubkey_algo == PUBKEY_ALGO_ECDH)
1358             {
1359               char *curve = openpgp_oid_to_str (pk->pkey[0]);
1360               const char *name = openpgp_oid_to_curve (curve);
1361               if (!*name || *name == '?')
1362                 name = curve;
1363               es_fputs (name, es_stdout);
1364               xfree (curve);
1365             }
1366           es_putc (':', es_stdout);     /* End of field 17. */
1367           es_putc ('\n', es_stdout);
1368           if (fpr > 1)
1369             print_fingerprint (NULL, pk2, 0);
1370           if (opt.with_key_data || opt.with_keygrip)
1371             {
1372               if (hexgrip)
1373                 es_fprintf (es_stdout, "grp:::::::::%s:\n", hexgrip);
1374               if (opt.with_key_data)
1375                 print_key_data (pk2);
1376             }
1377         }
1378       else if (opt.list_sigs && node->pkt->pkttype == PKT_SIGNATURE)
1379         {
1380           PKT_signature *sig = node->pkt->pkt.signature;
1381           int sigrc, fprokay = 0;
1382           char *sigstr;
1383           size_t fplen;
1384           byte fparray[MAX_FINGERPRINT_LEN];
1385
1386           if (sig->sig_class == 0x20 || sig->sig_class == 0x28
1387               || sig->sig_class == 0x30)
1388             sigstr = "rev";
1389           else if ((sig->sig_class & ~3) == 0x10)
1390             sigstr = "sig";
1391           else if (sig->sig_class == 0x18)
1392             sigstr = "sig";
1393           else if (sig->sig_class == 0x1F)
1394             sigstr = "sig";
1395           else
1396             {
1397               es_fprintf (es_stdout, "sig::::::::::%02x%c:\n",
1398                       sig->sig_class, sig->flags.exportable ? 'x' : 'l');
1399               continue;
1400             }
1401
1402           if (opt.check_sigs)
1403             {
1404               PKT_public_key *signer_pk = NULL;
1405
1406               fflush (stdout);
1407               if (opt.no_sig_cache)
1408                 signer_pk = xmalloc_clear (sizeof (PKT_public_key));
1409
1410               rc = check_key_signature2 (keyblock, node, NULL, signer_pk,
1411                                          NULL, NULL, NULL);
1412               switch (gpg_err_code (rc))
1413                 {
1414                 case 0:
1415                   sigrc = '!';
1416                   break;
1417                 case GPG_ERR_BAD_SIGNATURE:
1418                   sigrc = '-';
1419                   break;
1420                 case GPG_ERR_NO_PUBKEY:
1421                 case GPG_ERR_UNUSABLE_PUBKEY:
1422                   sigrc = '?';
1423                   break;
1424                 default:
1425                   sigrc = '%';
1426                   break;
1427                 }
1428
1429               if (opt.no_sig_cache)
1430                 {
1431                   if (!rc)
1432                     {
1433                       fingerprint_from_pk (signer_pk, fparray, &fplen);
1434                       fprokay = 1;
1435                     }
1436                   free_public_key (signer_pk);
1437                 }
1438             }
1439           else
1440             {
1441               rc = 0;
1442               sigrc = ' ';
1443             }
1444           es_fputs (sigstr, es_stdout);
1445           es_putc (':', es_stdout);
1446           if (sigrc != ' ')
1447             es_putc (sigrc, es_stdout);
1448           es_fprintf (es_stdout, "::%d:%08lX%08lX:%s:%s:", sig->pubkey_algo,
1449                   (ulong) sig->keyid[0], (ulong) sig->keyid[1],
1450                   colon_datestr_from_sig (sig),
1451                   colon_expirestr_from_sig (sig));
1452
1453           if (sig->trust_depth || sig->trust_value)
1454             es_fprintf (es_stdout, "%d %d", sig->trust_depth, sig->trust_value);
1455           es_fprintf (es_stdout, ":");
1456
1457           if (sig->trust_regexp)
1458             es_write_sanitized (es_stdout, sig->trust_regexp,
1459                                 strlen (sig->trust_regexp), ":", NULL);
1460           es_fprintf (es_stdout, ":");
1461
1462           if (sigrc == '%')
1463             es_fprintf (es_stdout, "[%s] ", g10_errstr (rc));
1464           else if (sigrc == '?')
1465             ;
1466           else if (!opt.fast_list_mode)
1467             {
1468               size_t n;
1469               p = get_user_id (sig->keyid, &n);
1470               es_write_sanitized (es_stdout, p, n, ":", NULL);
1471               xfree (p);
1472             }
1473           es_fprintf (es_stdout, ":%02x%c::", sig->sig_class,
1474                   sig->flags.exportable ? 'x' : 'l');
1475
1476           if (opt.no_sig_cache && opt.check_sigs && fprokay)
1477             {
1478               for (i = 0; i < fplen; i++)
1479                 es_fprintf (es_stdout, "%02X", fparray[i]);
1480             }
1481
1482           es_fprintf (es_stdout, ":::%d:\n", sig->digest_algo);
1483
1484           if (opt.show_subpackets)
1485             print_subpackets_colon (sig);
1486
1487           /* fixme: check or list other sigs here */
1488         }
1489     }
1490
1491   xfree (hexgrip);
1492   xfree (serialno);
1493 }
1494
1495 /*
1496  * Reorder the keyblock so that the primary user ID (and not attribute
1497  * packet) comes first.  Fixme: Replace this by a generic sort
1498  * function.  */
1499 static void
1500 do_reorder_keyblock (KBNODE keyblock, int attr)
1501 {
1502   KBNODE primary = NULL, primary0 = NULL, primary2 = NULL;
1503   KBNODE last, node;
1504
1505   for (node = keyblock; node; primary0 = node, node = node->next)
1506     {
1507       if (node->pkt->pkttype == PKT_USER_ID &&
1508           ((attr && node->pkt->pkt.user_id->attrib_data) ||
1509            (!attr && !node->pkt->pkt.user_id->attrib_data)) &&
1510           node->pkt->pkt.user_id->is_primary)
1511         {
1512           primary = primary2 = node;
1513           for (node = node->next; node; primary2 = node, node = node->next)
1514             {
1515               if (node->pkt->pkttype == PKT_USER_ID
1516                   || node->pkt->pkttype == PKT_PUBLIC_SUBKEY
1517                   || node->pkt->pkttype == PKT_SECRET_SUBKEY)
1518                 {
1519                   break;
1520                 }
1521             }
1522           break;
1523         }
1524     }
1525   if (!primary)
1526     return; /* No primary key flag found (should not happen).  */
1527
1528   for (last = NULL, node = keyblock; node; last = node, node = node->next)
1529     {
1530       if (node->pkt->pkttype == PKT_USER_ID)
1531         break;
1532     }
1533   assert (node);
1534   assert (last);         /* The user ID is never the first packet.  */
1535   assert (primary0);     /* Ditto (this is the node before primary).  */
1536   if (node == primary)
1537     return; /* Already the first one.  */
1538
1539   last->next = primary;
1540   primary0->next = primary2->next;
1541   primary2->next = node;
1542 }
1543
1544 void
1545 reorder_keyblock (KBNODE keyblock)
1546 {
1547   do_reorder_keyblock (keyblock, 1);
1548   do_reorder_keyblock (keyblock, 0);
1549 }
1550
1551 void
1552 list_keyblock (KBNODE keyblock, int secret, int has_secret, int fpr,
1553                void *opaque)
1554 {
1555   reorder_keyblock (keyblock);
1556   if (opt.with_colons)
1557     list_keyblock_colon (keyblock, secret, has_secret, fpr);
1558   else
1559     list_keyblock_print (keyblock, secret, fpr, opaque);
1560 }
1561
1562 /*
1563  * Function to print the finperprint.
1564  * mode 0: as used in key listings, opt.with_colons is honored
1565  *      1: print using log_info ()
1566  *      2: direct use of tty
1567  *      3: direct use of tty but only primary key.
1568  *
1569  * Modes 1 and 2 will try and print both subkey and primary key
1570  * fingerprints.  A MODE with bit 7 set is used internally.  If
1571  * OVERRIDE_FP is not NULL that stream will be used in  0 instead
1572  * of es_stdout or instead of the TTY in modes 2 and 3.
1573  */
1574 void
1575 print_fingerprint (estream_t override_fp, PKT_public_key *pk, int mode)
1576 {
1577   byte array[MAX_FINGERPRINT_LEN], *p;
1578   size_t i, n;
1579   estream_t fp;
1580   const char *text;
1581   int primary = 0;
1582
1583   if (pk->main_keyid[0] == pk->keyid[0]
1584       && pk->main_keyid[1] == pk->keyid[1])
1585     primary = 1;
1586
1587   /* Just to be safe */
1588   if ((mode & 0x80) && !primary)
1589     {
1590       log_error ("primary key is not really primary!\n");
1591       return;
1592     }
1593
1594   mode &= ~0x80;
1595
1596   if (!primary && (mode == 1 || mode == 2))
1597     {
1598       PKT_public_key *primary_pk = xmalloc_clear (sizeof (*primary_pk));
1599       get_pubkey (primary_pk, pk->main_keyid);
1600       print_fingerprint (override_fp, primary_pk, (mode | 0x80));
1601       free_public_key (primary_pk);
1602     }
1603
1604   if (mode == 1)
1605     {
1606       fp = log_get_stream ();
1607       if (primary)
1608         text = _("Primary key fingerprint:");
1609       else
1610         text = _("     Subkey fingerprint:");
1611     }
1612   else if (mode == 2)
1613     {
1614       fp = override_fp; /* Use tty or given stream.  */
1615       if (primary)
1616         /* TRANSLATORS: this should fit into 24 bytes to that the
1617          * fingerprint data is properly aligned with the user ID */
1618         text = _(" Primary key fingerprint:");
1619       else
1620         text = _("      Subkey fingerprint:");
1621     }
1622   else if (mode == 3)
1623     {
1624       fp = override_fp; /* Use tty or given stream.  */
1625       text = _("      Key fingerprint =");
1626     }
1627   else
1628     {
1629       fp = override_fp? override_fp : es_stdout;
1630       text = _("      Key fingerprint =");
1631     }
1632
1633   fingerprint_from_pk (pk, array, &n);
1634   p = array;
1635   if (opt.with_colons && !mode)
1636     {
1637       es_fprintf (fp, "fpr:::::::::");
1638       for (i = 0; i < n; i++, p++)
1639         es_fprintf (fp, "%02X", *p);
1640       es_putc (':', fp);
1641     }
1642   else
1643     {
1644       tty_fprintf (fp, "%s", text);
1645       if (n == 20)
1646         {
1647           for (i = 0; i < n; i++, i++, p += 2)
1648             tty_fprintf (fp, "%s %02X%02X", i==10? " ":"", *p, p[1]);
1649         }
1650       else
1651         {
1652           for (i = 0; i < n; i++, p++)
1653             tty_fprintf (fp, "%s %02X", (i && !(i % 8))? " ":"", *p);
1654         }
1655     }
1656   tty_fprintf (fp, "\n");
1657 }
1658
1659 /* Print the serial number of an OpenPGP card if available.  */
1660 static void
1661 print_card_serialno (const char *serialno)
1662 {
1663   if (!serialno)
1664     return;
1665   if (opt.with_colons)
1666     return; /* Handled elsewhere. */
1667
1668   es_fputs (_("      Card serial no. ="), es_stdout);
1669   es_putc (' ', es_stdout);
1670   if (strlen (serialno) == 32 && !strncmp (serialno, "D27600012401", 12))
1671     {
1672       /* This is an OpenPGP card.  Print the relevant part.  */
1673       /* Example: D2760001240101010001000003470000 */
1674       /*                          xxxxyyyyyyyy     */
1675       es_fprintf (es_stdout, "%.*s %.*s", 4, serialno+16, 8, serialno+20);
1676     }
1677  else
1678    es_fputs (serialno, es_stdout);
1679   es_putc ('\n', es_stdout);
1680 }
1681
1682
1683
1684 void
1685 set_attrib_fd (int fd)
1686 {
1687   static int last_fd = -1;
1688
1689   if (fd != -1 && last_fd == fd)
1690     return;
1691
1692   /* Fixme: Do we need to check for the log stream here?  */
1693   if (attrib_fp && attrib_fp != log_get_stream ())
1694     es_fclose (attrib_fp);
1695   attrib_fp = NULL;
1696   if (fd == -1)
1697     return;
1698
1699 #ifdef HAVE_DOSISH_SYSTEM
1700   setmode (fd, O_BINARY);
1701 #endif
1702   if (fd == 1)
1703     attrib_fp = es_stdout;
1704   else if (fd == 2)
1705     attrib_fp = es_stderr;
1706   else
1707     attrib_fp = es_fdopen (fd, "wb");
1708   if (!attrib_fp)
1709     {
1710       log_fatal ("can't open fd %d for attribute output: %s\n",
1711                  fd, strerror (errno));
1712     }
1713
1714   last_fd = fd;
1715 }