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