~ubuntu-branches/ubuntu/dapper/gnupg2/dapper

« back to all changes in this revision

Viewing changes to g10/keylist.c

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Mueller
  • Date: 2005-03-29 10:30:32 UTC
  • Revision ID: james.westby@ubuntu.com-20050329103032-sj42n2ain3ipx310
Tags: upstream-1.9.15
ImportĀ upstreamĀ versionĀ 1.9.15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* keylist.c - List all or selected keys
 
2
 * Copyright (C) 1998, 1999, 2000, 2001, 2002,
 
3
 *               2003 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 2 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, write to the Free Software
 
19
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 
20
 */
 
21
 
 
22
#include <config.h>
 
23
#include <stdio.h>
 
24
#include <stdlib.h>
 
25
#include <string.h>
 
26
#include <errno.h>
 
27
#include <assert.h>
 
28
 
 
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"
 
41
 
 
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);
 
45
 
 
46
struct sig_stats
 
47
{
 
48
  int inv_sigs;
 
49
  int no_key;
 
50
  int oth_err;
 
51
};
 
52
 
 
53
static FILE *attrib_fp=NULL;
 
54
 
 
55
/****************
 
56
 * List the keys
 
57
 * If list is NULL, all available keys are listed
 
58
 */
 
59
void
 
60
public_key_list( STRLIST list )
 
61
{
 
62
  if(opt.with_colons)
 
63
    {
 
64
      byte trust_model,marginals,completes,cert_depth;
 
65
      ulong created,nextcheck;
 
66
 
 
67
      read_trust_options(&trust_model,&created,&nextcheck,
 
68
                         &marginals,&completes,&cert_depth);
 
69
 
 
70
      printf("tru:");
 
71
 
 
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)
 
77
        {
 
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");
 
84
        }
 
85
 
 
86
      printf(":%d:%lu:%lu",trust_model,created,nextcheck);
 
87
 
 
88
      /* Only show marginals, completes, and cert_depth in the classic
 
89
         or PGP trust models since they are not meaningful
 
90
         otherwise. */
 
91
 
 
92
      if(trust_model==TM_PGP || trust_model==TM_CLASSIC)
 
93
        printf(":%d:%d:%d",marginals,completes,cert_depth);
 
94
 
 
95
      printf("\n");
 
96
    }
 
97
 
 
98
  if( !list )
 
99
    list_all(0);
 
100
  else
 
101
    list_one( list, 0 );
 
102
}
 
103
 
 
104
void
 
105
secret_key_list( STRLIST list )
 
106
{
 
107
    if( !list )
 
108
        list_all(1);
 
109
    else  /* List by user id */
 
110
        list_one( list, 1 );
 
111
}
 
112
 
 
113
void
 
114
print_seckey_info (PKT_secret_key *sk)
 
115
{
 
116
    u32 sk_keyid[2];
 
117
    size_t n;
 
118
    char *p;
 
119
 
 
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));
 
125
    
 
126
    p = get_user_id (sk_keyid, &n);
 
127
    tty_print_utf8_string (p, n);
 
128
    xfree (p);
 
129
 
 
130
    tty_printf ("\n");   
 
131
}
 
132
 
 
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)
 
138
{
 
139
  u32 pk_keyid[2];
 
140
  size_t n;
 
141
  char *p;
 
142
 
 
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));
 
154
 
 
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);
 
161
  
 
162
  if (fp)
 
163
    putc ('\n', fp);
 
164
  else
 
165
    tty_printf ("\n\n"); 
 
166
}
 
167
 
 
168
/*
 
169
  mode=0 for stdout.
 
170
  mode=1 for log_info + status messages
 
171
  mode=2 for status messages only
 
172
*/
 
173
 
 
174
void
 
175
show_policy_url(PKT_signature *sig,int indent,int mode)
 
