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