1 /* keylist.c - print keys
2 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003,
3 * 2004, 2005 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
43 static void list_all(int);
44 static void list_one( STRLIST names
, int secret
);
45 static void print_card_serialno (PKT_secret_key
*sk
);
54 static FILE *attrib_fp
=NULL
;
58 * If list is NULL, all available keys are listed
61 public_key_list( STRLIST list
)
65 byte trust_model
,marginals
,completes
,cert_depth
;
66 ulong created
,nextcheck
;
68 read_trust_options(&trust_model
,&created
,&nextcheck
,
69 &marginals
,&completes
,&cert_depth
);
73 if(nextcheck
&& nextcheck
<= make_timestamp())
75 if(trust_model
!=opt
.trust_model
)
77 if(opt
.trust_model
==TM_PGP
|| opt
.trust_model
==TM_CLASSIC
)
79 if(marginals
!=opt
.marginals_needed
)
81 if(completes
!=opt
.completes_needed
)
83 if(cert_depth
!=opt
.max_cert_depth
)
87 printf(":%d:%lu:%lu",trust_model
,created
,nextcheck
);
89 /* Only show marginals, completes, and cert_depth in the classic
90 or PGP trust models since they are not meaningful
93 if(trust_model
==TM_PGP
|| trust_model
==TM_CLASSIC
)
94 printf(":%d:%d:%d",marginals
,completes
,cert_depth
);
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 ();
113 secret_key_list( STRLIST list
)
115 check_trustdb_stale ();
119 else /* List by user id */
124 print_seckey_info (PKT_secret_key
*sk
)
129 keyid_from_sk (sk
, keyid
);
130 p
=get_user_id_native(keyid
);
132 tty_printf ("\nsec %4u%c/%s %s %s\n",
134 pubkey_letter (sk
->pubkey_algo
),
135 keystr(keyid
), datestr_from_sk (sk
), p
);
140 /* Print information about the public key. With FP passed as NULL,
141 the tty output interface is used, otherwise output is directted to
144 print_pubkey_info (FILE *fp
, PKT_public_key
*pk
)
149 keyid_from_pk (pk
, keyid
);
151 /* If the pk was chosen by a particular user ID, that is the one to
154 p
=utf8_to_native(pk
->user_id
->name
,pk
->user_id
->len
,0);
156 p
=get_user_id_native(keyid
);
159 fprintf (fp
, "pub %4u%c/%s %s %s\n",
161 pubkey_letter (pk
->pubkey_algo
),
162 keystr(keyid
), datestr_from_pk (pk
), p
);
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
);
172 /* Print basic information of a secret key including the card serial
173 number information. */
175 print_card_key_info (FILE *fp
, KBNODE keyblock
)
180 for (node
= keyblock
; node
; node
= node
->next
)
182 if (node
->pkt
->pkttype
== PKT_SECRET_KEY
183 || (node
->pkt
->pkttype
== PKT_SECRET_SUBKEY
) )
185 PKT_secret_key
*sk
= node
->pkt
->pkt
.secret_key
;
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)?'>':' ',
192 pubkey_letter (sk
->pubkey_algo
),
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)
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))
204 /* This is an OpenPGP card. */
205 for (i
=8; i
< 14; i
++)
208 tty_fprintf (fp
, " ");
209 tty_fprintf (fp
, "%02X", sk
->protect
.iv
[i
]);
213 { /* Something is wrong: Print all. */
214 for (i
=0; i
< sk
->protect
.ivlen
; i
++)
215 tty_fprintf (fp
, "%02X", sk
->protect
.iv
[i
]);
218 tty_fprintf (fp
, "\n");
225 /* Flags = 0x01 hashed 0x02 critical */
227 status_one_subpacket(sigsubpkttype_t type
,size_t len
,int flags
,const byte
*buf
)
231 /* Don't print these. */
235 sprintf(status
,"%d %u %u ",type
,flags
,(unsigned int)len
);
237 write_status_text_and_buffer(STATUS_SIG_SUBPACKET
,status
,buf
,len
,0);
242 mode=1 for log_info + status messages
243 mode=2 for status messages only
247 show_policy_url(PKT_signature
*sig
,int indent
,int mode
)
252 FILE *fp
=mode
?log_get_stream():stdout
;
254 while((p
=enum_sig_subpkt(sig
->hashed
,SIGSUBPKT_POLICY
,&len
,&seq
,&crit
)))
261 for(i
=0;i
<indent
;i
++)
265 str
=_("Critical signature policy: ");
267 str
=_("Signature policy: ");
272 print_utf8_string(fp
,p
,len
);
277 write_status_buffer ( STATUS_POLICY_URL
, p
, len
, 0 );
283 mode=1 for log_info + status messages
284 mode=2 for status messages only
288 show_keyserver_url(PKT_signature
*sig
,int indent
,int mode
)
293 FILE *fp
=mode
?log_get_stream():stdout
;
295 while((p
=enum_sig_subpkt(sig
->hashed
,SIGSUBPKT_PREF_KS
,&len
,&seq
,&crit
)))
302 for(i
=0;i
<indent
;i
++)
306 str
=_("Critical preferred keyserver: ");
308 str
=_("Preferred keyserver: ");
313 print_utf8_string(fp
,p
,len
);
318 status_one_subpacket(SIGSUBPKT_PREF_KS
,len
,(crit
?0x02:0)|0x01,p
);
324 mode=1 for log_info + status messages
325 mode=2 for status messages only
328 1 == standard notations
333 show_notation(PKT_signature
*sig
,int indent
,int mode
,int which
)
335 FILE *fp
=mode
?log_get_stream():stdout
;
336 struct notation
*nd
,*notations
;
341 notations
=sig_to_notation(sig
);
343 /* There may be multiple notations in the same sig. */
344 for(nd
=notations
;nd
;nd
=nd
->next
)
348 int has_at
=!!strchr(nd
->name
,'@');
350 if((which
&1 && !has_at
) || (which
&2 && has_at
))
355 for(i
=0;i
<indent
;i
++)
358 if(nd
->flags
.critical
)
359 str
=_("Critical signature notation: ");
361 str
=_("Signature notation: ");
366 /* This is all UTF8 */
367 print_utf8_string(fp
,nd
->name
,strlen(nd
->name
));
369 print_utf8_string(fp
,nd
->value
,strlen(nd
->value
));
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);
383 free_notation(notations
);
387 print_signature_stats(struct sig_stats
*s
)
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
);
394 tty_printf(_("1 signature not checked due to a missing key\n") );
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
);
404 list_all( int secret
)
407 KBNODE keyblock
= NULL
;
409 const char *lastresname
, *resname
;
410 struct sig_stats stats
;
412 memset(&stats
,0,sizeof(stats
));
414 hd
= keydb_new (secret
);
418 rc
= keydb_search_first (hd
);
421 log_error("keydb_search_first failed: %s\n", g10_errstr(rc
) );
427 rc
= keydb_get_keyblock (hd
, &keyblock
);
429 log_error ("keydb_get_keyblock failed: %s\n", g10_errstr(rc
));
434 resname
= keydb_get_resource_name (hd
);
435 if (lastresname
!= resname
)
439 printf("%s\n", resname
);
440 for(i
=strlen(resname
); i
; i
-- )
443 lastresname
= resname
;
446 merge_keys_and_selfsig( keyblock
);
447 list_keyblock( keyblock
, secret
, opt
.fingerprint
,
448 opt
.check_sigs
?&stats
:NULL
);
449 release_kbnode( keyblock
);
451 } while (!(rc
= keydb_search_next (hd
)));
453 log_error ("keydb_search_next failed: %s\n", g10_errstr(rc
));
455 if(opt
.check_sigs
&& !opt
.with_colons
)
456 print_signature_stats(&stats
);
459 release_kbnode (keyblock
);
465 list_one( STRLIST names
, int secret
)
468 KBNODE keyblock
= NULL
;
471 const char *keyring_str
= _("Keyring");
473 struct sig_stats stats
;
475 memset(&stats
,0,sizeof(stats
));
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. */
487 rc
= get_seckey_bynames( &ctx
, NULL
, names
, &keyblock
);
489 log_error("error reading key: %s\n", g10_errstr(rc
) );
490 get_seckey_end( ctx
);
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
-- )
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
);
507 rc
= get_pubkey_bynames( &ctx
, NULL
, names
, &keyblock
);
509 log_error("error reading key: %s\n", g10_errstr(rc
) );
510 get_pubkey_end( ctx
);
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
-- )
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
);
528 if(opt
.check_sigs
&& !opt
.with_colons
)
529 print_signature_stats(&stats
);
533 print_key_data( PKT_public_key
*pk
)
535 int n
= pk
? pubkey_get_npkey( pk
->pubkey_algo
) : 0;
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 );
547 print_capabilities (PKT_public_key
*pk
, PKT_secret_key
*sk
, KBNODE keyblock
)
549 if(pk
|| (sk
&& sk
->protect
.s2k
.mode
!=1001))
551 unsigned int use
= pk
? pk
->pubkey_usage
: sk
->pubkey_usage
;
553 if ( use
& PUBKEY_USAGE_ENC
)
556 if ( use
& PUBKEY_USAGE_SIG
)
559 if( pk
? pk
->is_primary
: sk
->is_primary
)
563 if ( (use
& PUBKEY_USAGE_AUTH
) )
567 if ( keyblock
) { /* figure out the usable capabilities */
569 int enc
=0, sign
=0, cert
=0, auth
=0, disabled
=0;
571 for (k
=keyblock
; k
; k
= k
->next
) {
572 if ( k
->pkt
->pkttype
== PKT_PUBLIC_KEY
573 || k
->pkt
->pkttype
== PKT_PUBLIC_SUBKEY
) {
574 pk
= k
->pkt
->pkt
.public_key
;
577 disabled
=pk_is_disabled(pk
);
579 if ( pk
->is_valid
&& !pk
->is_revoked
&& !pk
->has_expired
) {
580 if ( pk
->pubkey_usage
& PUBKEY_USAGE_ENC
)
582 if ( pk
->pubkey_usage
& PUBKEY_USAGE_SIG
)
588 if ( (pk
->pubkey_usage
& PUBKEY_USAGE_AUTH
) )
592 else if ( k
->pkt
->pkttype
== PKT_SECRET_KEY
593 || k
->pkt
->pkttype
== PKT_SECRET_SUBKEY
) {
594 sk
= k
->pkt
->pkt
.secret_key
;
595 if ( sk
->is_valid
&& !sk
->is_revoked
&& !sk
->has_expired
596 && sk
->protect
.s2k
.mode
!=1001 ) {
597 if ( sk
->pubkey_usage
& PUBKEY_USAGE_ENC
)
599 if ( sk
->pubkey_usage
& PUBKEY_USAGE_SIG
)
605 if ( (sk
->pubkey_usage
& PUBKEY_USAGE_AUTH
) )
625 /* Flags = 0x01 hashed 0x02 critical */
627 print_one_subpacket(sigsubpkttype_t type
,size_t len
,int flags
,const byte
*buf
)
631 printf("spk:%d:%u:%u:",type
,flags
,(unsigned int)len
);
635 /* printable ascii other than : and % */
636 if(buf
[i
]>=32 && buf
[i
]<=126 && buf
[i
]!=':' && buf
[i
]!='%')
639 printf("%%%02X",buf
[i
]);
646 print_subpackets_colon(PKT_signature
*sig
)
650 assert(opt
.show_subpackets
);
652 for(i
=opt
.show_subpackets
;*i
;i
++)
660 while((p
=enum_sig_subpkt(sig
->hashed
,*i
,&len
,&seq
,&crit
)))
661 print_one_subpacket(*i
,len
,0x01|(crit
?0x02:0),p
);
665 while((p
=enum_sig_subpkt(sig
->unhashed
,*i
,&len
,&seq
,&crit
)))
666 print_one_subpacket(*i
,len
,0x00|(crit
?0x02:0),p
);
671 dump_attribs(const PKT_user_id
*uid
,PKT_public_key
*pk
,PKT_secret_key
*sk
)
678 for(i
=0;i
<uid
->numattribs
;i
++)
680 if(is_status_enabled())
682 byte array
[MAX_FINGERPRINT_LEN
], *p
;
683 char buf
[(MAX_FINGERPRINT_LEN
*2)+90];
687 fingerprint_from_pk( pk
, array
, &n
);
689 fingerprint_from_sk( sk
, array
, &n
);
694 for(j
=0; j
< n
; j
++, p
++ )
695 sprintf(buf
+2*j
, "%02X", *p
);
697 sprintf(buf
+strlen(buf
)," %lu %u %u %u %lu %lu %u",
698 (ulong
)uid
->attribs
[i
].len
,uid
->attribs
[i
].type
,i
+1,
699 uid
->numattribs
,(ulong
)uid
->created
,(ulong
)uid
->expiredate
,
700 ((uid
->is_primary
?0x01:0)|
701 (uid
->is_revoked
?0x02:0)|
702 (uid
->is_expired
?0x04:0)));
703 write_status_text(STATUS_ATTRIBUTE
,buf
);
706 fwrite(uid
->attribs
[i
].data
,uid
->attribs
[i
].len
,1,attrib_fp
);
711 list_keyblock_print ( KBNODE keyblock
, int secret
, int fpr
, void *opaque
)
718 struct sig_stats
*stats
=opaque
;
721 /* get the keyid from the keyblock */
722 node
= find_kbnode( keyblock
, secret
? PKT_SECRET_KEY
: PKT_PUBLIC_KEY
);
724 log_error("Oops; key lost!\n");
725 dump_kbnode( keyblock
);
732 sk
= node
->pkt
->pkt
.secret_key
;
734 printf("sec%c %4u%c/%s %s",(sk
->protect
.s2k
.mode
==1001)?'#':
735 (sk
->protect
.s2k
.mode
==1002)?'>':' ',
736 nbits_from_sk( sk
),pubkey_letter( sk
->pubkey_algo
),
737 keystr_from_sk(sk
),datestr_from_sk( sk
));
742 printf(_("expired: %s"),expirestr_from_sk(sk
));
745 else if(sk
->expiredate
)
748 printf(_("expires: %s"),expirestr_from_sk(sk
));
756 pk
= node
->pkt
->pkt
.public_key
;
759 check_trustdb_stale();
761 printf("pub %4u%c/%s %s",
762 nbits_from_pk(pk
),pubkey_letter(pk
->pubkey_algo
),
763 keystr_from_pk(pk
),datestr_from_pk( pk
));
765 /* We didn't include this before in the key listing, but there
766 is room in the new format, so why not? */
771 printf(_("revoked: %s"),revokestr_from_pk(pk
));
774 else if(pk
->has_expired
)
777 printf(_("expired: %s"),expirestr_from_pk(pk
));
780 else if(pk
->expiredate
)
783 printf(_("expires: %s"),expirestr_from_pk(pk
));
788 /* I need to think about this some more. It's easy enough to
789 include, but it looks sort of confusing in the
791 if(opt
.list_options
&LIST_SHOW_VALIDITY
)
793 int validity
=get_validity(pk
,NULL
);
794 printf(" [%s]",trust_value_to_string(validity
));
802 print_fingerprint( pk
, sk
, 0 );
803 print_card_serialno (sk
);
804 if( opt
.with_key_data
)
805 print_key_data( pk
);
807 for( kbctx
=NULL
; (node
=walk_kbnode( keyblock
, &kbctx
, 0)) ; ) {
808 if( node
->pkt
->pkttype
== PKT_USER_ID
&& !opt
.fast_list_mode
) {
809 PKT_user_id
*uid
=node
->pkt
->pkt
.user_id
;
811 if(pk
&& (uid
->is_expired
|| uid
->is_revoked
)
812 && !(opt
.list_options
&LIST_SHOW_UNUSABLE_UIDS
))
820 if(attrib_fp
&& uid
->attrib_data
!=NULL
)
821 dump_attribs(uid
,pk
,sk
);
823 if((uid
->is_revoked
|| uid
->is_expired
)
824 || ((opt
.list_options
&LIST_SHOW_UID_VALIDITY
) && pk
))
826 const char *validity
;
829 validity
=uid_trust_string_fixed(pk
,uid
);
830 indent
=(keystrlen()+9)-atoi(uid_trust_string_fixed(NULL
,NULL
));
832 if(indent
<0 || indent
>40)
835 printf("uid%*s%s ",indent
,"",validity
);
838 printf("uid%*s", (int)keystrlen()+10,"");
840 print_utf8_string( stdout
, uid
->name
, uid
->len
);
843 if((opt
.list_options
&LIST_SHOW_PHOTOS
) && uid
->attribs
!=NULL
)
844 show_photos(uid
->attribs
,uid
->numattribs
,pk
,sk
);
846 else if( node
->pkt
->pkttype
== PKT_PUBLIC_SUBKEY
)
848 PKT_public_key
*pk2
= node
->pkt
->pkt
.public_key
;
850 if((pk2
->is_revoked
|| pk2
->has_expired
)
851 && !(opt
.list_options
&LIST_SHOW_UNUSABLE_SUBKEYS
))
859 printf("sub %4u%c/%s %s",
860 nbits_from_pk( pk2
),pubkey_letter( pk2
->pubkey_algo
),
861 keystr_from_pk(pk2
),datestr_from_pk(pk2
));
862 if( pk2
->is_revoked
)
865 printf(_("revoked: %s"),revokestr_from_pk(pk2
));
868 else if( pk2
->has_expired
)
871 printf(_("expired: %s"),expirestr_from_pk(pk2
));
874 else if( pk2
->expiredate
)
877 printf(_("expires: %s"),expirestr_from_pk(pk2
));
882 print_fingerprint( pk2
, NULL
, 0 );
883 if( opt
.with_key_data
)
884 print_key_data( pk2
);
886 else if( node
->pkt
->pkttype
== PKT_SECRET_SUBKEY
)
888 PKT_secret_key
*sk2
= node
->pkt
->pkt
.secret_key
;
890 printf("ssb%c %4u%c/%s %s",
891 (sk2
->protect
.s2k
.mode
==1001)?'#':
892 (sk2
->protect
.s2k
.mode
==1002)?'>':' ',
893 nbits_from_sk( sk2
),pubkey_letter( sk2
->pubkey_algo
),
894 keystr_from_sk(sk2
),datestr_from_sk( sk2
) );
895 if( sk2
->expiredate
)
898 printf(_("expires: %s"),expirestr_from_sk(sk2
));
904 print_fingerprint( NULL
, sk2
, 0 );
905 print_card_serialno (sk2
);
908 else if( opt
.list_sigs
909 && node
->pkt
->pkttype
== PKT_SIGNATURE
911 PKT_signature
*sig
= node
->pkt
->pkt
.signature
;
917 rc
= check_key_signature( keyblock
, node
, NULL
);
918 switch( gpg_err_code (rc
) ) {
919 case 0: sigrc
= '!'; break;
920 case GPG_ERR_BAD_SIGNATURE
:
921 stats
->inv_sigs
++; sigrc
= '-'; break;
922 case GPG_ERR_NO_PUBKEY
:
923 case GPG_ERR_UNUSABLE_PUBKEY
: stats
->no_key
++; continue;
924 default: stats
->oth_err
++; sigrc
= '%'; break;
927 /* TODO: Make sure a cached sig record here still has
928 the pk that issued it. See also
929 keyedit.c:print_and_check_one_sig */
936 if( sig
->sig_class
== 0x20 || sig
->sig_class
== 0x28
937 || sig
->sig_class
== 0x30 )
939 else if( (sig
->sig_class
&~3) == 0x10 )
941 else if( sig
->sig_class
== 0x18 )
943 else if( sig
->sig_class
== 0x1F )
947 "[unexpected signature class 0x%02x]\n",sig
->sig_class
);
951 fputs( sigstr
, stdout
);
952 printf("%c%c %c%c%c%c%c%c %s %s",
953 sigrc
,(sig
->sig_class
-0x10>0 &&
954 sig
->sig_class
-0x10<4)?'0'+sig
->sig_class
-0x10:' ',
955 sig
->flags
.exportable
?' ':'L',
956 sig
->flags
.revocable
?' ':'R',
957 sig
->flags
.policy_url
?'P':' ',
958 sig
->flags
.notation
?'N':' ',
959 sig
->flags
.expired
?'X':' ',
960 (sig
->trust_depth
>9)?'T':
961 (sig
->trust_depth
>0)?'0'+sig
->trust_depth
:' ',
962 keystr(sig
->keyid
),datestr_from_sig(sig
));
963 if(opt
.list_options
&LIST_SHOW_SIG_EXPIRE
)
964 printf(" %s", expirestr_from_sig(sig
));
967 printf("[%s] ", g10_errstr(rc
) );
968 else if( sigrc
== '?' )
970 else if ( !opt
.fast_list_mode
) {
972 char *p
= get_user_id( sig
->keyid
, &n
);
973 print_utf8_string( stdout
, p
, n
);
978 if(sig
->flags
.policy_url
979 && (opt
.list_options
&LIST_SHOW_POLICY_URLS
))
980 show_policy_url(sig
,3,0);
982 if(sig
->flags
.notation
&& (opt
.list_options
&LIST_SHOW_NOTATIONS
))
983 show_notation(sig
,3,0,
984 ((opt
.list_options
&LIST_SHOW_STD_NOTATIONS
)?1:0)+
985 ((opt
.list_options
&LIST_SHOW_USER_NOTATIONS
)?2:0));
987 if(sig
->flags
.pref_ks
988 && (opt
.list_options
&LIST_SHOW_KEYSERVER_URLS
))
989 show_keyserver_url(sig
,3,0);
991 /* fixme: check or list other sigs here */
998 print_revokers(PKT_public_key
*pk
)
1000 /* print the revoker record */
1001 if( !pk
->revkey
&& pk
->numrevkeys
)
1007 for (i
=0; i
< pk
->numrevkeys
; i
++)
1011 printf ("rvk:::%d::::::", pk
->revkey
[i
].algid
);
1012 p
= pk
->revkey
[i
].fpr
;
1013 for (j
=0; j
< 20; j
++, p
++ )
1014 printf ("%02X", *p
);
1015 printf (":%02x%s:\n", pk
->revkey
[i
].class,
1016 (pk
->revkey
[i
].class&0x40)?"s":"");
1022 list_keyblock_colon( KBNODE keyblock
, int secret
, int fpr
)
1031 int trustletter
= 0;
1035 /* get the keyid from the keyblock */
1036 node
= find_kbnode( keyblock
, secret
? PKT_SECRET_KEY
: PKT_PUBLIC_KEY
);
1038 log_error("Oops; key lost!\n");
1039 dump_kbnode( keyblock
);
1045 sk
= node
->pkt
->pkt
.secret_key
;
1046 keyid_from_sk( sk
, keyid
);
1047 printf("sec::%u:%d:%08lX%08lX:%s:%s:::",
1048 nbits_from_sk( sk
),
1050 (ulong
)keyid
[0],(ulong
)keyid
[1],
1051 colon_datestr_from_sk( sk
),
1052 colon_strtime (sk
->expiredate
)
1053 /* fixme: add LID here */ );
1056 pk
= node
->pkt
->pkt
.public_key
;
1058 keyid_from_pk( pk
, keyid
);
1059 fputs( "pub:", stdout
);
1060 if ( !pk
->is_valid
)
1062 else if ( pk
->is_revoked
)
1064 else if ( pk
->has_expired
)
1066 else if ( opt
.fast_list_mode
|| opt
.no_expensive_trust_checks
)
1069 trustletter
= get_validity_info ( pk
, NULL
);
1070 if( trustletter
== 'u' )
1072 putchar(trustletter
);
1074 printf(":%u:%d:%08lX%08lX:%s:%s::",
1075 nbits_from_pk( pk
),
1077 (ulong
)keyid
[0],(ulong
)keyid
[1],
1078 colon_datestr_from_pk( pk
),
1079 colon_strtime (pk
->expiredate
) );
1080 if( !opt
.fast_list_mode
&& !opt
.no_expensive_trust_checks
)
1081 putchar( get_ownertrust_info(pk
) );
1085 if (opt
.fixed_list_mode
) {
1086 /* do not merge the first uid with the primary key */
1089 print_capabilities (pk
, sk
, keyblock
);
1091 putchar(':'); /* End of field 13. */
1092 putchar(':'); /* End of field 14. */
1093 if (sk
->protect
.s2k
.mode
== 1001)
1094 putchar('#'); /* Key is just a stub. */
1095 else if (sk
->protect
.s2k
.mode
== 1002) {
1096 /* Key is stored on an external token (card) or handled by
1097 the gpg-agent. Print the serial number of that token
1099 for (i
=0; i
< sk
->protect
.ivlen
; i
++)
1100 printf ("%02X", sk
->protect
.iv
[i
]);
1102 putchar(':'); /* End of field 15. */
1108 print_fingerprint( pk
, sk
, 0 );
1109 if( opt
.with_key_data
)
1110 print_key_data( pk
);
1114 for( kbctx
=NULL
; (node
=walk_kbnode( keyblock
, &kbctx
, 0)) ; ) {
1115 if( node
->pkt
->pkttype
== PKT_USER_ID
&& !opt
.fast_list_mode
) {
1116 PKT_user_id
*uid
=node
->pkt
->pkt
.user_id
;
1117 if(attrib_fp
&& node
->pkt
->pkt
.user_id
->attrib_data
!=NULL
)
1118 dump_attribs(node
->pkt
->pkt
.user_id
,pk
,sk
);
1120 * Fixme: We need a is_valid flag here too
1123 char *str
=uid
->attrib_data
?"uat":"uid";
1124 /* If we're listing a secret key, leave out the
1125 validity values for now. This is handled better in
1128 printf("%s:::::",str
);
1129 else if ( uid
->is_revoked
)
1130 printf("%s:r::::",str
);
1131 else if ( uid
->is_expired
)
1132 printf("%s:e::::",str
);
1133 else if ( opt
.no_expensive_trust_checks
)
1134 printf("%s:::::",str
);
1138 if( pk
&& !ulti_hack
)
1139 uid_validity
=get_validity_info (pk
, uid
);
1142 printf("%s:%c::::",str
,uid_validity
);
1145 printf("%s:",colon_strtime(uid
->created
));
1146 printf("%s:",colon_strtime(uid
->expiredate
));
1148 namehash_from_uid(uid
);
1150 for(i
=0; i
< 20; i
++ )
1151 printf("%02X",uid
->namehash
[i
]);
1155 if(uid
->attrib_data
)
1156 printf("%u %lu",uid
->numattribs
,uid
->attrib_len
);
1158 print_string(stdout
,uid
->name
,uid
->len
, ':' );
1164 print_capabilities (pk
, sk
, keyblock
);
1167 print_fingerprint( pk
, sk
, 0 );
1168 if( opt
.with_key_data
)
1169 print_key_data( pk
);
1173 else if( node
->pkt
->pkttype
== PKT_PUBLIC_SUBKEY
) {
1175 PKT_public_key
*pk2
= node
->pkt
->pkt
.public_key
;
1180 print_capabilities (pk
, sk
, keyblock
);
1183 print_fingerprint( pk
, sk
, 0 ); /* of the main key */
1187 keyid_from_pk( pk2
, keyid2
);
1188 fputs ("sub:", stdout
);
1189 if ( !pk2
->is_valid
)
1191 else if ( pk2
->is_revoked
)
1193 else if ( pk2
->has_expired
)
1195 else if ( opt
.fast_list_mode
|| opt
.no_expensive_trust_checks
)
1198 /* trustletter should always be defined here */
1200 printf("%c", trustletter
);
1202 printf(":%u:%d:%08lX%08lX:%s:%s:::::",
1203 nbits_from_pk( pk2
),
1205 (ulong
)keyid2
[0],(ulong
)keyid2
[1],
1206 colon_datestr_from_pk( pk2
),
1207 colon_strtime (pk2
->expiredate
)
1208 /* fixme: add LID and ownertrust here */
1210 print_capabilities (pk2
, NULL
, NULL
);
1213 print_fingerprint( pk2
, NULL
, 0 );
1214 if( opt
.with_key_data
)
1215 print_key_data( pk2
);
1217 else if( node
->pkt
->pkttype
== PKT_SECRET_SUBKEY
) {
1219 PKT_secret_key
*sk2
= node
->pkt
->pkt
.secret_key
;
1224 print_capabilities (pk
, sk
, keyblock
);
1227 print_fingerprint( pk
, sk
, 0 ); /* of the main key */
1231 keyid_from_sk( sk2
, keyid2
);
1232 printf("ssb::%u:%d:%08lX%08lX:%s:%s:::::",
1233 nbits_from_sk( sk2
),
1235 (ulong
)keyid2
[0],(ulong
)keyid2
[1],
1236 colon_datestr_from_sk( sk2
),
1237 colon_strtime (sk2
->expiredate
)
1238 /* fixme: add LID */ );
1239 print_capabilities (NULL
, sk2
, NULL
);
1240 if (opt
.fixed_list_mode
) {
1241 /* We print the serial number only in fixed list mode
1242 for the primary key so, so avoid questions we print
1243 it for subkeys also only in this mode. There is no
1244 technical reason, though. */
1245 putchar(':'); /* End of field 13. */
1246 putchar(':'); /* End of field 14. */
1247 if (sk2
->protect
.s2k
.mode
== 1001)
1248 putchar('#'); /* Key is just a stub. */
1249 else if (sk2
->protect
.s2k
.mode
== 1002) {
1250 /* Key is stored on an external token (card) or handled by
1251 the gpg-agent. Print the serial number of that token
1253 for (i
=0; i
< sk2
->protect
.ivlen
; i
++)
1254 printf ("%02X", sk2
->protect
.iv
[i
]);
1256 putchar(':'); /* End of field 15. */
1260 print_fingerprint( NULL
, sk2
, 0 );
1262 else if( opt
.list_sigs
&& node
->pkt
->pkttype
== PKT_SIGNATURE
) {
1263 PKT_signature
*sig
= node
->pkt
->pkt
.signature
;
1264 int sigrc
,fprokay
=0;
1267 byte fparray
[MAX_FINGERPRINT_LEN
];
1269 if( !any
) { /* no user id, (maybe a revocation follows)*/
1270 if( sig
->sig_class
== 0x20 )
1271 fputs("[revoked]:", stdout
);
1272 else if( sig
->sig_class
== 0x18 )
1273 fputs("[key binding]:", stdout
);
1274 else if( sig
->sig_class
== 0x28 )
1275 fputs("[subkey revoked]:", stdout
);
1279 print_capabilities (pk
, sk
, keyblock
);
1282 print_fingerprint( pk
, sk
, 0 );
1286 if( sig
->sig_class
== 0x20 || sig
->sig_class
== 0x28
1287 || sig
->sig_class
== 0x30 )
1289 else if( (sig
->sig_class
&~3) == 0x10 )
1291 else if( sig
->sig_class
== 0x18 )
1293 else if( sig
->sig_class
== 0x1F )
1296 printf ("sig::::::::::%02x%c:\n",
1297 sig
->sig_class
, sig
->flags
.exportable
?'x':'l');
1300 if( opt
.check_sigs
) {
1301 PKT_public_key
*signer_pk
=NULL
;
1304 if(opt
.no_sig_cache
)
1305 signer_pk
=xmalloc_clear(sizeof(PKT_public_key
));
1307 rc
= check_key_signature2( keyblock
, node
, NULL
, signer_pk
,
1309 switch ( gpg_err_code (rc
) ) {
1310 case 0: sigrc
= '!'; break;
1311 case GPG_ERR_BAD_SIGNATURE
: sigrc
= '-'; break;
1312 case GPG_ERR_NO_PUBKEY
:
1313 case GPG_ERR_UNUSABLE_PUBKEY
: sigrc
= '?'; break;
1314 default: sigrc
= '%'; break;
1317 if(opt
.no_sig_cache
)
1321 fingerprint_from_pk (signer_pk
, fparray
, &fplen
);
1324 free_public_key(signer_pk
);
1331 fputs( sigstr
, stdout
);
1335 printf("::%d:%08lX%08lX:%s:%s:", sig
->pubkey_algo
,
1336 (ulong
)sig
->keyid
[0], (ulong
)sig
->keyid
[1],
1337 colon_datestr_from_sig(sig
),
1338 colon_expirestr_from_sig(sig
));
1340 if(sig
->trust_depth
|| sig
->trust_value
)
1341 printf("%d %d",sig
->trust_depth
,sig
->trust_value
);
1344 if(sig
->trust_regexp
)
1345 print_string(stdout
,sig
->trust_regexp
,
1346 strlen(sig
->trust_regexp
),':');
1350 printf("[%s] ", g10_errstr(rc
) );
1351 else if( sigrc
== '?' )
1353 else if ( !opt
.fast_list_mode
) {
1355 char *p
= get_user_id( sig
->keyid
, &n
);
1356 print_string( stdout
, p
, n
, ':' );
1359 printf(":%02x%c:", sig
->sig_class
,sig
->flags
.exportable
?'x':'l');
1361 if(opt
.no_sig_cache
&& opt
.check_sigs
&& fprokay
)
1365 for (i
=0; i
< fplen
; i
++ )
1366 printf ("%02X", fparray
[i
] );
1373 if(opt
.show_subpackets
)
1374 print_subpackets_colon(sig
);
1376 /* fixme: check or list other sigs here */
1379 if( !any
) {/* oops, no user id */
1382 print_capabilities (pk
, sk
, keyblock
);
1388 * Reorder the keyblock so that the primary user ID (and not attribute
1389 * packet) comes first. Fixme: Replace this by a generic sort
1392 do_reorder_keyblock (KBNODE keyblock
,int attr
)
1394 KBNODE primary
= NULL
, primary0
= NULL
, primary2
= NULL
;
1397 for (node
=keyblock
; node
; primary0
=node
, node
= node
->next
) {
1398 if( node
->pkt
->pkttype
== PKT_USER_ID
&&
1399 ((attr
&& node
->pkt
->pkt
.user_id
->attrib_data
) ||
1400 (!attr
&& !node
->pkt
->pkt
.user_id
->attrib_data
)) &&
1401 node
->pkt
->pkt
.user_id
->is_primary
) {
1402 primary
= primary2
= node
;
1403 for (node
=node
->next
; node
; primary2
=node
, node
= node
->next
) {
1404 if( node
->pkt
->pkttype
== PKT_USER_ID
1405 || node
->pkt
->pkttype
== PKT_PUBLIC_SUBKEY
1406 || node
->pkt
->pkttype
== PKT_SECRET_SUBKEY
) {
1414 return; /* no primary key flag found (should not happen) */
1416 for (last
=NULL
, node
=keyblock
; node
; last
= node
, node
= node
->next
) {
1417 if( node
->pkt
->pkttype
== PKT_USER_ID
)
1421 assert (last
); /* the user ID is never the first packet */
1422 assert (primary0
); /* ditto (this is the node before primary) */
1423 if ( node
== primary
)
1424 return; /* already the first one */
1426 last
->next
= primary
;
1427 primary0
->next
= primary2
->next
;
1428 primary2
->next
= node
;
1432 reorder_keyblock (KBNODE keyblock
)
1434 do_reorder_keyblock(keyblock
,1);
1435 do_reorder_keyblock(keyblock
,0);
1439 list_keyblock( KBNODE keyblock
, int secret
, int fpr
, void *opaque
)
1441 reorder_keyblock (keyblock
);
1442 if (opt
.with_colons
)
1443 list_keyblock_colon (keyblock
, secret
, fpr
);
1445 list_keyblock_print (keyblock
, secret
, fpr
, opaque
);
1449 * standard function to print the finperprint.
1450 * mode 0: as used in key listings, opt.with_colons is honored
1451 * 1: print using log_info ()
1452 * 2: direct use of tty
1453 * 3: direct use of tty but only primary key.
1454 * modes 1 and 2 will try and print both subkey and primary key fingerprints
1457 print_fingerprint (PKT_public_key
*pk
, PKT_secret_key
*sk
, int mode
)
1459 byte array
[MAX_FINGERPRINT_LEN
], *p
;
1467 if(sk
->main_keyid
[0]==sk
->keyid
[0] && sk
->main_keyid
[1]==sk
->keyid
[1])
1472 if(pk
->main_keyid
[0]==pk
->keyid
[0] && pk
->main_keyid
[1]==pk
->keyid
[1])
1476 /* Just to be safe */
1477 if(mode
&0x80 && !primary
)
1479 log_error("primary key is not really primary!\n");
1485 if(!primary
&& (mode
==1 || mode
==2))
1489 PKT_secret_key
*primary_sk
=xmalloc_clear(sizeof(*primary_sk
));
1490 get_seckey(primary_sk
,sk
->main_keyid
);
1491 print_fingerprint(NULL
,primary_sk
,mode
|0x80);
1492 free_secret_key(primary_sk
);
1496 PKT_public_key
*primary_pk
=xmalloc_clear(sizeof(*primary_pk
));
1497 get_pubkey(primary_pk
,pk
->main_keyid
);
1498 print_fingerprint(primary_pk
,NULL
,mode
|0x80);
1499 free_public_key(primary_pk
);
1504 fp
= log_get_stream ();
1506 text
= _("Primary key fingerprint:");
1508 text
= _(" Subkey fingerprint:");
1510 else if (mode
== 2) {
1511 fp
= NULL
; /* use tty */
1513 /* TRANSLATORS: this should fit into 24 bytes to that the
1514 * fingerprint data is properly aligned with the user ID */
1515 text
= _(" Primary key fingerprint:");
1517 text
= _(" Subkey fingerprint:");
1519 else if (mode
== 3) {
1520 fp
= NULL
; /* use tty */
1521 text
= _(" Key fingerprint =");
1525 text
= _(" Key fingerprint =");
1529 fingerprint_from_sk (sk
, array
, &n
);
1531 fingerprint_from_pk (pk
, array
, &n
);
1533 if (opt
.with_colons
&& !mode
) {
1534 fprintf (fp
, "fpr:::::::::");
1535 for (i
=0; i
< n
; i
++, p
++ )
1536 fprintf (fp
, "%02X", *p
);
1543 tty_printf ("%s", text
);
1545 for (i
=0; i
< n
; i
++, i
++, p
+= 2 ) {
1549 fprintf (fp
, " %02X%02X", *p
, p
[1] );
1554 tty_printf (" %02X%02X", *p
, p
[1]);
1559 for (i
=0; i
< n
; i
++, p
++ ) {
1563 fprintf (fp
, " %02X", *p
);
1568 tty_printf (" %02X", *p
);
1579 /* Print the serial number of an OpenPGP card if available. */
1581 print_card_serialno (PKT_secret_key
*sk
)
1587 if (!sk
->is_protected
|| sk
->protect
.s2k
.mode
!= 1002)
1588 return; /* Not a card. */
1589 if (opt
.with_colons
)
1590 return; /* Handled elsewhere. */
1592 fputs (_(" Card serial no. ="), stdout
);
1594 if (sk
->protect
.ivlen
== 16
1595 && !memcmp (sk
->protect
.iv
, "\xD2\x76\x00\x01\x24\x01", 6) )
1596 { /* This is an OpenPGP card. Just print the relevant part. */
1597 for (i
=8; i
< 14; i
++)
1601 printf ("%02X", sk
->protect
.iv
[i
]);
1605 { /* Something is wrong: Print all. */
1606 for (i
=0; i
< sk
->protect
.ivlen
; i
++)
1607 printf ("%02X", sk
->protect
.iv
[i
]);
1614 void set_attrib_fd(int fd
)
1616 static int last_fd
=-1;
1618 if ( fd
!= -1 && last_fd
== fd
)
1621 if ( attrib_fp
&& attrib_fp
!= stdout
&& attrib_fp
!= stderr
)
1632 attrib_fp
= fdopen( fd
, "wb" );
1634 log_fatal("can't open fd %d for attribute output: %s\n",
1635 fd
, strerror(errno
));