176
{
 
177
  const byte *p;
 
178
  size_t len;
 
179
  int seq=0,crit;
 
180
  FILE *fp=mode?log_get_stream():stdout;
 
181
 
 
182
  while((p=enum_sig_subpkt(sig->hashed,SIGSUBPKT_POLICY,&len,&seq,&crit)))
 
183
    {
 
184
      if(mode!=2)
 
185
        {
 
186
          int i;
 
187
          char *str;
 
188
 
 
189
          for(i=0;i<indent;i++)
 
190
            putchar(' ');
 
191
 
 
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");
 
202
        }
 
203
 
 
204
      if(mode)
 
205
        write_status_buffer ( STATUS_POLICY_URL, p, len, 0 );
 
206
    }
 
207
}
 
208
 
 
209
 
 
210
/*
 
211
  mode=0 for stdout.
 
212
  mode=1 for log_info + status messages
 
213
  mode=2 for status messages only
 
214
*/
 
215
/* TODO: use this */
 
216
void
 
217
show_keyserver_url(PKT_signature *sig,int indent,int mode)
 
218
{
 
219
  const byte *p;
 
220
  size_t len;
 
221
  int seq=0,crit;
 
222
  FILE *fp=mode?log_get_stream():stdout;
 
223
 
 
224
  while((p=enum_sig_subpkt(sig->hashed,SIGSUBPKT_PREF_KS,&len,&seq,&crit)))
 
225
    {
 
226
      if(mode!=2)
 
227
        {
 
228
          int i;
 
229
          char *str;
 
230
 
 
231
          for(i=0;i<indent;i++)
 
232
            putchar(' ');
 
233
 
 
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");
 
244
        }
 
245
 
 
246
      /* TODO: put in a status-fd tag for preferred keyservers */
 
247
    }
 
248
}
 
249
 
 
250
 
 
251
/*
 
252
  mode=0 for stdout.
 
253
  mode=1 for log_info + status messages
 
254
  mode=2 for status messages only
 
255
*/
 
256
 
 
257
void
 
258
show_notation(PKT_signature *sig,int indent,int mode)
 
259
{
 
260
  const byte *p;
 
261
  size_t len;
 
262
  int seq=0,crit;
 
263
  FILE *fp=mode?log_get_stream():stdout;
 
264
 
 
265
  /* There may be multiple notations in the same sig. */
 
266
 
 
267
  while((p=enum_sig_subpkt(sig->hashed,SIGSUBPKT_NOTATION,&len,&seq,&crit)))
 
268
    if(len>=8)
 
269
      {
 
270
        int n1,n2;
 
271
 
 
272
        n1=(p[4]<<8)|p[5];
 
273
        n2=(p[6]<<8)|p[7];
 
274
 
 
275
        if(8+n1+n2!=len)
 
276
          {
 
277
            log_info(_("WARNING: invalid notation data found\n"));
 
278
            return;
 
279
          }
 
280
 
 
281
        if(mode!=2)
 
282
          {
 
283
            int i;
 
284
            char *str;
 
285
 
 
286
            for(i=0;i<indent;i++)
 
287
              putchar(' ');
 
288
 
 
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,"=");
 
300
 
 
301
            if(*p&0x80)
 
302
              print_utf8_string(fp,p+8+n1,n2);
 
303
            else
 
304
              fprintf(fp,"[ %s ]",_("not human readable"));
 
305
 
 
306
            fprintf(fp,"\n");
 
307
          }
 
308
 
 
309
        if(mode)
 
310
          {
 
311
            write_status_buffer ( STATUS_NOTATION_NAME, p+8   , n1, 0 );
 
312
            write_status_buffer ( STATUS_NOTATION_DATA, p+8+n1, n2, 50 );
 
313
          }
 
314
      }
 
315
  else
 
316
    log_info(_("WARNING: invalid notation data found\n"));
 
317
}
 
318
 
 
319
static void
 
320
print_signature_stats(struct sig_stats *s)
 
321
{
 
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 );
 
334
}
 
335
 
 
336
static void
 
337
list_all( int secret )
 
