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