2006-04-14 Marcus Brinkmann <marcus@g10code.de>
[gnupg.git] / g10 / keylist.c
blob50850de716724f85f62cac19c5fb50fd078156ef
1 /* keylist.c - List all or selected keys
2 * Copyright (C) 1998, 1999, 2000, 2001, 2002,
3 * 2003 Free Software Foundation, Inc.
5 * This file is part of GnuPG.
7 * GnuPG is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
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.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
22 #include <config.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <errno.h>
27 #include <assert.h>
29 #include "options.h"
30 #include "packet.h"
31 #include "errors.h"
32 #include "keydb.h"
33 #include "memory.h"
34 #include "photoid.h"
35 #include "util.h"
36 #include "ttyio.h"
37 #include "trustdb.h"
38 #include "main.h"
39 #include "i18n.h"
40 #include "status.h"
42 static void list_all(int);
43 static void list_one( STRLIST names, int secret);
44 static void print_card_serialno (PKT_secret_key *sk);
46 struct sig_stats
48 int inv_sigs;
49 int no_key;
50 int oth_err;
53 static FILE *attrib_fp=NULL;
55 /****************
56 * List the keys
57 * If list is NULL, all available keys are listed
59 void
60 public_key_list( STRLIST list )
62 if(opt.with_colons)
64 byte trust_model,marginals,completes,cert_depth;
65 ulong created,nextcheck;
67 read_trust_options(&trust_model,&created,&nextcheck,
68 &marginals,&completes,&cert_depth);
70 printf("tru:");
72 if(nextcheck && nextcheck <= make_timestamp())
73 printf("o");
74 if(trust_model!=opt.trust_model)
75 printf("t");
76 if(opt.trust_model==TM_PGP || opt.trust_model==TM_CLASSIC)
78 if(marginals!=opt.marginals_needed)
79 printf("m");
80 if(completes!=opt.completes_needed)
81 printf("c");
82 if(cert_depth!=opt.max_cert_depth)
83 printf("d");
86 printf(":%d:%lu:%lu",trust_model,created,nextcheck);
88 /* Only show marginals, completes, and cert_depth in the classic
89 or PGP trust models since they are not meaningful
90 otherwise. */
92 if(trust_model==TM_PGP || trust_model==TM_CLASSIC)
93 printf(":%d:%d:%d",marginals,completes,cert_depth);
95 printf("\n");
98 if( !list )
99 list_all(0);
100 else
101 list_one( list, 0 );
104 void
105 secret_key_list( STRLIST list )
107 if( !list )
108 list_all(1);
109 else /* List by user id */
110 list_one( list, 1 );
113 void
114 print_seckey_info (PKT_secret_key *sk)
116 u32 sk_keyid[2];
117 size_t n;
118 char *p;
120 keyid_from_sk (sk, sk_keyid);
121 tty_printf ("\nsec %4u%c/%08lX %s ",
122 nbits_from_sk (sk),
123 pubkey_letter (sk->pubkey_algo),
124 (ulong)sk_keyid[1], datestr_from_sk (sk));
126 p = get_user_id (sk_keyid, &n);
127 tty_print_utf8_string (p, n);
128 xfree (p);
130 tty_printf ("\n");
133 /* Print information about the public key. With FP passed as NULL,
134 the tty output interface is used, otherwise output is directted to
135 the given stream. */
136 void
137 print_pubkey_info (FILE *fp, PKT_public_key *pk)
139 u32 pk_keyid[2];
140 size_t n;
141 char *p;
143 keyid_from_pk (pk, pk_keyid);
144 if (fp)
145 fprintf (fp, "pub %4u%c/%08lX %s ",
146 nbits_from_pk (pk),
147 pubkey_letter (pk->pubkey_algo),
148 (ulong)pk_keyid[1], datestr_from_pk (pk));
149 else
150 tty_printf ("\npub %4u%c/%08lX %s ",
151 nbits_from_pk (pk),
152 pubkey_letter (pk->pubkey_algo),
153 (ulong)pk_keyid[1], datestr_from_pk (pk));
155 p = get_user_id (pk_keyid, &n);
156 if (fp)
157 print_utf8_string2 (fp, p, n, '\n');
158 else
159 tty_print_utf8_string (p, n);
160 xfree (p);
162 if (fp)
163 putc ('\n', fp);
164 else
165 tty_printf ("\n\n");
169 mode=0 for stdout.
170 mode=1 for log_info + status messages
171 mode=2 for status messages only
174 void
175 show_policy_url(PKT_signature *sig,int indent,int mode)
177 const byte *p;
178 size_t len;
179 int seq=0,crit;
180 FILE *fp=mode?log_get_stream():stdout;
182 while((p=enum_sig_subpkt(sig->hashed,SIGSUBPKT_POLICY,&len,&seq,&crit)))
184 if(mode!=2)
186 int i;
187 char *str;
189 for(i=0;i<indent;i++)
190 putchar(' ');
192 if(crit)
193 str=_("Critical signature policy: ");
194 else
195 str=_("Signature policy: ");
196 if(mode)
197 log_info("%s",str);
198 else
199 printf("%s",str);
200 print_utf8_string(fp,p,len);
201 fprintf(fp,"\n");
204 if(mode)
205 write_status_buffer ( STATUS_POLICY_URL, p, len, 0 );
211 mode=0 for stdout.
212 mode=1 for log_info + status messages
213 mode=2 for status messages only
215 /* TODO: use this */
216 void
217 show_keyserver_url(PKT_signature *sig,int indent,int mode)
219 const byte *p;
220 size_t len;
221 int seq=0,crit;
222 FILE *fp=mode?log_get_stream():stdout;
224 while((p=enum_sig_subpkt(sig->hashed,SIGSUBPKT_PREF_KS,&len,&seq,&crit)))
226 if(mode!=2)
228 int i;
229 char *str;
231 for(i=0;i<indent;i++)
232 putchar(' ');
234 if(crit)
235 str=_("Critical preferred keyserver: ");
236 else
237 str=_("Preferred keyserver: ");
238 if(mode)
239 log_info("%s",str);
240 else
241 printf("%s",str);
242 print_utf8_string(fp,p,len);
243 fprintf(fp,"\n");
246 /* TODO: put in a status-fd tag for preferred keyservers */
252 mode=0 for stdout.
253 mode=1 for log_info + status messages
254 mode=2 for status messages only
257 void
258 show_notation(PKT_signature *sig,int indent,int mode)
260 const byte *p;
261 size_t len;
262 int seq=0,crit;
263 FILE *fp=mode?log_get_stream():stdout;
265 /* There may be multiple notations in the same sig. */
267 while((p=enum_sig_subpkt(sig->hashed,SIGSUBPKT_NOTATION,&len,&seq,&crit)))
268 if(len>=8)
270 int n1,n2;
272 n1=(p[4]<<8)|p[5];
273 n2=(p[6]<<8)|p[7];
275 if(8+n1+n2!=len)
277 log_info(_("WARNING: invalid notation data found\n"));
278 return;
281 if(mode!=2)
283 int i;
284 char *str;
286 for(i=0;i<indent;i++)
287 putchar(' ');
289 /* This is UTF8 */
290 if(crit)
291 str=_("Critical signature notation: ");
292 else
293 str=_("Signature notation: ");
294 if(mode)
295 log_info("%s",str);
296 else
297 printf("%s",str);
298 print_utf8_string(fp,p+8,n1);
299 fprintf(fp,"=");
301 if(*p&0x80)
302 print_utf8_string(fp,p+8+n1,n2);
303 else
304 fprintf(fp,"[ %s ]",_("not human readable"));
306 fprintf(fp,"\n");
309 if(mode)
311 write_status_buffer ( STATUS_NOTATION_NAME, p+8 , n1, 0 );
312 write_status_buffer ( STATUS_NOTATION_DATA, p+8+n1, n2, 50 );
315 else
316 log_info(_("WARNING: invalid notation data found\n"));
319 static void
320 print_signature_stats(struct sig_stats *s)
322 if( s->inv_sigs == 1 )
323 tty_printf(_("1 bad signature\n") );
324 else if( s->inv_sigs )
325 tty_printf(_("%d bad signatures\n"), s->inv_sigs );
326 if( s->no_key == 1 )
327 tty_printf(_("1 signature not checked due to a missing key\n") );
328 else if( s->no_key )
329 tty_printf(_("%d signatures not checked due to missing keys\n"),s->no_key);
330 if( s->oth_err == 1 )
331 tty_printf(_("1 signature not checked due to an error\n") );
332 else if( s->oth_err )
333 tty_printf(_("%d signatures not checked due to errors\n"), s->oth_err );
336 static void
337 list_all( int secret )
339 KEYDB_HANDLE hd;
340 KBNODE keyblock = NULL;
341 int rc=0;
342 const char *lastresname, *resname;
343 struct sig_stats stats;
345 memset(&stats,0,sizeof(stats));
347 hd = keydb_new (secret);
348 if (!hd)
349 rc = GPG_ERR_GENERAL;
350 else
351 rc = keydb_search_first (hd);
352 if( rc ) {
353 if( rc != -1 )
354 log_error("keydb_search_first failed: %s\n", gpg_strerror (rc) );
355 goto leave;
358 lastresname = NULL;
359 do {
360 rc = keydb_get_keyblock (hd, &keyblock);
361 if (rc) {
362 log_error ("keydb_get_keyblock failed: %s\n", gpg_strerror (rc));
363 goto leave;
365 if(!opt.with_colons)
367 resname = keydb_get_resource_name (hd);
368 if (lastresname != resname )
370 int i;
372 printf("%s\n", resname );
373 for(i=strlen(resname); i; i-- )
374 putchar('-');
375 putchar('\n');
376 lastresname = resname;
379 merge_keys_and_selfsig( keyblock );
380 list_keyblock( keyblock, secret, opt.fingerprint,
381 opt.check_sigs?&stats:NULL);
382 release_kbnode( keyblock );
383 keyblock = NULL;
384 } while (!(rc = keydb_search_next (hd)));
385 if( rc && rc != -1 )
386 log_error ("keydb_search_next failed: %s\n", gpg_strerror (rc));
388 if(opt.check_sigs && !opt.with_colons)
389 print_signature_stats(&stats);
391 leave:
392 release_kbnode (keyblock);
393 keydb_release (hd);
397 static void
398 list_one( STRLIST names, int secret )
400 int rc = 0;
401 KBNODE keyblock = NULL;
402 GETKEY_CTX ctx;
403 const char *resname;
404 char *keyring_str = _("Keyring");
405 int i;
406 struct sig_stats stats;
408 memset(&stats,0,sizeof(stats));
410 /* fixme: using the bynames function has the disadvantage that we
411 * don't know wether one of the names given was not found. OTOH,
412 * this function has the advantage to list the names in the
413 * sequence as defined by the keyDB and does not duplicate
414 * outputs. A solution could be do test whether all given have
415 * been listed (this needs a way to use the keyDB search
416 * functions) or to have the search function return indicators for
417 * found names. Yet another way is to use the keydb search
418 * facilities directly. */
419 if( secret ) {
420 rc = get_seckey_bynames( &ctx, NULL, names, &keyblock );
421 if( rc ) {
422 log_error("error reading key: %s\n", gpg_strerror (rc) );
423 get_seckey_end( ctx );
424 return;
426 do {
427 if ((opt.list_options&LIST_SHOW_KEYRING) && !opt.with_colons) {
428 resname = keydb_get_resource_name (get_ctx_handle(ctx));
429 printf("%s: %s\n", keyring_str, resname);
430 for(i = strlen(resname) + strlen(keyring_str) + 2; i; i-- )
431 putchar('-');
432 putchar('\n');
434 list_keyblock( keyblock, 1, opt.fingerprint, NULL );
435 release_kbnode( keyblock );
436 } while( !get_seckey_next( ctx, NULL, &keyblock ) );
437 get_seckey_end( ctx );
439 else {
440 rc = get_pubkey_bynames( &ctx, NULL, names, &keyblock );
441 if( rc ) {
442 log_error("error reading key: %s\n", gpg_strerror (rc) );
443 get_pubkey_end( ctx );
444 return;
446 do {
447 if ((opt.list_options&LIST_SHOW_KEYRING) && !opt.with_colons) {
448 resname = keydb_get_resource_name (get_ctx_handle(ctx));
449 printf("%s: %s\n", keyring_str, resname);
450 for(i = strlen(resname) + strlen(keyring_str) + 2; i; i-- )
451 putchar('-');
452 putchar('\n');
454 list_keyblock( keyblock, 0, opt.fingerprint,
455 opt.check_sigs?&stats:NULL );
456 release_kbnode( keyblock );
457 } while( !get_pubkey_next( ctx, NULL, &keyblock ) );
458 get_pubkey_end( ctx );
461 if(opt.check_sigs && !opt.with_colons)
462 print_signature_stats(&stats);
465 static void
466 print_key_data( PKT_public_key *pk, u32 *keyid )
468 int n = pk ? pubkey_get_npkey( pk->pubkey_algo ) : 0;
469 int i;
471 for(i=0; i < n; i++ ) {
472 printf("pkd:%d:%u:", i, mpi_get_nbits( pk->pkey[i] ) );
473 mpi_print(stdout, pk->pkey[i], 1 );
474 putchar(':');
475 putchar('\n');
479 static void
480 print_capabilities (PKT_public_key *pk, PKT_secret_key *sk, KBNODE keyblock)
482 if(pk || (sk && sk->protect.s2k.mode!=1001))
484 unsigned int use = pk? pk->pubkey_usage : sk->pubkey_usage;
486 if ( (use & PUBKEY_USAGE_ENC) )
487 putchar ('e');
489 if ( (use & PUBKEY_USAGE_SIG) )
491 putchar ('s');
492 if( pk? pk->is_primary : sk->is_primary )
493 putchar ('c');
496 if ( (use & PUBKEY_USAGE_AUTH) )
497 putchar ('a');
500 if ( keyblock ) { /* figure out the usable capabilities */
501 KBNODE k;
502 int enc=0, sign=0, cert=0, auth=0, disabled=0;
504 for (k=keyblock; k; k = k->next ) {
505 if ( k->pkt->pkttype == PKT_PUBLIC_KEY
506 || k->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
507 pk = k->pkt->pkt.public_key;
509 if(pk->is_primary)
510 disabled=pk_is_disabled(pk);
512 if ( pk->is_valid && !pk->is_revoked && !pk->has_expired ) {
513 if ( (pk->pubkey_usage & PUBKEY_USAGE_ENC) )
514 enc = 1;
515 if ( (pk->pubkey_usage & PUBKEY_USAGE_SIG) )
517 sign = 1;
518 if(pk->is_primary)
519 cert = 1;
521 if ( (pk->pubkey_usage & PUBKEY_USAGE_AUTH) )
522 auth = 1;
525 else if ( k->pkt->pkttype == PKT_SECRET_KEY
526 || k->pkt->pkttype == PKT_SECRET_SUBKEY ) {
527 sk = k->pkt->pkt.secret_key;
528 if ( sk->is_valid && !sk->is_revoked && !sk->has_expired
529 && sk->protect.s2k.mode!=1001 ) {
530 if ( (sk->pubkey_usage & PUBKEY_USAGE_ENC) )
531 enc = 1;
532 if ( (sk->pubkey_usage & PUBKEY_USAGE_SIG) )
534 sign = 1;
535 if(sk->is_primary)
536 cert = 1;
538 if ( (sk->pubkey_usage & PUBKEY_USAGE_AUTH) )
539 auth = 1;
543 if (enc)
544 putchar ('E');
545 if (sign)
546 putchar ('S');
547 if (cert)
548 putchar ('C');
549 if (auth)
550 putchar ('A');
551 if (disabled)
552 putchar ('D');
555 putchar(':');
558 void
559 dump_attribs(const PKT_user_id *uid,PKT_public_key *pk,PKT_secret_key *sk)
561 int i;
563 if(!attrib_fp)
564 return;
566 for(i=0;i<uid->numattribs;i++)
568 if(is_status_enabled())
570 byte array[MAX_FINGERPRINT_LEN], *p;
571 char buf[(MAX_FINGERPRINT_LEN*2)+90];
572 size_t j,n;
574 if(pk)
575 fingerprint_from_pk( pk, array, &n );
576 else if(sk)
577 fingerprint_from_sk( sk, array, &n );
578 else
579 BUG();
581 p = array;
582 for(j=0; j < n ; j++, p++ )
583 sprintf(buf+2*j, "%02X", *p );
585 sprintf(buf+strlen(buf)," %lu %u %u %u %lu %lu %u",
586 (ulong)uid->attribs[i].len,uid->attribs[i].type,i+1,
587 uid->numattribs,(ulong)uid->created,(ulong)uid->expiredate,
588 ((uid->is_primary?0x01:0)|
589 (uid->is_revoked?0x02:0)|
590 (uid->is_expired?0x04:0)));
591 write_status_text(STATUS_ATTRIBUTE,buf);
594 fwrite(uid->attribs[i].data,uid->attribs[i].len,1,attrib_fp);
598 static void
599 list_keyblock_print ( KBNODE keyblock, int secret, int fpr, void *opaque )
601 int rc = 0;
602 KBNODE kbctx;
603 KBNODE node;
604 PKT_public_key *pk;
605 PKT_secret_key *sk;
606 u32 keyid[2];
607 int any=0;
608 struct sig_stats *stats=opaque;
609 int newformat=((opt.list_options&LIST_SHOW_VALIDITY) && !secret)
610 || (opt.list_options&LIST_SHOW_LONG_KEYID);
612 /* get the keyid from the keyblock */
613 node = find_kbnode( keyblock, secret? PKT_SECRET_KEY : PKT_PUBLIC_KEY );
614 if( !node ) {
615 log_error("Oops; key lost!\n");
616 dump_kbnode( keyblock );
617 return;
620 if( secret )
622 pk = NULL;
623 sk = node->pkt->pkt.secret_key;
624 keyid_from_sk( sk, keyid );
626 printf("sec%c %4u%c/",(sk->protect.s2k.mode==1001)?'#':' ',
627 nbits_from_sk( sk ),pubkey_letter( sk->pubkey_algo ));
629 if(opt.list_options&LIST_SHOW_LONG_KEYID)
630 printf("%08lX%08lX",(ulong)keyid[0],(ulong)keyid[1]);
631 else
632 printf("%08lX",(ulong)keyid[1]);
634 printf(" %s%s",datestr_from_sk( sk ),newformat?"":" " );
636 if(newformat && sk->expiredate )
637 printf(_(" [expires: %s]"), expirestr_from_sk( sk ) );
639 else
641 int validity;
642 pk = node->pkt->pkt.public_key;
643 sk = NULL;
644 keyid_from_pk( pk, keyid );
646 validity=get_validity(pk,NULL);
648 printf("pub %4u%c/",
649 nbits_from_pk(pk),pubkey_letter(pk->pubkey_algo));
651 if(opt.list_options&LIST_SHOW_LONG_KEYID)
652 printf("%08lX%08lX",(ulong)keyid[0],(ulong)keyid[1]);
653 else
654 printf("%08lX",(ulong)keyid[1]);
656 printf(" %s%s",datestr_from_pk( pk ),newformat?"":" " );
658 /* We didn't include this before in the key listing, but there
659 is room in the new format, so why not? */
660 if(newformat && pk->expiredate)
661 printf(_(" [expires: %s]"), expirestr_from_pk( pk ) );
663 if(opt.list_options&LIST_SHOW_VALIDITY)
664 printf(" [%s]",trust_value_to_string(validity));
667 for( kbctx=NULL; (node=walk_kbnode( keyblock, &kbctx, 0)) ; ) {
668 if( node->pkt->pkttype == PKT_USER_ID && !opt.fast_list_mode ) {
669 int indent;
670 /* don't list revoked or expired UIDS unless we are in
671 * verbose mode and signature listing has not been
672 * requested */
673 if ( !opt.verbose && !opt.list_sigs &&
674 (node->pkt->pkt.user_id->is_revoked ||
675 node->pkt->pkt.user_id->is_expired ))
676 continue;
678 if(attrib_fp && node->pkt->pkt.user_id->attrib_data!=NULL)
679 dump_attribs(node->pkt->pkt.user_id,pk,sk);
681 if(!any && newformat)
682 printf("\n");
684 if((opt.list_options&LIST_SHOW_VALIDITY) && pk)
686 const char *validity=
687 trust_value_to_string(get_validity(pk,node->pkt->pkt.user_id));
689 /* Includes the 3 spaces for [, ], and " ". */
690 indent=((opt.list_options&LIST_SHOW_LONG_KEYID)?23:15)
691 -strlen(validity);
693 if(indent<0)
694 indent=0;
696 printf("uid%*s[%s] ",indent,"",validity);
698 else if(newformat)
699 printf("uid%*s",26,"");
700 else if(any)
701 printf("uid%*s",29,"");
703 if ( node->pkt->pkt.user_id->is_revoked )
704 fputs ("[revoked] ", stdout);
705 if ( node->pkt->pkt.user_id->is_expired )
706 fputs ("[expired] ", stdout);
708 print_utf8_string( stdout, node->pkt->pkt.user_id->name,
709 node->pkt->pkt.user_id->len );
710 putchar('\n');
711 if( !any ) {
712 if( fpr )
713 print_fingerprint( pk, sk, 0 );
714 print_card_serialno (sk);
715 if( opt.with_key_data )
716 print_key_data( pk, keyid );
717 any = 1;
720 if((opt.list_options&LIST_SHOW_PHOTOS)
721 && node->pkt->pkt.user_id->attribs!=NULL)
722 show_photos(node->pkt->pkt.user_id->attribs,
723 node->pkt->pkt.user_id->numattribs,pk,sk);
725 else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
726 u32 keyid2[2];
727 PKT_public_key *pk2 = node->pkt->pkt.public_key;
729 if( !any ) {
730 putchar('\n');
731 if( fpr )
732 print_fingerprint( pk, sk, 0 ); /* of the main key */
733 any = 1;
736 keyid_from_pk( pk2, keyid2 );
737 printf("sub %4u%c/",
738 nbits_from_pk( pk2 ),pubkey_letter( pk2->pubkey_algo ));
739 if(opt.list_options&LIST_SHOW_LONG_KEYID)
740 printf("%08lX%08lX",(ulong)keyid2[0],(ulong)keyid2[1]);
741 else
742 printf("%08lX",(ulong)keyid2[1]);
743 printf(" %s",datestr_from_pk(pk2));
744 if( pk2->expiredate )
745 printf(_(" [expires: %s]"), expirestr_from_pk( pk2 ) );
746 putchar('\n');
747 if( fpr > 1 )
748 print_fingerprint( pk2, NULL, 0 );
749 if( opt.with_key_data )
750 print_key_data( pk2, keyid2 );
752 else if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
753 u32 keyid2[2];
754 PKT_secret_key *sk2 = node->pkt->pkt.secret_key;
756 if( !any ) {
757 putchar('\n');
758 if( fpr )
759 print_fingerprint( pk, sk, 0 ); /* of the main key */
760 print_card_serialno (sk);
761 any = 1;
764 keyid_from_sk( sk2, keyid2 );
765 printf("ssb %4u%c/",
766 nbits_from_sk( sk2 ),pubkey_letter( sk2->pubkey_algo ));
767 if(opt.list_options&LIST_SHOW_LONG_KEYID)
768 printf("%08lX%08lX",(ulong)keyid2[0],(ulong)keyid2[1]);
769 else
770 printf("%08lX",(ulong)keyid2[1]);
771 printf(" %s",datestr_from_sk( sk2 ) );
772 if( sk2->expiredate )
773 printf(_(" [expires: %s]"), expirestr_from_sk( sk2 ) );
774 putchar('\n');
775 if( fpr > 1 )
777 print_fingerprint( NULL, sk2, 0 );
778 print_card_serialno (sk);
781 else if( opt.list_sigs && node->pkt->pkttype == PKT_SIGNATURE ) {
782 PKT_signature *sig = node->pkt->pkt.signature;
783 int sigrc;
784 char *sigstr;
786 if( stats ) {
787 /*fflush(stdout);*/
788 rc = check_key_signature( keyblock, node, NULL );
789 switch( gpg_err_code (rc) ) {
790 case 0: sigrc = '!'; break;
791 case GPG_ERR_BAD_SIGNATURE: stats->inv_sigs++; sigrc = '-'; break;
792 case GPG_ERR_NO_PUBKEY:
793 case GPG_ERR_UNUSABLE_PUBKEY: stats->no_key++; continue;
794 default: stats->oth_err++; sigrc = '%'; break;
797 /* TODO: Make sure a cached sig record here still has
798 the pk that issued it. See also
799 keyedit.c:print_and_check_one_sig */
802 else {
803 rc = 0;
804 sigrc = ' ';
807 if( !any ) { /* no user id, (maybe a revocation follows)*/
808 /* Check if the pk is really revoked - there could be a
809 0x20 sig packet there even if we are not revoked
810 (say, if a revocation key issued the packet, but the
811 revocation key isn't present to verify it.) */
812 if( sig->sig_class == 0x20 && pk->is_revoked )
813 puts("[revoked]");
814 else if( sig->sig_class == 0x18 )
815 puts("[key binding]");
816 else if( sig->sig_class == 0x28 )
817 puts("[subkey revoked]");
818 else
819 putchar('\n');
820 if( fpr )
821 print_fingerprint( pk, sk, 0 );
822 print_card_serialno (sk);
823 any=1;
826 if( sig->sig_class == 0x20 || sig->sig_class == 0x28
827 || sig->sig_class == 0x30 )
828 sigstr = "rev";
829 else if( (sig->sig_class&~3) == 0x10 )
830 sigstr = "sig";
831 else if( sig->sig_class == 0x18 )
832 sigstr = "sig";
833 else if( sig->sig_class == 0x1F )
834 sigstr = "sig";
835 else {
836 printf("sig "
837 "[unexpected signature class 0x%02x]\n",sig->sig_class );
838 continue;
841 fputs( sigstr, stdout );
842 printf("%c%c %c%c%c%c%c%c ",
843 sigrc,(sig->sig_class-0x10>0 &&
844 sig->sig_class-0x10<4)?'0'+sig->sig_class-0x10:' ',
845 sig->flags.exportable?' ':'L',
846 sig->flags.revocable?' ':'R',
847 sig->flags.policy_url?'P':' ',
848 sig->flags.notation?'N':' ',
849 sig->flags.expired?'X':' ',
850 (sig->trust_depth>9)?'T':
851 (sig->trust_depth>0)?'0'+sig->trust_depth:' ');
852 if(opt.list_options&LIST_SHOW_LONG_KEYID)
853 printf("%08lX%08lX",(ulong)sig->keyid[0],(ulong)sig->keyid[1]);
854 else
855 printf("%08lX",(ulong)sig->keyid[1]);
856 printf(" %s ", datestr_from_sig(sig));
857 if( sigrc == '%' )
858 printf("[%s] ", gpg_strerror (rc) );
859 else if( sigrc == '?' )
861 else if ( !opt.fast_list_mode ) {
862 size_t n;
863 char *p = get_user_id( sig->keyid, &n );
864 print_utf8_string( stdout, p, n );
865 xfree (p);
867 putchar('\n');
869 if(sig->flags.policy_url && (opt.list_options&LIST_SHOW_POLICY))
870 show_policy_url(sig,3,0);
872 if(sig->flags.notation && (opt.list_options&LIST_SHOW_NOTATION))
873 show_notation(sig,3,0);
875 if(sig->flags.pref_ks && (opt.list_options&LIST_SHOW_KEYSERVER))
876 show_keyserver_url(sig,3,0);
878 /* fixme: check or list other sigs here */
881 putchar('\n');
885 static void
886 list_keyblock_colon( KBNODE keyblock, int secret, int fpr )
888 int rc = 0;
889 KBNODE kbctx;
890 KBNODE node;
891 PKT_public_key *pk;
892 PKT_secret_key *sk;
893 u32 keyid[2];
894 int any=0;
895 int trustletter = 0;
896 int ulti_hack = 0;
898 /* get the keyid from the keyblock */
899 node = find_kbnode( keyblock, secret? PKT_SECRET_KEY : PKT_PUBLIC_KEY );
900 if( !node ) {
901 log_error("Oops; key lost!\n");
902 dump_kbnode( keyblock );
903 return;
906 if( secret ) {
907 pk = NULL;
908 sk = node->pkt->pkt.secret_key;
909 keyid_from_sk( sk, keyid );
910 printf("sec::%u:%d:%08lX%08lX:%s:%s:::",
911 nbits_from_sk( sk ),
912 sk->pubkey_algo,
913 (ulong)keyid[0],(ulong)keyid[1],
914 colon_datestr_from_sk( sk ),
915 colon_strtime (sk->expiredate)
916 /* fixme: add LID here */ );
918 else {
919 pk = node->pkt->pkt.public_key;
920 sk = NULL;
921 keyid_from_pk( pk, keyid );
922 fputs( "pub:", stdout );
923 if ( !pk->is_valid )
924 putchar ('i');
925 else if ( pk->is_revoked )
926 putchar ('r');
927 else if ( pk->has_expired )
928 putchar ('e');
929 else if ( opt.fast_list_mode || opt.no_expensive_trust_checks )
931 else {
932 trustletter = get_validity_info ( pk, NULL );
933 if( trustletter == 'u' )
934 ulti_hack = 1;
935 putchar(trustletter);
937 printf(":%u:%d:%08lX%08lX:%s:%s:",
938 nbits_from_pk( pk ),
939 pk->pubkey_algo,
940 (ulong)keyid[0],(ulong)keyid[1],
941 colon_datestr_from_pk( pk ),
942 colon_strtime (pk->expiredate) );
943 if( pk->local_id )
944 printf("%lu", pk->local_id );
945 putchar(':');
946 if( !opt.fast_list_mode && !opt.no_expensive_trust_checks )
947 putchar( get_ownertrust_info(pk) );
948 putchar(':');
951 if (opt.fixed_list_mode) {
952 /* do not merge the first uid with the primary key */
953 putchar(':');
954 putchar(':');
955 print_capabilities (pk, sk, keyblock);
956 putchar('\n');
957 if( fpr )
958 print_fingerprint( pk, sk, 0 );
959 if( opt.with_key_data )
960 print_key_data( pk, keyid );
961 any = 1;
965 for( kbctx=NULL; (node=walk_kbnode( keyblock, &kbctx, 0)) ; ) {
966 if( node->pkt->pkttype == PKT_USER_ID && !opt.fast_list_mode ) {
967 PKT_user_id *uid=node->pkt->pkt.user_id;
968 if(attrib_fp && node->pkt->pkt.user_id->attrib_data!=NULL)
969 dump_attribs(node->pkt->pkt.user_id,pk,sk);
971 * Fixme: We need a is_valid flag here too
973 if( any ) {
974 int i;
975 char *str=uid->attrib_data?"uat":"uid";
976 /* If we're listing a secret key, leave out the
977 validity values for now. FIXME: This should be
978 handled better in 1.9. */
979 if ( sk )
980 printf("%s:::::",str);
981 else if ( uid->is_revoked )
982 printf("%s:r::::",str);
983 else if ( uid->is_expired )
984 printf("%s:e::::",str);
985 else if ( opt.no_expensive_trust_checks )
986 printf("%s:::::",str);
987 else {
988 int uid_validity;
990 if( pk && !ulti_hack )
991 uid_validity=get_validity_info (pk, uid);
992 else
993 uid_validity = 'u';
994 printf("%s:%c::::",str,uid_validity);
997 printf("%s:",colon_strtime(uid->created));
998 printf("%s:",colon_strtime(uid->expiredate));
1000 namehash_from_uid(uid);
1002 for(i=0; i < 20; i++ )
1003 printf("%02X",uid->namehash[i]);
1005 printf("::");
1007 if(uid->attrib_data)
1008 printf("%u %lu",uid->numattribs,uid->attrib_len);
1009 else
1010 print_string(stdout,uid->name,uid->len, ':' );
1011 putchar(':');
1012 if (any)
1013 putchar('\n');
1014 else {
1015 putchar(':');
1016 print_capabilities (pk, sk, keyblock);
1017 putchar('\n');
1018 if( fpr )
1019 print_fingerprint( pk, sk, 0 );
1020 if( opt.with_key_data )
1021 print_key_data( pk, keyid );
1022 any = 1;
1025 else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
1026 u32 keyid2[2];
1027 PKT_public_key *pk2 = node->pkt->pkt.public_key;
1029 if( !any ) {
1030 putchar(':');
1031 putchar(':');
1032 print_capabilities (pk, sk, keyblock);
1033 putchar('\n');
1034 if( fpr )
1035 print_fingerprint( pk, sk, 0 ); /* of the main key */
1036 any = 1;
1039 keyid_from_pk( pk2, keyid2 );
1040 fputs ("sub:", stdout );
1041 if ( !pk2->is_valid )
1042 putchar ('i');
1043 else if ( pk2->is_revoked )
1044 putchar ('r');
1045 else if ( pk2->has_expired )
1046 putchar ('e');
1047 else if ( opt.fast_list_mode || opt.no_expensive_trust_checks )
1049 else {
1050 /* trustletter should always be defined here */
1051 if(trustletter)
1052 printf("%c", trustletter );
1054 printf(":%u:%d:%08lX%08lX:%s:%s:",
1055 nbits_from_pk( pk2 ),
1056 pk2->pubkey_algo,
1057 (ulong)keyid2[0],(ulong)keyid2[1],
1058 colon_datestr_from_pk( pk2 ),
1059 colon_strtime (pk2->expiredate)
1060 /* fixme: add LID and ownertrust here */
1062 if( pk->local_id ) /* use the local_id of the main key??? */
1063 printf("%lu", pk->local_id );
1064 putchar(':');
1065 putchar(':');
1066 putchar(':');
1067 putchar(':');
1068 print_capabilities (pk2, NULL, NULL);
1069 putchar('\n');
1070 if( fpr > 1 )
1071 print_fingerprint( pk2, NULL, 0 );
1072 if( opt.with_key_data )
1073 print_key_data( pk2, keyid2 );
1075 else if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
1076 u32 keyid2[2];
1077 PKT_secret_key *sk2 = node->pkt->pkt.secret_key;
1079 if( !any ) {
1080 putchar(':');
1081 putchar(':');
1082 print_capabilities (pk, sk, keyblock);
1083 putchar('\n');
1084 if( fpr )
1085 print_fingerprint( pk, sk, 0 ); /* of the main key */
1086 any = 1;
1089 keyid_from_sk( sk2, keyid2 );
1090 printf("ssb::%u:%d:%08lX%08lX:%s:%s:::::",
1091 nbits_from_sk( sk2 ),
1092 sk2->pubkey_algo,
1093 (ulong)keyid2[0],(ulong)keyid2[1],
1094 colon_datestr_from_sk( sk2 ),
1095 colon_strtime (sk2->expiredate)
1096 /* fixme: add LID */ );
1097 print_capabilities (NULL, sk2, NULL);
1098 putchar ('\n');
1099 if( fpr > 1 )
1100 print_fingerprint( NULL, sk2, 0 );
1102 else if( opt.list_sigs && node->pkt->pkttype == PKT_SIGNATURE ) {
1103 PKT_signature *sig = node->pkt->pkt.signature;
1104 int sigrc, fprokay=0;
1105 char *sigstr;
1106 size_t fplen;
1107 byte fparray[MAX_FINGERPRINT_LEN];
1109 if( !any ) { /* no user id, (maybe a revocation follows)*/
1110 if( sig->sig_class == 0x20 )
1111 fputs("[revoked]:", stdout);
1112 else if( sig->sig_class == 0x18 )
1113 fputs("[key binding]:", stdout);
1114 else if( sig->sig_class == 0x28 )
1115 fputs("[subkey revoked]:", stdout);
1116 else
1117 putchar (':');
1118 putchar(':');
1119 print_capabilities (pk, sk, keyblock);
1120 putchar('\n');
1121 if( fpr )
1122 print_fingerprint( pk, sk, 0 );
1123 any=1;
1126 if( sig->sig_class == 0x20 || sig->sig_class == 0x28
1127 || sig->sig_class == 0x30 )
1128 sigstr = "rev";
1129 else if( (sig->sig_class&~3) == 0x10 )
1130 sigstr = "sig";
1131 else if( sig->sig_class == 0x18 )
1132 sigstr = "sig";
1133 else if( sig->sig_class == 0x1F )
1134 sigstr = "sig";
1135 else {
1136 printf ("sig::::::::::%02x%c:\n",
1137 sig->sig_class, sig->flags.exportable?'x':'l');
1138 continue;
1140 if( opt.check_sigs ) {
1141 PKT_public_key *signer_pk=NULL;
1143 fflush(stdout);
1144 if(opt.no_sig_cache)
1145 signer_pk = xcalloc (1, sizeof(PKT_public_key));
1147 rc = check_key_signature2( keyblock, node, NULL, signer_pk,
1148 NULL, NULL, NULL );
1149 switch( gpg_err_code (rc) ) {
1150 case 0: sigrc = '!'; break;
1151 case GPG_ERR_BAD_SIGNATURE: sigrc = '-'; break;
1152 case GPG_ERR_NO_PUBKEY:
1153 case GPG_ERR_UNUSABLE_PUBKEY: sigrc = '?'; break;
1154 default: sigrc = '%'; break;
1157 if(opt.no_sig_cache)
1159 if(!rc)
1161 fingerprint_from_pk (signer_pk, fparray, &fplen);
1162 fprokay=1;
1164 free_public_key(signer_pk);
1167 else {
1168 rc = 0;
1169 sigrc = ' ';
1171 fputs( sigstr, stdout );
1172 putchar(':');
1173 if( sigrc != ' ' )
1174 putchar(sigrc);
1175 printf("::%d:%08lX%08lX:%s:%s:", sig->pubkey_algo,
1176 (ulong)sig->keyid[0], (ulong)sig->keyid[1],
1177 colon_datestr_from_sig(sig),
1178 colon_expirestr_from_sig(sig));
1180 if(sig->trust_depth || sig->trust_value)
1181 printf("%d %d",sig->trust_depth,sig->trust_value);
1182 printf(":");
1184 if(sig->trust_regexp)
1185 print_string(stdout,sig->trust_regexp,
1186 strlen(sig->trust_regexp),':');
1187 printf(":");
1189 if( sigrc == '%' )
1190 printf("[%s] ", gpg_strerror (rc) );
1191 else if( sigrc == '?' )
1193 else if ( !opt.fast_list_mode ) {
1194 size_t n;
1195 char *p = get_user_id( sig->keyid, &n );
1196 print_string( stdout, p, n, ':' );
1197 xfree (p);
1199 printf(":%02x%c:", sig->sig_class,sig->flags.exportable?'x':'l');
1200 if(opt.no_sig_cache && opt.check_sigs && fprokay)
1202 size_t i;
1204 printf(":");
1206 for (i=0; i < fplen ; i++ )
1207 printf ("%02X", fparray[i] );
1209 printf(":");
1212 printf("\n");
1213 /* fixme: check or list other sigs here */
1216 if( !any ) {/* oops, no user id */
1217 putchar(':');
1218 putchar(':');
1219 print_capabilities (pk, sk, keyblock);
1220 putchar('\n');
1225 * Reorder the keyblock so that the primary user ID (and not attribute
1226 * packet) comes first. Fixme: Replace this by a generic sort
1227 * function. */
1228 void
1229 reorder_keyblock (KBNODE keyblock)
1231 KBNODE primary = NULL, primary0 = NULL, primary2 = NULL;
1232 KBNODE last, node;
1234 for (node=keyblock; node; primary0=node, node = node->next) {
1235 if( node->pkt->pkttype == PKT_USER_ID &&
1236 !node->pkt->pkt.user_id->attrib_data &&
1237 node->pkt->pkt.user_id->is_primary ) {
1238 primary = primary2 = node;
1239 for (node=node->next; node; primary2=node, node = node->next ) {
1240 if( node->pkt->pkttype == PKT_USER_ID
1241 || node->pkt->pkttype == PKT_PUBLIC_SUBKEY
1242 || node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
1243 break;
1246 break;
1249 if ( !primary )
1250 return; /* no primary key flag found (should not happen) */
1252 for (last=NULL, node=keyblock; node; last = node, node = node->next) {
1253 if( node->pkt->pkttype == PKT_USER_ID )
1254 break;
1256 assert (node);
1257 assert (last); /* the user ID is never the first packet */
1258 assert (primary0); /* ditto (this is the node before primary) */
1259 if ( node == primary )
1260 return; /* already the first one */
1262 last->next = primary;
1263 primary0->next = primary2->next;
1264 primary2->next = node;
1267 void
1268 list_keyblock( KBNODE keyblock, int secret, int fpr, void *opaque )
1270 reorder_keyblock (keyblock);
1271 if (opt.with_colons)
1272 list_keyblock_colon (keyblock, secret, fpr );
1273 else
1274 list_keyblock_print (keyblock, secret, fpr, opaque );
1278 * standard function to print the finperprint.
1279 * mode 0: as used in key listings, opt.with_colons is honored
1280 * 1: print using log_info ()
1281 * 2: direct use of tty
1282 * 3: direct use of tty but only primary key.
1283 * modes 1 and 2 will try and print both subkey and primary key fingerprints
1285 void
1286 print_fingerprint (PKT_public_key *pk, PKT_secret_key *sk, int mode )
1288 byte array[MAX_FINGERPRINT_LEN], *p;
1289 size_t i, n;
1290 FILE *fp;
1291 const char *text;
1292 int primary=0;
1294 if(sk)
1296 if(sk->main_keyid[0]==sk->keyid[0] && sk->main_keyid[1]==sk->keyid[1])
1297 primary=1;
1299 else
1301 if(pk->main_keyid[0]==pk->keyid[0] && pk->main_keyid[1]==pk->keyid[1])
1302 primary=1;
1305 /* Just to be safe */
1306 if(mode&0x80 && !primary)
1308 log_error("primary key is not really primary!\n");
1309 return;
1312 mode&=~0x80;
1314 if(!primary && (mode==1 || mode==2))
1316 if(sk)
1318 PKT_secret_key *primary_sk=xcalloc (1,sizeof(*primary_sk));
1319 get_seckey(primary_sk,sk->main_keyid);
1320 print_fingerprint(NULL,primary_sk,mode|0x80);
1321 free_secret_key(primary_sk);
1323 else
1325 PKT_public_key *primary_pk=xcalloc (1,sizeof(*primary_pk));
1326 get_pubkey(primary_pk,pk->main_keyid);
1327 print_fingerprint(primary_pk,NULL,mode|0x80);
1328 free_public_key(primary_pk);
1332 if (mode == 1) {
1333 fp = log_get_stream ();
1334 if(primary)
1335 text = _("Primary key fingerprint:");
1336 else
1337 text = _(" Subkey fingerprint:");
1339 else if (mode == 2) {
1340 fp = NULL; /* use tty */
1341 /* Translators: this should fit into 24 bytes to that the fingerprint
1342 * data is properly aligned with the user ID */
1343 if(primary)
1344 text = _(" Primary key fingerprint:");
1345 else
1346 text = _(" Subkey fingerprint:");
1348 else if (mode == 3) {
1349 fp = NULL; /* use tty */
1350 text = _(" Key fingerprint =");
1352 else {
1353 fp = stdout;
1354 text = _(" Key fingerprint =");
1357 if (sk)
1358 fingerprint_from_sk (sk, array, &n);
1359 else
1360 fingerprint_from_pk (pk, array, &n);
1361 p = array;
1362 if (opt.with_colons && !mode) {
1363 fprintf (fp, "fpr:::::::::");
1364 for (i=0; i < n ; i++, p++ )
1365 fprintf (fp, "%02X", *p );
1366 putc(':', fp);
1368 else {
1369 if (fp)
1370 fputs (text, fp);
1371 else
1372 tty_printf ("%s", text);
1373 if (n == 20) {
1374 for (i=0; i < n ; i++, i++, p += 2 ) {
1375 if (fp) {
1376 if (i == 10 )
1377 putc(' ', fp);
1378 fprintf (fp, " %02X%02X", *p, p[1] );
1380 else {
1381 if (i == 10 )
1382 tty_printf (" ");
1383 tty_printf (" %02X%02X", *p, p[1]);
1387 else {
1388 for (i=0; i < n ; i++, p++ ) {
1389 if (fp) {
1390 if (i && !(i%8) )
1391 putc (' ', fp);
1392 fprintf (fp, " %02X", *p );
1394 else {
1395 if (i && !(i%8) )
1396 tty_printf (" ");
1397 tty_printf (" %02X", *p );
1402 if (fp)
1403 putc ('\n', fp);
1404 else
1405 tty_printf ("\n");
1409 /* Print the serial number of an OpenPGP card if available. */
1410 static void
1411 print_card_serialno (PKT_secret_key *sk)
1413 int i;
1415 if (!sk)
1416 return;
1417 if (!sk->is_protected || sk->protect.s2k.mode != 1002)
1418 return; /* Not a card. */
1419 if (opt.with_colons)
1420 return; /* Format not yet defined. */
1422 fputs (_(" Card serial no. ="), stdout);
1423 putchar (' ');
1424 if (sk->protect.ivlen == 16
1425 && !memcmp (sk->protect.iv, "\xD2\x76\x00\x01\x24\x01", 6) )
1426 { /* This is an OpenPGP card. Just print the relevant part. */
1427 for (i=8; i < 14; i++)
1429 if (i == 10)
1430 putchar (' ');
1431 printf ("%02X", sk->protect.iv[i]);
1434 else
1435 { /* Something is wrong: Print all. */
1436 for (i=0; i < sk->protect.ivlen; i++)
1437 printf ("%02X", sk->protect.iv[i]);
1439 putchar ('\n');
1442 void set_attrib_fd(int fd)
1444 static int last_fd=-1;
1446 if ( fd != -1 && last_fd == fd )
1447 return;
1449 if ( attrib_fp && attrib_fp != stdout && attrib_fp != stderr )
1450 fclose (attrib_fp);
1451 attrib_fp = NULL;
1452 if ( fd == -1 )
1453 return;
1455 if( fd == 1 )
1456 attrib_fp = stdout;
1457 else if( fd == 2 )
1458 attrib_fp = stderr;
1459 else
1460 attrib_fp = fdopen( fd, "w" );
1461 if( !attrib_fp ) {
1462 log_fatal("can't open fd %d for attribute output: %s\n",
1463 fd, strerror(errno));
1465 last_fd = fd;