338
{
 
339
    KEYDB_HANDLE hd;
 
340
    KBNODE keyblock = NULL;
 
341
    int rc=0;
 
342
    const char *lastresname, *resname;
 
343
    struct sig_stats stats;
 
344
 
 
345
    memset(&stats,0,sizeof(stats));
 
346
 
 
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;
 
356
    }
 
357
 
 
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;
 
364
        }
 
365
        if(!opt.with_colons)
 
366
          {
 
367
            resname = keydb_get_resource_name (hd);
 
368
            if (lastresname != resname )
 
369
              {
 
370
                int i;
 
371
 
 
372
                printf("%s\n", resname );
 
373
                for(i=strlen(resname); i; i-- )
 
374
                  putchar('-');
 
375
                putchar('\n');
 
376
                lastresname = resname;
 
377
              }
 
378
          }
 
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));
 
387
 
 
388
    if(opt.check_sigs && !opt.with_colons)
 
389
      print_signature_stats(&stats);
 
390
 
 
391
  leave:
 
392
    release_kbnode (keyblock);
 
393
    keydb_release (hd);
 
394
}
 
395
 
 
396
 
 
397
static void
 
398
list_one( STRLIST names, int secret )
 
399
{
 
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;
 
407
 
 
408
    memset(&stats,0,sizeof(stats));
 
409
 
 
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;
 
425
        }
 
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');
 
433
            }
 
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 );
 
438
    }
 
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;
 
445
        }
 
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');
 
453
            }
 
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 );
 
459
    }
 
460
 
 
461
    if(opt.check_sigs && !opt.with_colons)
 
462
      print_signature_stats(&stats);
 
463
}
 
464
 
 
465
static void
 
466
print_key_data( PKT_public_key *pk, u32 *keyid )
 
467
{
 
468
    int n = pk ? pubkey_get_npkey( pk->pubkey_algo ) : 0;
 
469
    int i;
 
470
 
 
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');
 
476
    }
 
477
}
 
478
 
 
479
static void
 
480
print_capabilities (PKT_public_key *pk, PKT_secret_key *sk, KBNODE keyblock)
 
481
{
 
482
  if(pk || (sk && sk->protect.s2k.mode!=1001))
 
483
    {
 
484
      unsigned int use = pk? pk->pubkey_usage : sk->pubkey_usage;
 
485
    
 
486
      if ( (use & PUBKEY_USAGE_ENC) )
 
487
        putchar ('e');
 
488
 
 
489
      if ( (use & PUBKEY_USAGE_SIG) )
 
490
        {
 
491
          putchar ('s');
 
492
          if( pk? pk->is_primary : sk->is_primary )
 
493
            putchar ('c');
 
494
        }
 
495
 
 
496
      if ( (use & PUBKEY_USAGE_AUTH) )
 
497
        putchar ('a');
 
498
    }
 
499
 
 
500
    if ( keyblock ) { /* figure out the usable capabilities */
 
501
        KBNODE k;
 
502
        int enc=0, sign=0, cert=0, auth=0, disabled=0;
 
503
 
 
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;
 
508
 
 
509
                if(pk->is_primary)
 
510
                  disabled=pk_is_disabled(pk);
 
511
 
 
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) )
 
516
                      {
 
517
                        sign = 1;
 
518
                        if(pk->is_primary)
 
519
                          cert = 1;
 
520
                      }
 
521
                    if ( (pk->pubkey_usage & PUBKEY_USAGE_AUTH) )
 
522
                      auth = 1;
 
523
                }
 
524
            }
 
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) )
 
533
                      {
 
534
                        sign = 1;
 
535
                        if(sk->is_primary)
 
536
                          cert = 1;
 
537
                      }
 
538
                    if ( (sk->pubkey_usage & PUBKEY_USAGE_AUTH) )
 
539
                        auth = 1;
 
540
                }
 
541
            }
 
542
        }
 
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');
 
553
    }
 
554
 
 
555
    putchar(':');
 
