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