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