556
}
 
557
 
 
558
void
 
559
dump_attribs(const PKT_user_id *uid,PKT_public_key *pk,PKT_secret_key *sk)
 
560
{
 
561
  int i;
 
562
 
 
563
  if(!attrib_fp)
 
564
    return;
 
565
 
 
566
  for(i=0;i<uid->numattribs;i++)
 
567
    {
 
568
      if(is_status_enabled())
 
569
        {
 
570
          byte array[MAX_FINGERPRINT_LEN], *p;
 
571
          char buf[(MAX_FINGERPRINT_LEN*2)+90];
 
572
          size_t j,n;
 
573
 
 
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();
 
580
 
 
581
          p = array;
 
582
          for(j=0; j < n ; j++, p++ )
 
583
            sprintf(buf+2*j, "%02X", *p );
 
584
 
 
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);
 
592
        }
 
593
 
 
594
      fwrite(uid->attribs[i].data,uid->attribs[i].len,1,attrib_fp);
 
595
    }
 
596
}
 
597
 
 
598
static void
 
599
list_keyblock_print ( KBNODE keyblock, int secret, int fpr, void *opaque )
 
600
{
 
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);
 
611
 
 
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;
 
618
    }
 
619
 
 
620
    if( secret )
 
621
      {
 
622
        pk = NULL;
 
623
        sk = node->pkt->pkt.secret_key;
 
624
        keyid_from_sk( sk, keyid );
 
625
 
 
626
        printf("sec%c  %4u%c/",(sk->protect.s2k.mode==1001)?'#':' ',
 
627
               nbits_from_sk( sk ),pubkey_letter( sk->pubkey_algo ));
 
628
 
 
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]);
 
633
 
 
634
        printf(" %s%s",datestr_from_sk( sk ),newformat?"":" " );
 
635
 
 
636
        if(newformat && sk->expiredate )
 
637
          printf(_(" [expires: %s]"), expirestr_from_sk( sk ) );
 
638
      }
 
639
    else
 
640
      {
 
641
        int validity;
 
642
        pk = node->pkt->pkt.public_key;
 
643
        sk = NULL;
 
644
        keyid_from_pk( pk, keyid );
 
645
 
 
646
        validity=get_validity(pk,NULL);
 
647
 
 
648
        printf("pub   %4u%c/",
 
649
               nbits_from_pk(pk),pubkey_letter(pk->pubkey_algo));
 
650
 
 
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]);
 
655
 
 
656
        printf(" %s%s",datestr_from_pk( pk ),newformat?"":" " );
 
657
 
 
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 ) );
 
662
 
 
663
        if(opt.list_options&LIST_SHOW_VALIDITY)
 
664
          printf(" [%s]",trust_value_to_string(validity));
 
665
      }
 
666
 
 
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; 
 
677
 
 
678
            if(attrib_fp && node->pkt->pkt.user_id->attrib_data!=NULL)
 
679
              dump_attribs(node->pkt->pkt.user_id,pk,sk);
 
680
 
 
681
            if(!any && newformat)
 
682
              printf("\n");
 
683
 
 
684
            if((opt.list_options&LIST_SHOW_VALIDITY) && pk)
 
685
              {
 
686
                const char *validity=
 
687
                trust_value_to_string(get_validity(pk,node->pkt->pkt.user_id));
 
688
 
 
689
                /* Includes the 3 spaces for [, ], and " ". */
 
690
                indent=((opt.list_options&LIST_SHOW_LONG_KEYID)?23:15)
 
691
                  -strlen(validity);
 
692
 
 
693
                if(indent<0)
 
694
                  indent=0;
 
695
 
 
696
                printf("uid%*s[%s] ",indent,"",validity);
 
697
              }
 
698
            else if(newformat)
 
699
              printf("uid%*s",26,"");
 
700
            else if(any)
 
701
              printf("uid%*s",29,"");
 
702
 
 
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);
 
707
 
 
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;
 
