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