2 * Copyright (C) 1998 Free Software Foundation, Inc.
4 * This file is part of GNUPG.
6 * GNUPG is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * GNUPG is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
38 static void list_all(int);
39 static void list_one(const char *name, int secret);
40 static void list_keyblock( KBNODE keyblock, int secret );
41 static void fingerprint( PKT_public_key *pk, PKT_secret_key *sk );
46 * If NNAMES is 0; all available keys are listed
49 public_key_list( int nnames, char **names )
53 else { /* List by user id */
54 for( ; nnames ; nnames--, names++ )
55 list_one( *names, 0 );
60 secret_key_list( int nnames, char **names )
64 else { /* List by user id */
65 for( ; nnames ; nnames--, names++ )
66 list_one( *names, 1 );
72 list_all( int secret )
75 KBNODE keyblock = NULL;
79 rc = enum_keyblocks( secret? 5:0, &kbpos, &keyblock );
82 log_error("enum_keyblocks(open) failed: %s\n", g10_errstr(rc) );
87 while( !(rc = enum_keyblocks( 1, &kbpos, &keyblock )) ) {
88 if( lastresno != kbpos.resno ) {
89 const char *s = keyblock_resource_name( &kbpos );
92 lastresno = kbpos.resno;
94 for(i=strlen(s); i; i-- )
98 merge_keys_and_selfsig( keyblock );
99 list_keyblock( keyblock, secret );
100 release_kbnode( keyblock ); keyblock = NULL;
104 log_error("enum_keyblocks(read) failed: %s\n", g10_errstr(rc));
107 enum_keyblocks( 2, &kbpos, &keyblock ); /* close */
108 release_kbnode( keyblock );
114 list_one( const char *name, int secret )
117 KBNODE keyblock = NULL;
122 rc = secret? find_secret_keyblock_byname( &kbpos, name )
123 : find_keyblock_byname( &kbpos, name );
125 log_error("%s: user not found\n", name );
129 rc = read_keyblock( &kbpos, &keyblock );
131 log_error("%s: keyblock read problem: %s\n", name, g10_errstr(rc) );
134 merge_keys_and_selfsig( keyblock );
135 list_keyblock( keyblock, secret );
136 release_kbnode( keyblock );
141 rc = get_pubkey_byname( &ctx, NULL, name, &keyblock );
143 log_error("%s: %s\n", name, g10_errstr(rc) );
144 get_pubkey_end( ctx );
148 list_keyblock( keyblock, 0 );
149 release_kbnode( keyblock );
150 } while( !get_pubkey_next( ctx, NULL, &keyblock ) );
151 get_pubkey_end( ctx );
157 list_keyblock( KBNODE keyblock, int secret )
168 /* get the keyid from the keyblock */
169 node = find_kbnode( keyblock, secret? PKT_SECRET_KEY : PKT_PUBLIC_KEY );
171 log_error("Oops; key lost!\n");
177 sk = node->pkt->pkt.secret_key;
178 keyid_from_sk( sk, keyid );
179 if( opt.with_colons )
180 printf("sec::%u:%d:%08lX%08lX:%s:%s:::",
183 (ulong)keyid[0],(ulong)keyid[1],
184 datestr_from_sk( sk ),
185 sk->expiredate? strtimestamp(sk->expiredate):""
186 /* fixme: add LID here */ );
188 printf("sec %4u%c/%08lX %s ", nbits_from_sk( sk ),
189 pubkey_letter( sk->pubkey_algo ),
191 datestr_from_sk( sk ) );
194 pk = node->pkt->pkt.public_key;
196 keyid_from_pk( pk, keyid );
197 if( opt.with_colons ) {
198 trustletter = query_trust_info( pk );
199 printf("pub:%c:%u:%d:%08lX%08lX:%s:%s:",
203 (ulong)keyid[0],(ulong)keyid[1],
204 datestr_from_pk( pk ),
205 pk->expiredate? strtimestamp(pk->expiredate):""
208 printf("%lu", pk->local_id );
211 putchar( get_ownertrust_info( pk->local_id ) );
215 printf("pub %4u%c/%08lX %s ", nbits_from_pk( pk ),
216 pubkey_letter( pk->pubkey_algo ),
218 datestr_from_pk( pk ) );
221 for( kbctx=NULL; (node=walk_kbnode( keyblock, &kbctx, 0)) ; ) {
222 if( node->pkt->pkttype == PKT_USER_ID ) {
224 if( opt.with_colons )
225 printf("uid:::::::::");
227 printf("uid%*s", 28, "");
229 print_string( stdout, node->pkt->pkt.user_id->name,
230 node->pkt->pkt.user_id->len, opt.with_colons );
231 if( opt.with_colons )
235 if( opt.fingerprint )
236 fingerprint( pk, sk );
240 else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
242 PKT_public_key *pk2 = node->pkt->pkt.public_key;
246 if( opt.fingerprint )
247 fingerprint( pk, sk ); /* of the main key */
253 keyid_from_pk( pk2, keyid2 );
254 if( opt.with_colons ) {
255 printf("sub:%c:%u:%d:%08lX%08lX:%s:%s:",
257 nbits_from_pk( pk2 ),
259 (ulong)keyid2[0],(ulong)keyid2[1],
260 datestr_from_pk( pk2 ),
261 pk2->expiredate? strtimestamp(pk2->expiredate):""
262 /* fixme: add LID and ownertrust here */
264 if( pk->local_id ) /* use the local_id of the main key??? */
265 printf("%lu", pk->local_id );
271 printf("sub %4u%c/%08lX %s\n", nbits_from_pk( pk2 ),
272 pubkey_letter( pk2->pubkey_algo ),
274 datestr_from_pk( pk2 ) );
275 if( opt.fingerprint > 1 )
276 fingerprint( pk2, NULL );
278 else if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
280 PKT_secret_key *sk2 = node->pkt->pkt.secret_key;
284 if( opt.fingerprint )
285 fingerprint( pk, sk ); /* of the main key */
289 keyid_from_sk( sk2, keyid2 );
290 if( opt.with_colons )
291 printf("ssb::%u:%d:%08lX%08lX:%s:%s:::\n",
292 nbits_from_sk( sk2 ),
294 (ulong)keyid2[0],(ulong)keyid2[1],
295 datestr_from_sk( sk2 ),
296 sk2->expiredate? strtimestamp(sk2->expiredate):""
300 printf("ssb %4u%c/%08lX %s\n", nbits_from_sk( sk2 ),
301 pubkey_letter( sk2->pubkey_algo ),
303 datestr_from_sk( sk2 ) );
304 if( opt.fingerprint > 1 )
305 fingerprint( NULL, sk2 );
308 else if( opt.list_sigs && node->pkt->pkttype == PKT_SIGNATURE ) {
309 PKT_signature *sig = node->pkt->pkt.signature;
312 if( !any ) { /* no user id, (maybe a revocation follows)*/
313 if( sig->sig_class == 0x20 )
315 else if( sig->sig_class == 0x18 )
316 puts("[key binding]");
319 if( opt.fingerprint )
320 fingerprint( pk, sk );
324 if( sig->sig_class == 0x20 || sig->sig_class == 0x30 )
325 fputs("rev", stdout);
326 else if( (sig->sig_class&~3) == 0x10 )
327 fputs("sig", stdout);
328 else if( sig->sig_class == 0x18 )
329 fputs("sig", stdout);
331 if( opt.with_colons )
332 printf("sig::::::::::%02x:\n",sig->sig_class );
335 "[unexpected signature class 0x%02x]\n",sig->sig_class );
338 if( opt.check_sigs ) {
340 rc = check_key_signature( keyblock, node, NULL );
342 case 0: sigrc = '!'; break;
343 case G10ERR_BAD_SIGN: sigrc = '-'; break;
344 case G10ERR_NO_PUBKEY: sigrc = '?'; break;
345 default: sigrc = '%'; break;
352 if( opt.with_colons ) {
356 printf(":::%08lX%08lX:%s::::", (ulong)sig->keyid[0],
357 (ulong)sig->keyid[1], datestr_from_sig(sig));
360 printf("%c %08lX %s ",
361 sigrc, (ulong)sig->keyid[1], datestr_from_sig(sig));
363 printf("[%s] ", g10_errstr(rc) );
364 else if( sigrc == '?' )
368 char *p = get_user_id( sig->keyid, &n );
369 print_string( stdout, p, n, opt.with_colons );
372 if( opt.with_colons )
373 printf(":%02x:", sig->sig_class );
375 /* FIXME: check or list other sigs here (subpkt PRIV_ADD_SIG)*/
378 if( !any ) {/* oops, no user id */
379 if( opt.with_colons )
388 fingerprint( PKT_public_key *pk, PKT_secret_key *sk )
393 p = array = pk? fingerprint_from_pk( pk, NULL, &n )
394 : fingerprint_from_sk( sk, NULL, &n );
395 if( opt.with_colons ) {
396 printf("fpr:::::::::");
397 for(i=0; i < n ; i++, p++ )
402 printf(" Key fingerprint =");
404 for(i=0; i < n ; i++, i++, p += 2 ) {
407 printf(" %02X%02X", *p, p[1] );
411 for(i=0; i < n ; i++, p++ ) {
414 printf(" %02X", *p );