718
            }
 
719
 
 
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);
 
724
        }
 
725
        else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
 
726
            u32 keyid2[2];
 
727
            PKT_public_key *pk2 = node->pkt->pkt.public_key;
 
728
 
 
729
            if( !any ) {
 
730
                putchar('\n');
 
731
                if( fpr )
 
732
                    print_fingerprint( pk, sk, 0 ); /* of the main key */
 
733
                any = 1;
 
734
            }
 
735
 
 
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 );
 
751
        }
 
752
        else if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
 
753
            u32 keyid2[2];
 
754
            PKT_secret_key *sk2 = node->pkt->pkt.secret_key;
 
755
 
 
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;
 
762
            }
 
763
 
 
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 )
 
776
              {
 
777
                print_fingerprint( NULL, sk2, 0 );
 
778
                print_card_serialno (sk);
 
779
              }
 
780
        }
 
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;
 
785
 
 
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;
 
795
                }
 
796
 
 
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 */
 
800
 
 
801
            }
 
802
            else {
 
803
                rc = 0;
 
804
                sigrc = ' ';
 
805
            }
 
806
 
 
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;
 
824
            }
 
825
 
 
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;
 
839
            }
 
840
 
 
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 == '?' )
 
860
                ;
 
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);
 
866
            }
 
867
            putchar('\n');
 
868
 
 
869
            if(sig->flags.policy_url && (opt.list_options&LIST_SHOW_POLICY))
 
870
              show_policy_url(sig,3,0);
 
871
 
 
872
            if(sig->flags.notation && (opt.list_options&LIST_SHOW_NOTATION))
 
873
              show_notation(sig,3,0);
 
874
 
 
875
            if(sig->flags.pref_ks && (opt.list_options&LIST_SHOW_KEYSERVER))
 
876
              show_keyserver_url(sig,3,0);
 
877
 
 
878
            /* fixme: check or list other sigs here */
 
879
        }
 
880
    }
 
881
    putchar('\n');
 
882
}
 
883
 
 
884
 
 
885
static void
 
886
list_keyblock_colon( KBNODE keyblock, int secret, int fpr )
 
887
{
 
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;
 
897
 
 
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;
 
904
    }
 
905
 
 
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 */ );
 
917
    }
 
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 ) 
 
930
            ;
 
931
        else {
 
932
            trustletter = get_validity_info ( pk, NULL );
 
933
            if( trustletter == 'u' )
 
934
                ulti_hack = 1;
 
935
            putchar(trustletter);
 
936
        }
 
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(':');
 
949
    }
 
950
    
 
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;
 
962
    }
 
963
 
 
964
 
 
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);
 
970
            /*
 
971
             * Fixme: We need a is_valid flag here too 
 
972
             */
 
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;
 
989
 
 
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);
 
995
                }
 
996
 
 
997
                printf("%s:",colon_strtime(uid->created));
 
998
                printf("%s:",colon_strtime(uid->expiredate));
 
999
 
 
1000
                namehash_from_uid(uid);
 
1001
 
 
1002
                for(i=0; i < 20; i++ )
 
1003
                  printf("%02X",uid->namehash[i]);
 
1004
 
 
1005
                printf("::");
 
1006
            }
 
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;
 
1023
            }
 
1024
        }
 
1025
        else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
 
1026
            u32 keyid2[2];
 
1027
            PKT_public_key *pk2 = node->pkt->pkt.public_key;
 
1028
 
 
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;
 
1037
            }
 
1038
 
 
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 )
 
1048
                ;
 
1049
            else {
 
1050
                /* trustletter should always be defined here */
 
1051
                if(trustletter)
 
1052
                  printf("%c", trustletter );
 
1053
            }
 
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 */
 
1061
                                                );
 
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 );
 
1074
        }
 
1075
        else if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
 
1076
            u32 keyid2[2];
 
1077
            PKT_secret_key *sk2 = node->pkt->pkt.secret_key;
 
