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