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