1078
 
 
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;
 
1087
            }
 
1088
 
 
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 );
 
1101
        }
 
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];
 
1108
 
 
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;
 
1124
            }
 
1125
 
 
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;
 
1139
            }
 
1140
            if( opt.check_sigs ) {
 
1141
                PKT_public_key *signer_pk=NULL;
 
1142
 
 
1143
                fflush(stdout);
 
1144
                if(opt.no_sig_cache)
 
1145
                  signer_pk = xcalloc (1, sizeof(PKT_public_key));
 
1146
 
 
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;
 
1155
                }
 
1156
 
 
1157
                if(opt.no_sig_cache)
 
1158
                  {
 
1159
                    if(!rc)
 
1160
                      {
 
1161
                        fingerprint_from_pk (signer_pk, fparray, &fplen);
 
1162
                        fprokay=1;
 
1163
                      }
 
1164
                    free_public_key(signer_pk);
 
1165
                  }
 
1166
            }
 
1167
            else {
 
1168
                rc = 0;
 
1169
                sigrc = ' ';
 
1170
            }
 
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));
 
1179
 
 
1180
            if(sig->trust_depth || sig->trust_value)
 
1181
              printf("%d %d",sig->trust_depth,sig->trust_value);
 
1182
            printf(":");
 
1183
 
 
1184
            if(sig->trust_regexp)
 
1185
              print_string(stdout,sig->trust_regexp,
 
1186
                           strlen(sig->trust_regexp),':');
 
1187
            printf(":");
 
1188
 
 
1189
            if( sigrc == '%' )
 
1190
                printf("[%s] ", gpg_strerror (rc) );
 
1191
            else if( sigrc == '?' )
 
1192
                ;
 
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);
 
1198
            }
 
1199
            printf(":%02x%c:", sig->sig_class,sig->flags.exportable?'x':'l');
 
1200
            if(opt.no_sig_cache && opt.check_sigs && fprokay)
 
1201
              {
 
1202
                size_t i;
 
1203
 
 
1204
                printf(":");
 
1205
 
 
1206
                for (i=0; i < fplen ; i++ )
 
1207
                  printf ("%02X", fparray[i] );
 
1208
 
 
1209
                printf(":");
 
1210
              }
 
1211
 
 
1212
            printf("\n");
 
1213
            /* fixme: check or list other sigs here */
 
1214
        }
 
1215
    }
 
1216
    if( !any ) {/* oops, no user id */
 
1217
        putchar(':');
 
1218
        putchar(':');
 
1219
        print_capabilities (pk, sk, keyblock);
 
1220
        putchar('\n');
 
1221
    }
 
1222
}
 
1223
 
 
1224
/*
 
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)
 
1230
{
 
1231
    KBNODE primary = NULL, primary0 = NULL, primary2 = NULL;
 
1232
    KBNODE last, node;
 
1233
 
 
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;
 
1244
                }
 
1245
            }
 
1246
            break;
 
1247
        }
 
1248
    }
 
1249
    if ( !primary )
 
1250
        return;  /* no primary key flag found (should not happen) */
 
1251
 
 
1252
    for (last=NULL, node=keyblock; node; last = node, node = node->next) {
 
1253
        if( node->pkt->pkttype == PKT_USER_ID )
 
1254
            break;
 
1255
    }
 
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 */
 
1261
 
 
1262
    last->next = primary;
 
1263
    primary0->next = primary2->next;
 
1264
    primary2->next = node;
 
1265
}
 
1266
 
 
1267
void
 
1268
list_keyblock( KBNODE keyblock, int secret, int fpr, void *opaque )
 
1269
{
 
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 );
 
1275
}
 
1276
 
 
1277
/*
 
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
 
1284
 */
 
1285
void
 
1286
print_fingerprint (PKT_public_key *pk, PKT_secret_key *sk, int mode )
 
1287
{
 
1288
    byte array[MAX_FINGERPRINT_LEN], *p;
 
1289
    size_t i, n;
 
1290
    FILE *fp;
 
1291
    const char *text;
 
1292
    int primary=0;
 
1293
 
 
1294
    if(sk)
 
1295
      {
 
1296
        if(sk->main_keyid[0]==sk->keyid[0] && sk->main_keyid[1]==sk->keyid[1])
 
1297
          primary=1;
 
1298
      }
 
1299
    else
 
1300
      {
 
1301
        if(pk->main_keyid[0]==pk->keyid[0] && pk->main_keyid[1]==pk->keyid[1])
 
1302
          primary=1;
 
1303
      }
 
1304
 
 
1305
    /* Just to be safe */
 
1306
    if(mode&0x80 && !primary)
 
1307
      {
 
1308
        log_error("primary key is not really primary!\n");
 
1309
        return;
 
1310
      }
 
1311
 
 
1312
    mode&=~0x80;
 
1313
 
 
1314
    if(!primary && (mode==1 || mode==2))
 
1315
      {
 
1316
        if(sk)
 
1317
          {
 
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);
 
1322
          }
 
1323
        else
 
1324
          {
 
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);
 
1329
          }
 
1330
      }
 
1331
 
 
1332
    if (mode == 1) {
 
1333
        fp = log_get_stream ();
 
1334
        if(primary)
 
1335
          text = _("Primary key fingerprint:");
 
1336
        else
 
1337
          text = _("     Subkey fingerprint:");
 
1338
    }
 
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:");
 
1347
    }
 
1348
    else if (mode == 3) {
 
1349
        fp = NULL; /* use tty */
 
1350
        text = _("      Key fingerprint =");
 
1351
    }
 
1352
    else {
 
1353
        fp = stdout;
 
1354
        text = _("      Key fingerprint =");
 
1355
    }
 
1356
  
 
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);
 
1367
    }
 
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] );
 
1379
                }
 
1380
                else {
 
1381
                    if (i == 10 )
 
1382
                        tty_printf (" ");
 
1383
                    tty_printf (" %02X%02X", *p, p[1]);
 
1384
                }
 
1385
            }
 
1386
        }
 
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 );
 
1393
                }
 
1394
                else {
 
1395
                    if (i && !(i%8) )
 
1396
                        tty_printf (" ");
 
1397
                    tty_printf (" %02X", *p );
 
1398
                }
 
1399
            }
 
1400
        }
 
1401
    }
 
1402
    if (fp)
 
1403
        putc ('\n', fp);
 
1404
    else
 
1405
        tty_printf ("\n");
 
1406
}
 
1407
 
 
1408
 
 
1409
/* Print the serial number of an OpenPGP card if available. */
 
1410
static void
 
1411
print_card_serialno (PKT_secret_key *sk)
 
1412
{
 
1413
  int i;
 
1414
 
 
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. */
 
1421
 
 
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++)
 
1428
        {
 
1429
          if (i == 10)
 
1430
            putchar (' ');
 
1431
          printf ("%02X", sk->protect.iv[i]);
 
1432
        }
 
1433
    }
 
1434
  else
 
1435
    { /* Something is wrong: Print all. */
 
1436
      for (i=0; i < sk->protect.ivlen; i++)
 
1437
        printf ("%02X", sk->protect.iv[i]);
 
1438
    }
 
1439
  putchar ('\n');
 
1440
}
 
1441
 
 
1442
void set_attrib_fd(int fd)
 
1443
{
 
1444
  static int last_fd=-1;
 
1445
 
 
1446
  if ( fd != -1 && last_fd == fd )
 
1447
    return;
 
1448
 
 
1449
  if ( attrib_fp && attrib_fp != stdout && attrib_fp != stderr )
 
1450
    fclose (attrib_fp);
 
1451
  attrib_fp = NULL;
 
1452
  if ( fd == -1 ) 
 
1453
    return;
 
1454
 
 
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));
 
1464
  }
 
1465
  last_fd = fd;
 
1466
}