~ubuntu-branches/ubuntu/precise/gnupg2/precise-proposed

« back to all changes in this revision

Viewing changes to sm/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
 
2
 * Copyright (C) 1998, 1999, 2000, 2001, 2003,
 
3
 *               2004 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 <unistd.h> 
 
28
#include <time.h>
 
29
#include <assert.h>
 
30
 
 
31
#include "gpgsm.h"
 
32
 
 
33
#include <gcrypt.h>
 
34
#include <ksba.h>
 
35
 
 
36
#include "keydb.h"
 
37
#include "../kbx/keybox.h" /* for KEYBOX_FLAG_* */
 
38
#include "i18n.h"
 
39
 
 
40
struct list_external_parm_s {
 
41
  ctrl_t ctrl;
 
42
  FILE *fp;
 
43
  int print_header;
 
44
  int with_colons;
 
45
  int with_chain;
 
46
  int raw_mode;
 
47
};
 
48
 
 
49
 
 
50
/* This table is to map Extended Key Usage OIDs to human readable
 
51
   names.  */
 
52
struct {
 
53
  const char *oid;
 
54
  const char *name;
 
55
} key_purpose_map[] = {
 
56
  { "1.3.6.1.5.5.7.3.1",  "serverAuth" },
 
57
  { "1.3.6.1.5.5.7.3.2",  "clientAuth" },          
 
58
  { "1.3.6.1.5.5.7.3.3",  "codeSigning" },      
 
59
  { "1.3.6.1.5.5.7.3.4",  "emailProtection" },     
 
60
  { "1.3.6.1.5.5.7.3.5",  "ipsecEndSystem" }, 
 
61
  { "1.3.6.1.5.5.7.3.6",  "ipsecTunnel" },  
 
62
  { "1.3.6.1.5.5.7.3.7",  "ipsecUser" },     
 
63
  { "1.3.6.1.5.5.7.3.8",  "timeStamping" },       
 
64
  { "1.3.6.1.5.5.7.3.9",  "ocspSigning" },    
 
65
  { "1.3.6.1.5.5.7.3.10", "dvcs" },      
 
66
  { "1.3.6.1.5.5.7.3.11", "sbgpCertAAServerAuth" },
 
67
  { "1.3.6.1.5.5.7.3.13", "eapOverPPP" },
 
68
  { "1.3.6.1.5.5.7.3.14", "wlanSSID" },       
 
69
  { NULL, NULL }
 
70
};
 
71
 
 
72
 
 
73
/* A table mapping OIDs to a descriptive string. */
 
74
static struct {
 
75
  char *oid;
 
76
  char *name;
 
77
  unsigned int flag;
 
78
} oidtranstbl[] = {
 
79
 
 
80
  /* Algorithms. */
 
81
  { "1.2.840.10040.4.1", "dsa" },
 
82
  { "1.2.840.10040.4.3", "dsaWithSha1" },
 
83
 
 
84
  { "1.2.840.113549.1.1.1", "rsaEncryption" },
 
85
  { "1.2.840.113549.1.1.2", "md2WithRSAEncryption" },
 
86
  { "1.2.840.113549.1.1.3", "md4WithRSAEncryption" },
 
87
  { "1.2.840.113549.1.1.4", "md5WithRSAEncryption" },
 
88
  { "1.2.840.113549.1.1.5", "sha1WithRSAEncryption" },
 
89
  { "1.2.840.113549.1.1.7", "rsaOAEP" },
 
90
  { "1.2.840.113549.1.1.8", "rsaOAEP-MGF" },
 
91
  { "1.2.840.113549.1.1.9", "rsaOAEP-pSpecified" },
 
92
  { "1.2.840.113549.1.1.10", "rsaPSS" },
 
93
  { "1.2.840.113549.1.1.11", "sha256WithRSAEncryption" },
 
94
  { "1.2.840.113549.1.1.12", "sha384WithRSAEncryption" },
 
95
  { "1.2.840.113549.1.1.13", "sha512WithRSAEncryption" },
 
96
 
 
97
  { "1.3.14.3.2.26", "sha1" },
 
98
  { "1.3.14.3.2.29",  "sha-1WithRSAEncryption" },
 
99
  { "1.3.36.3.3.1.2", "rsaSignatureWithripemd160" },
 
100
 
 
101
 
 
102
  /* Telesec extensions. */
 
103
  { "0.2.262.1.10.12.0", "certExtensionLiabilityLimitationExt" },
 
104
  { "0.2.262.1.10.12.1", "telesecCertIdExt" },
 
105
  { "0.2.262.1.10.12.2", "telesecPolicyIdentifier" },
 
106
  { "0.2.262.1.10.12.3", "telesecPolicyQualifierID" },
 
107
  { "0.2.262.1.10.12.4", "telesecCRLFilteredExt" },
 
108
  { "0.2.262.1.10.12.5", "telesecCRLFilterExt"},
 
109
  { "0.2.262.1.10.12.6", "telesecNamingAuthorityExt" },
 
110
 
 
111
  /* PKIX private extensions. */
 
112
  { "1.3.6.1.5.5.7.1.1", "authorityInfoAccess" },
 
113
  { "1.3.6.1.5.5.7.1.2", "biometricInfo" },
 
114
  { "1.3.6.1.5.5.7.1.3", "qcStatements" },
 
115
  { "1.3.6.1.5.5.7.1.4", "acAuditIdentity" },
 
116
  { "1.3.6.1.5.5.7.1.5", "acTargeting" },
 
117
  { "1.3.6.1.5.5.7.1.6", "acAaControls" },
 
118
  { "1.3.6.1.5.5.7.1.7", "sbgp-ipAddrBlock" },
 
119
  { "1.3.6.1.5.5.7.1.8", "sbgp-autonomousSysNum" },
 
120
  { "1.3.6.1.5.5.7.1.9", "sbgp-routerIdentifier" },
 
121
  { "1.3.6.1.5.5.7.1.10", "acProxying" },
 
122
  { "1.3.6.1.5.5.7.1.11", "subjectInfoAccess" },
 
123
 
 
124
  /* X.509 id-ce */
 
125
  { "2.5.29.14", "subjectKeyIdentifier"},
 
126
  { "2.5.29.15", "keyUsage", 1 },
 
127
  { "2.5.29.16", "privateKeyUsagePeriod" },
 
128
  { "2.5.29.17", "subjectAltName", 1 },
 
129
  { "2.5.29.18", "issuerAltName", 1 },
 
130
  { "2.5.29.19", "basicConstraints", 1},
 
131
  { "2.5.29.20", "cRLNumber" },
 
132
  { "2.5.29.21", "cRLReason" },
 
133
  { "2.5.29.22", "expirationDate" },
 
134
  { "2.5.29.23", "instructionCode" }, 
 
135
  { "2.5.29.24", "invalidityDate" },
 
136
  { "2.5.29.27", "deltaCRLIndicator" },
 
137
  { "2.5.29.28", "issuingDistributionPoint" },
 
138
  { "2.5.29.29", "certificateIssuer" },
 
139
  { "2.5.29.30", "nameConstraints" },
 
140
  { "2.5.29.31", "cRLDistributionPoints", 1 },
 
141
  { "2.5.29.32", "certificatePolicies", 1 },
 
142
  { "2.5.29.32.0", "anyPolicy" },
 
143
  { "2.5.29.33", "policyMappings" },
 
144
  { "2.5.29.35", "authorityKeyIdentifier", 1 },
 
145
  { "2.5.29.36", "policyConstraints" },
 
146
  { "2.5.29.37", "extKeyUsage", 1 },
 
147
  { "2.5.29.46", "freshestCRL" },
 
148
  { "2.5.29.54", "inhibitAnyPolicy" },
 
149
 
 
150
  /* Netscape certificate extensions. */
 
151
  { "2.16.840.1.113730.1.1", "netscape-cert-type" },
 
152
  { "2.16.840.1.113730.1.2", "netscape-base-url" },
 
153
  { "2.16.840.1.113730.1.3", "netscape-revocation-url" },
 
154
  { "2.16.840.1.113730.1.4", "netscape-ca-revocation-url" },
 
155
  { "2.16.840.1.113730.1.7", "netscape-cert-renewal-url" },
 
156
  { "2.16.840.1.113730.1.8", "netscape-ca-policy-url" },
 
157
  { "2.16.840.1.113730.1.9", "netscape-homePage-url" },
 
158
  { "2.16.840.1.113730.1.10", "netscape-entitylogo" },
 
159
  { "2.16.840.1.113730.1.11", "netscape-userPicture" },
 
160
  { "2.16.840.1.113730.1.12", "netscape-ssl-server-name" },
 
161
  { "2.16.840.1.113730.1.13", "netscape-comment" },
 
162
 
 
163
  { NULL }
 
164
};
 
165
 
 
166
 
 
167
/* Return the description for OID; if no description is available 
 
168
   NULL is returned. */
 
169
static const char *
 
170
get_oid_desc (const char *oid, unsigned int *flag)
 
171
{
 
172
  int i;
 
173
 
 
174
  if (oid)
 
175
    for (i=0; oidtranstbl[i].oid; i++)
 
176
      if (!strcmp (oidtranstbl[i].oid, oid))
 
177
        {
 
178
          if (flag)
 
179
            *flag = oidtranstbl[i].flag;
 
180
          return oidtranstbl[i].name;
 
181
        }
 
182
  if (flag)
 
183
    *flag = 0;
 
184
  return NULL;
 
185
}
 
186
 
 
187
 
 
188
static void
 
189
print_key_data (ksba_cert_t cert, FILE *fp)
 
190
{
 
191
#if 0  
 
192
  int n = pk ? pubkey_get_npkey( pk->pubkey_algo ) : 0;
 
193
  int i;
 
194
 
 
195
  for(i=0; i < n; i++ ) 
 
196
    {
 
197
      fprintf (fp, "pkd:%d:%u:", i, mpi_get_nbits( pk->pkey[i] ) );
 
198
      mpi_print(stdout, pk->pkey[i], 1 );
 
199
      putchar(':');
 
200
      putchar('\n');
 
201
    }
 
202
#endif
 
203
}
 
204
 
 
205
static void
 
206
print_capabilities (ksba_cert_t cert, FILE *fp)
 
207
{
 
208
  gpg_error_t err;
 
209
  unsigned int use;
 
210
 
 
211
  err = ksba_cert_get_key_usage (cert, &use);
 
212
  if (gpg_err_code (err) == GPG_ERR_NO_DATA)
 
213
    {
 
214
      putc ('e', fp);
 
215
      putc ('s', fp);
 
216
      putc ('c', fp);
 
217
      putc ('E', fp);
 
218
      putc ('S', fp);
 
219
      putc ('C', fp);
 
220
      return;
 
221
    }
 
222
  if (err)
 
223
    { 
 
224
      log_error (_("error getting key usage information: %s\n"),
 
225
                 gpg_strerror (err));
 
226
      return;
 
227
    } 
 
228
 
 
229
  if ((use & (KSBA_KEYUSAGE_KEY_ENCIPHERMENT|KSBA_KEYUSAGE_DATA_ENCIPHERMENT)))
 
230
    putc ('e', fp);
 
231
  if ((use & (KSBA_KEYUSAGE_DIGITAL_SIGNATURE|KSBA_KEYUSAGE_NON_REPUDIATION)))
 
232
    putc ('s', fp);
 
233
  if ((use & KSBA_KEYUSAGE_KEY_CERT_SIGN))
 
234
    putc ('c', fp);
 
235
  if ((use & (KSBA_KEYUSAGE_KEY_ENCIPHERMENT|KSBA_KEYUSAGE_DATA_ENCIPHERMENT)))
 
236
    putc ('E', fp);
 
237
  if ((use & (KSBA_KEYUSAGE_DIGITAL_SIGNATURE|KSBA_KEYUSAGE_NON_REPUDIATION)))
 
238
    putc ('S', fp);
 
239
  if ((use & KSBA_KEYUSAGE_KEY_CERT_SIGN))
 
240
    putc ('C', fp);
 
241
}
 
242
 
 
243
 
 
244
static void
 
245
print_time (gnupg_isotime_t t, FILE *fp)
 
246
{
 
247
  if (!t || !*t)
 
248
    ;
 
249
  else 
 
250
    fputs (t, fp);
 
251
}
 
252
 
 
253
 
 
254
/* return an allocated string with the email address extracted from a
 
255
   DN */
 
256
static char *
 
257
email_kludge (const char *name)
 
258
{
 
259
  const unsigned char *p;
 
260
  unsigned char *buf;
 
261
  int n;
 
262
 
 
263
  if (strncmp (name, "1.2.840.113549.1.9.1=#", 22))
 
264
    return NULL;
 
265
  /* This looks pretty much like an email address in the subject's DN
 
266
     we use this to add an additional user ID entry.  This way,
 
267
     openSSL generated keys get a nicer and usable listing */
 
268
  name += 22;    
 
269
  for (n=0, p=name; hexdigitp (p) && hexdigitp (p+1); p +=2, n++)
 
270
    ;
 
271
  if (*p != '#' || !n)
 
272
    return NULL;
 
273
  buf = xtrymalloc (n+3);
 
274
  if (!buf)
 
275
    return NULL; /* oops, out of core */
 
276
  *buf = '<';
 
277
  for (n=1, p=name; *p != '#'; p +=2, n++)
 
278
    buf[n] = xtoi_2 (p);
 
279
  buf[n++] = '>';
 
280
  buf[n] = 0;
 
281
  return buf;
 
282
}
 
283
 
 
284
 
 
285
 
 
286
 
 
287
/* List one certificate in colon mode */
 
288
static void
 
289
list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity,
 
290
                 FILE *fp, int have_secret)
 
291
{
 
292
  int rc;
 
293
  int idx;
 
294
  char truststring[2];
 
295
  char *p;
 
296
  ksba_sexp_t sexp;
 
297
  char *fpr;
 
298
  ksba_isotime_t t;
 
299
  gpg_error_t valerr;
 
300
  int algo;
 
301
  unsigned int nbits;
 
302
  const char *chain_id;
 
303
  char *chain_id_buffer = NULL;
 
304
  int is_root = 0;
 
305
 
 
306
  if (ctrl->with_validation)
 
307
    valerr = gpgsm_validate_chain (ctrl, cert, NULL, 1, NULL, 0);
 
308
  else
 
309
    valerr = 0;
 
310
 
 
311
 
 
312
  /* We need to get the fingerprint and the chaining ID in advance. */
 
313
  fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
 
314
  {
 
315
    ksba_cert_t next;
 
316
 
 
317
    rc = gpgsm_walk_cert_chain (cert, &next);
 
318
    if (!rc) /* We known the issuer's certificate. */
 
319
      {
 
320
        p = gpgsm_get_fingerprint_hexstring (next, GCRY_MD_SHA1);
 
321
        chain_id_buffer = p;
 
322
        chain_id = chain_id_buffer;
 
323
        ksba_cert_release (next);
 
324
      }
 
325
    else if (rc == -1)  /* We have reached the root certificate. */
 
326
      {
 
327
        chain_id = fpr;
 
328
        is_root = 1;
 
329
      }
 
330
    else
 
331
      chain_id = NULL;
 
332
  }
 
333
 
 
334
 
 
335
  fputs (have_secret? "crs:":"crt:", fp);
 
336
 
 
337
  /* Note: We can't use multiple flags, like "ei", because the
 
338
     validation check does only return one error.  */
 
339
  truststring[0] = 0;
 
340
  truststring[1] = 0;
 
341
  if ((validity & VALIDITY_REVOKED)
 
342
      || gpg_err_code (valerr) == GPG_ERR_CERT_REVOKED)
 
343
    *truststring = 'r';
 
344
  else if (gpg_err_code (valerr) == GPG_ERR_CERT_EXPIRED)
 
345
    *truststring = 'e';
 
346
  else 
 
347
    {
 
348
      /* Lets also check whether the certificate under question
 
349
         expired.  This is merely a hack until we found a proper way
 
350
         to store the expiration flag in the keybox. */
 
351
      ksba_isotime_t current_time, not_after;
 
352
  
 
353
      gnupg_get_isotime (current_time);
 
354
      if (!opt.ignore_expiration
 
355
          && !ksba_cert_get_validity (cert, 1, not_after)
 
356
          && *not_after && strcmp (current_time, not_after) > 0 )
 
357
        *truststring = 'e';
 
358
      else if (valerr)
 
359
        *truststring = 'i';
 
360
    }
 
361
 
 
362
  /* Is we have no truststring yet (i.e. the certificate might be
 
363
     good) and this is a root certificate, we ask the agent whether
 
364
     this is a trusted root certificate. */
 
365
  if (!*truststring && is_root)
 
366
    {
 
367
      rc = gpgsm_agent_istrusted (ctrl, cert);
 
368
      if (!rc)
 
369
        *truststring = 'u';  /* Yes, we trust this one (ultimately). */
 
370
      else if (gpg_err_code (rc) == GPG_ERR_NOT_TRUSTED)
 
371
        *truststring = 'n';  /* No, we do not trust this one. */
 
372
      /* (in case of an error we can't tell anything.) */
 
373
    }
 
374
  
 
375
  if (*truststring)
 
376
    fputs (truststring, fp);
 
377
 
 
378
  algo = gpgsm_get_key_algo_info (cert, &nbits);
 
379
  fprintf (fp, ":%u:%d:%s:", nbits, algo, fpr+24);
 
380
 
 
381
  /* We assume --fixed-list-mode for gpgsm */
 
382
  ksba_cert_get_validity (cert, 0, t);
 
383
  print_time (t, fp);
 
384
  putc (':', fp);
 
385
  ksba_cert_get_validity (cert, 1, t);
 
386
  print_time ( t, fp);
 
387
  putc (':', fp);
 
388
  /* Field 8, serial number: */
 
389
  if ((sexp = ksba_cert_get_serial (cert)))
 
390
    {
 
391
      int len;
 
392
      const unsigned char *s = sexp;
 
393
      
 
394
      if (*s == '(')
 
395
        {
 
396
          s++;
 
397
          for (len=0; *s && *s != ':' && digitp (s); s++)
 
398
            len = len*10 + atoi_1 (s);
 
399
          if (*s == ':')
 
400
            for (s++; len; len--, s++)
 
401
              fprintf (fp,"%02X", *s);
 
402
        }
 
403
      xfree (sexp);
 
404
    }
 
405
  putc (':', fp);
 
406
  /* Field 9, ownertrust - not used here */
 
407
  putc (':', fp);
 
408
  /* field 10, old user ID - we use it here for the issuer DN */
 
409
  if ((p = ksba_cert_get_issuer (cert,0)))
 
410
    {
 
411
      print_sanitized_string (fp, p, ':');
 
412
      xfree (p);
 
413
    }
 
414
  putc (':', fp);
 
415
  /* Field 11, signature class - not used */ 
 
416
  putc (':', fp);
 
417
  /* Field 12, capabilities: */ 
 
418
  print_capabilities (cert, fp);
 
419
  putc (':', fp);
 
420
  putc ('\n', fp);
 
421
 
 
422
  /* FPR record */
 
423
  fprintf (fp, "fpr:::::::::%s:::", fpr);
 
424
  /* Print chaining ID (field 13)*/
 
425
  if (chain_id)
 
426
    fputs (chain_id, fp);
 
427
  putc (':', fp);
 
428
  putc ('\n', fp);
 
429
  xfree (fpr); fpr = NULL; chain_id = NULL;
 
430
  xfree (chain_id_buffer); chain_id_buffer = NULL;
 
431
 
 
432
  if (opt.with_key_data)
 
433
    {
 
434
      if ( (p = gpgsm_get_keygrip_hexstring (cert)))
 
435
        {
 
436
          fprintf (fp, "grp:::::::::%s:\n", p);
 
437
          xfree (p);
 
438
        }
 
439
      print_key_data (cert, fp);
 
440
    }
 
441
 
 
442
  for (idx=0; (p = ksba_cert_get_subject (cert,idx)); idx++)
 
443
    {
 
444
      fprintf (fp, "uid:%s::::::::", truststring);
 
445
      print_sanitized_string (fp, p, ':');
 
446
      putc (':', fp);
 
447
      putc (':', fp);
 
448
      putc ('\n', fp);
 
449
      if (!idx)
 
450
        {
 
451
          /* It would be better to get the faked email address from
 
452
             the keydb.  But as long as we don't have a way to pass
 
453
             the meta data back, we just check it the same way as the
 
454
             code used to create the keybox meta data does */
 
455
          char *pp = email_kludge (p);
 
456
          if (pp)
 
457
            {
 
458
              fprintf (fp, "uid:%s::::::::", truststring);
 
459
              print_sanitized_string (fp, pp, ':');
 
460
              putc (':', fp);
 
461
              putc (':', fp);
 
462
              putc ('\n', fp);
 
463
              xfree (pp);
 
464
            }
 
465
        }
 
466
      xfree (p);
 
467
    }
 
468
}
 
469
 
 
470
 
 
471
static void
 
472
print_name_raw (FILE *fp, const char *string)
 
473
{
 
474
  if (!string)
 
475
    fputs ("[error]", fp);
 
476
  else
 
477
    print_sanitized_string (fp, string, 0);
 
478
}
 
479
 
 
480
static void
 
481
print_names_raw (FILE *fp, int indent, ksba_name_t name)
 
482
{
 
483
  int idx;
 
484
  const char *s;
 
485
  int indent_all;
 
486
 
 
487
  if ((indent_all = (indent < 0)))
 
488
    indent = - indent;
 
489
 
 
490
  if (!name)
 
491
    {
 
492
      fputs ("none\n", fp);
 
493
      return;
 
494
    }
 
495
  
 
496
  for (idx=0; (s = ksba_name_enum (name, idx)); idx++)
 
497
    {
 
498
      char *p = ksba_name_get_uri (name, idx);
 
499
      printf ("%*s%s\n", idx||indent_all?indent:0, "", p?p:s);
 
500
      xfree (p);
 
501
    }
 
502
}
 
503
 
 
504
 
 
505
/* List one certificate in raw mode useful to have a closer look at
 
506
   the certificate.  This one does no beautification and only minimal
 
507
   output sanitation.  It is mainly useful for debugging. */
 
508
static void
 
509
list_cert_raw (ctrl_t ctrl, KEYDB_HANDLE hd,
 
510
               ksba_cert_t cert, FILE *fp, int have_secret,
 
511
               int with_validation)
 
512
{
 
513
  gpg_error_t err;
 
514
  size_t off, len;
 
515
  ksba_sexp_t sexp;
 
516
  char *dn;
 
517
  ksba_isotime_t t;
 
518
  int idx, i;
 
519
  int is_ca, chainlen;
 
520
  unsigned int kusage;
 
521
  char *string, *p, *pend;
 
522
  const char *oid, *s;
 
523
  ksba_name_t name, name2;
 
524
  unsigned int reason;
 
525
 
 
526
  sexp = ksba_cert_get_serial (cert);
 
527
  fputs ("Serial number: ", fp);
 
528
  gpgsm_print_serial (fp, sexp);
 
529
  ksba_free (sexp);
 
530
  putc ('\n', fp);
 
531
 
 
532
  dn = ksba_cert_get_issuer (cert, 0);
 
533
  fputs ("       Issuer: ", fp);
 
534
  print_name_raw (fp, dn);
 
535
  ksba_free (dn);
 
536
  putc ('\n', fp);
 
537
  for (idx=1; (dn = ksba_cert_get_issuer (cert, idx)); idx++)
 
538
    {
 
539
      fputs ("          aka: ", fp);
 
540
      print_name_raw (fp, dn);
 
541
      ksba_free (dn);
 
542
      putc ('\n', fp);
 
543
    }
 
544
 
 
545
  dn = ksba_cert_get_subject (cert, 0);
 
546
  fputs ("      Subject: ", fp);
 
547
  print_name_raw (fp, dn);
 
548
  ksba_free (dn);
 
549
  putc ('\n', fp);
 
550
  for (idx=1; (dn = ksba_cert_get_subject (cert, idx)); idx++)
 
551
    {
 
552
      fputs ("          aka: ", fp);
 
553
      print_name_raw (fp, dn);
 
554
      ksba_free (dn);
 
555
      putc ('\n', fp);
 
556
    }
 
557
 
 
558
  dn = gpgsm_get_fingerprint_string (cert, 0);
 
559
  fprintf (fp, "     sha1_fpr: %s\n", dn?dn:"error");
 
560
  xfree (dn);
 
561
 
 
562
  dn = gpgsm_get_fingerprint_string (cert, GCRY_MD_MD5);
 
563
  fprintf (fp, "      md5_fpr: %s\n", dn?dn:"error");
 
564
  xfree (dn);
 
565
 
 
566
  dn = gpgsm_get_keygrip_hexstring (cert);
 
567
  fprintf (fp, "      keygrip: %s\n", dn?dn:"error");
 
568
  xfree (dn);
 
569
 
 
570
  ksba_cert_get_validity (cert, 0, t);
 
571
  fputs ("    notBefore: ", fp);
 
572
  gpgsm_print_time (fp, t);
 
573
  putc ('\n', fp);
 
574
  fputs ("     notAfter: ", fp);
 
575
  ksba_cert_get_validity (cert, 1, t);
 
576
  gpgsm_print_time (fp, t);
 
577
  putc ('\n', fp);
 
578
 
 
579
  oid = ksba_cert_get_digest_algo (cert);
 
580
  s = get_oid_desc (oid, NULL);
 
581
  fprintf (fp, "     hashAlgo: %s%s%s%s\n", oid, s?" (":"",s?s:"",s?")":"");
 
582
 
 
583
  {
 
584
    const char *algoname;
 
585
    unsigned int nbits;
 
586
 
 
587
    algoname = gcry_pk_algo_name (gpgsm_get_key_algo_info (cert, &nbits));
 
588
    fprintf (fp, "      keyType: %u bit %s\n",  nbits, algoname? algoname:"?");
 
589
  }
 
590
 
 
591
  /* authorityKeyIdentifier */
 
592
  fputs ("    authKeyId: ", fp);
 
593
  err = ksba_cert_get_auth_key_id (cert, NULL, &name, &sexp);
 
594
  if (!err || gpg_err_code (err) == GPG_ERR_NO_DATA)
 
595
    {
 
596
      if (gpg_err_code (err) == GPG_ERR_NO_DATA || !name)
 
597
        fputs ("[none]\n", fp);
 
598
      else
 
599
        {
 
600
          gpgsm_print_serial (fp, sexp);
 
601
          ksba_free (sexp);
 
602
          putc ('\n', fp);
 
603
          print_names_raw (fp, -15, name);
 
604
          ksba_name_release (name);
 
605
        }
 
606
    }
 
607
  else
 
608
    fputs ("[?]\n", fp);
 
609
 
 
610
  fputs ("     keyUsage:", fp);
 
611
  err = ksba_cert_get_key_usage (cert, &kusage);
 
612
  if (gpg_err_code (err) != GPG_ERR_NO_DATA)
 
613
    {
 
614
      if (err)
 
615
        fprintf (fp, " [error: %s]", gpg_strerror (err));
 
616
      else
 
617
        {
 
618
          if ( (kusage & KSBA_KEYUSAGE_DIGITAL_SIGNATURE))
 
619
            fputs (" digitalSignature", fp);
 
620
          if ( (kusage & KSBA_KEYUSAGE_NON_REPUDIATION))  
 
621
            fputs (" nonRepudiation", fp);
 
622
          if ( (kusage & KSBA_KEYUSAGE_KEY_ENCIPHERMENT)) 
 
623
            fputs (" keyEncipherment", fp);
 
624
          if ( (kusage & KSBA_KEYUSAGE_DATA_ENCIPHERMENT))
 
625
            fputs (" dataEncipherment", fp);
 
626
          if ( (kusage & KSBA_KEYUSAGE_KEY_AGREEMENT))    
 
627
            fputs (" keyAgreement", fp);
 
628
          if ( (kusage & KSBA_KEYUSAGE_KEY_CERT_SIGN))
 
629
            fputs (" certSign", fp);
 
630
          if ( (kusage & KSBA_KEYUSAGE_CRL_SIGN))  
 
631
            fputs (" crlSign", fp);
 
632
          if ( (kusage & KSBA_KEYUSAGE_ENCIPHER_ONLY))
 
633
            fputs (" encipherOnly", fp);
 
634
          if ( (kusage & KSBA_KEYUSAGE_DECIPHER_ONLY))  
 
635
            fputs (" decipherOnly", fp);
 
636
        }
 
637
      putc ('\n', fp);
 
638
    }
 
639
  else
 
640
    fputs ("[none]\n", fp);
 
641
 
 
642
  fputs ("  extKeyUsage: ", fp);
 
643
  err = ksba_cert_get_ext_key_usages (cert, &string);
 
644
  if (gpg_err_code (err) != GPG_ERR_NO_DATA)
 
645
    { 
 
646
      if (err)
 
647
        fprintf (fp, "[error: %s]", gpg_strerror (err));
 
648
      else
 
649
        {
 
650
          p = string;
 
651
          while (p && (pend=strchr (p, ':')))
 
652
            {
 
653
              *pend++ = 0;
 
654
              for (i=0; key_purpose_map[i].oid; i++)
 
655
                if ( !strcmp (key_purpose_map[i].oid, p) )
 
656
                  break;
 
657
              fputs (key_purpose_map[i].oid?key_purpose_map[i].name:p, fp);
 
658
              p = pend;
 
659
              if (*p != 'C')
 
660
                fputs (" (suggested)", fp);
 
661
              if ((p = strchr (p, '\n')))
 
662
                {
 
663
                  p++;
 
664
                  fputs ("\n               ", fp);
 
665
                }
 
666
            }
 
667
          xfree (string);
 
668
        }
 
669
      putc ('\n', fp);
 
670
    }
 
671
  else
 
672
    fputs ("[none]\n", fp);
 
673
 
 
674
 
 
675
  fputs ("     policies: ", fp);
 
676
  err = ksba_cert_get_cert_policies (cert, &string);
 
677
  if (gpg_err_code (err) != GPG_ERR_NO_DATA)
 
678
    {
 
679
      if (err)
 
680
        fprintf (fp, "[error: %s]", gpg_strerror (err));
 
681
      else
 
682
        {
 
683
          p = string;
 
684
          while (p && (pend=strchr (p, ':')))
 
685
            {
 
686
              *pend++ = 0;
 
687
              for (i=0; key_purpose_map[i].oid; i++)
 
688
                if ( !strcmp (key_purpose_map[i].oid, p) )
 
689
                  break;
 
690
              fputs (p, fp);
 
691
              p = pend;
 
692
              if (*p == 'C')
 
693
                fputs (" (critical)", fp);
 
694
              if ((p = strchr (p, '\n')))
 
695
                {
 
696
                  p++;
 
697
                  fputs ("\n               ", fp);
 
698
                }
 
699
            }
 
700
          xfree (string);
 
701
        }
 
702
      putc ('\n', fp);
 
703
    }
 
704
  else
 
705
    fputs ("[none]\n", fp);
 
706
 
 
707
  fputs ("  chainLength: ", fp);
 
708
  err = ksba_cert_is_ca (cert, &is_ca, &chainlen);
 
709
  if (err || is_ca)
 
710
    {
 
711
      if (err)
 
712
        fprintf (fp, "[error: %s]", gpg_strerror (err));
 
713
      else if (chainlen == -1)
 
714
        fputs ("unlimited", fp);
 
715
      else
 
716
        fprintf (fp, "%d", chainlen);
 
717
      putc ('\n', fp);
 
718
    }
 
719
  else
 
720
    fputs ("not a CA\n", fp);
 
721
 
 
722
 
 
723
  /* CRL distribution point */
 
724
  for (idx=0; !(err=ksba_cert_get_crl_dist_point (cert, idx, &name, &name2,
 
725
                                                  &reason)) ;idx++)
 
726
    {
 
727
      fputs ("        crlDP: ", fp);
 
728
      print_names_raw (fp, 15, name);
 
729
      if (reason)
 
730
        {
 
731
          fputs ("               reason: ", fp);
 
732
          if ( (reason & KSBA_CRLREASON_UNSPECIFIED))
 
733
            fputs (" unused", stdout);
 
734
          if ( (reason & KSBA_CRLREASON_KEY_COMPROMISE))
 
735
            fputs (" keyCompromise", stdout);
 
736
          if ( (reason & KSBA_CRLREASON_CA_COMPROMISE))
 
737
            fputs (" caCompromise", stdout);
 
738
          if ( (reason & KSBA_CRLREASON_AFFILIATION_CHANGED))
 
739
            fputs (" affiliationChanged", stdout);
 
740
          if ( (reason & KSBA_CRLREASON_SUPERSEDED))
 
741
            fputs (" superseded", stdout);
 
742
          if ( (reason & KSBA_CRLREASON_CESSATION_OF_OPERATION))
 
743
            fputs (" cessationOfOperation", stdout);
 
744
          if ( (reason & KSBA_CRLREASON_CERTIFICATE_HOLD))
 
745
            fputs (" certificateHold", stdout);
 
746
          putchar ('\n');
 
747
        }
 
748
      fputs ("               issuer: ", fp);
 
749
      print_names_raw (fp, 23, name2);
 
750
      ksba_name_release (name);
 
751
      ksba_name_release (name2);
 
752
    }
 
753
  if (err && gpg_err_code (err) != GPG_ERR_EOF)
 
754
    fputs ("        crlDP: [error]\n", fp);
 
755
  else if (!idx)
 
756
    fputs ("        crlDP: [none]\n", fp);
 
757
 
 
758
 
 
759
  /* authorityInfoAccess. */
 
760
  for (idx=0; !(err=ksba_cert_get_authority_info_access (cert, idx, &string,
 
761
                                                         &name)); idx++)
 
762
    {
 
763
      fputs ("     authInfo: ", fp);
 
764
      s = get_oid_desc (string, NULL);
 
765
      fprintf (fp, "%s%s%s%s\n", string, s?" (":"", s?s:"", s?")":"");
 
766
      print_names_raw (fp, -15, name);
 
767
      ksba_name_release (name);
 
768
      ksba_free (string);
 
769
    }
 
770
  if (err && gpg_err_code (err) != GPG_ERR_EOF)
 
771
    fputs ("     authInfo: [error]\n", fp);
 
772
  else if (!idx)
 
773
    fputs ("     authInfo: [none]\n", fp);
 
774
 
 
775
  /* subjectInfoAccess. */
 
776
  for (idx=0; !(err=ksba_cert_get_subject_info_access (cert, idx, &string,
 
777
                                                         &name)); idx++)
 
778
    {
 
779
      fputs ("  subjectInfo: ", fp);
 
780
      s = get_oid_desc (string, NULL);
 
781
      fprintf (fp, "%s%s%s%s\n", string, s?" (":"", s?s:"", s?")":"");
 
782
      print_names_raw (fp, -15, name);
 
783
      ksba_name_release (name);
 
784
      ksba_free (string);
 
785
    }
 
786
  if (err && gpg_err_code (err) != GPG_ERR_EOF)
 
787
    fputs ("     subjInfo: [error]\n", fp);
 
788
  else if (!idx)
 
789
    fputs ("     subjInfo: [none]\n", fp);
 
790
 
 
791
 
 
792
  for (idx=0; !(err=ksba_cert_get_extension (cert, idx,
 
793
                                             &oid, &i, &off, &len));idx++)
 
794
    {
 
795
      unsigned int flag;
 
796
 
 
797
      s = get_oid_desc (oid, &flag);
 
798
 
 
799
      if (!(flag & 1))
 
800
        fprintf (fp, "     %s: %s%s%s%s  [%d octets]\n",
 
801
                 i? "critExtn":"    extn",
 
802
                 oid, s?" (":"", s?s:"", s?")":"", (int)len);
 
803
    }
 
804
 
 
805
 
 
806
  if (with_validation)
 
807
    {
 
808
      err = gpgsm_validate_chain (ctrl, cert, NULL, 1, fp, 0);
 
809
      if (!err)
 
810
        fprintf (fp, "  [certificate is good]\n");
 
811
      else
 
812
        fprintf (fp, "  [certificate is bad: %s]\n", gpg_strerror (err));
 
813
    }
 
814
 
 
815
  if (opt.with_ephemeral_keys && hd)
 
816
    {
 
817
      unsigned int blobflags;
 
818
 
 
819
      err = keydb_get_flags (hd, KEYBOX_FLAG_BLOB, 0, &blobflags);
 
820
      if (err)
 
821
        fprintf (fp, "  [error getting keyflags: %s]\n", gpg_strerror (err));
 
822
      else if ((blobflags & 2))
 
823
        fprintf (fp, "  [stored as ephemeral]\n");
 
824
    }
 
825
 
 
826
}
 
827
 
 
828
 
 
829
 
 
830
 
 
831
/* List one certificate in standard mode */
 
832
static void
 
833
list_cert_std (ctrl_t ctrl, ksba_cert_t cert, FILE *fp, int have_secret,
 
834
               int with_validation)
 
835
{
 
836
  gpg_error_t err;
 
837
  ksba_sexp_t sexp;
 
838
  char *dn;
 
839
  ksba_isotime_t t;
 
840
  int idx, i;
 
841
  int is_ca, chainlen;
 
842
  unsigned int kusage;
 
843
  char *string, *p, *pend;
 
844
 
 
845
  sexp = ksba_cert_get_serial (cert);
 
846
  fputs ("Serial number: ", fp);
 
847
  gpgsm_print_serial (fp, sexp);
 
848
  ksba_free (sexp);
 
849
  putc ('\n', fp);
 
850
 
 
851
  dn = ksba_cert_get_issuer (cert, 0);
 
852
  fputs ("       Issuer: ", fp);
 
853
  gpgsm_print_name (fp, dn);
 
854
  ksba_free (dn);
 
855
  putc ('\n', fp);
 
856
  for (idx=1; (dn = ksba_cert_get_issuer (cert, idx)); idx++)
 
857
    {
 
858
      fputs ("          aka: ", fp);
 
859
      gpgsm_print_name (fp, dn);
 
860
      ksba_free (dn);
 
861
      putc ('\n', fp);
 
862
    }
 
863
 
 
864
  dn = ksba_cert_get_subject (cert, 0);
 
865
  fputs ("      Subject: ", fp);
 
866
  gpgsm_print_name (fp, dn);
 
867
  ksba_free (dn);
 
868
  putc ('\n', fp);
 
869
  for (idx=1; (dn = ksba_cert_get_subject (cert, idx)); idx++)
 
870
    {
 
871
      fputs ("          aka: ", fp);
 
872
      gpgsm_print_name (fp, dn);
 
873
      ksba_free (dn);
 
874
      putc ('\n', fp);
 
875
    }
 
876
 
 
877
  ksba_cert_get_validity (cert, 0, t);
 
878
  fputs ("     validity: ", fp);
 
879
  gpgsm_print_time (fp, t);
 
880
  fputs (" through ", fp);
 
881
  ksba_cert_get_validity (cert, 1, t);
 
882
  gpgsm_print_time (fp, t);
 
883
  putc ('\n', fp);
 
884
 
 
885
 
 
886
  {
 
887
    const char *algoname;
 
888
    unsigned int nbits;
 
889
 
 
890
    algoname = gcry_pk_algo_name (gpgsm_get_key_algo_info (cert, &nbits));
 
891
    fprintf (fp, "     key type: %u bit %s\n", nbits, algoname? algoname:"?");
 
892
  }
 
893
 
 
894
 
 
895
  err = ksba_cert_get_key_usage (cert, &kusage);
 
896
  if (gpg_err_code (err) != GPG_ERR_NO_DATA)
 
897
    {
 
898
      fputs ("    key usage:", fp);
 
899
      if (err)
 
900
        fprintf (fp, " [error: %s]", gpg_strerror (err));
 
901
      else
 
902
        {
 
903
          if ( (kusage & KSBA_KEYUSAGE_DIGITAL_SIGNATURE))
 
904
            fputs (" digitalSignature", fp);
 
905
          if ( (kusage & KSBA_KEYUSAGE_NON_REPUDIATION))  
 
906
            fputs (" nonRepudiation", fp);
 
907
          if ( (kusage & KSBA_KEYUSAGE_KEY_ENCIPHERMENT)) 
 
908
            fputs (" keyEncipherment", fp);
 
909
          if ( (kusage & KSBA_KEYUSAGE_DATA_ENCIPHERMENT))
 
910
            fputs (" dataEncipherment", fp);
 
911
          if ( (kusage & KSBA_KEYUSAGE_KEY_AGREEMENT))    
 
912
            fputs (" keyAgreement", fp);
 
913
          if ( (kusage & KSBA_KEYUSAGE_KEY_CERT_SIGN))
 
914
            fputs (" certSign", fp);
 
915
          if ( (kusage & KSBA_KEYUSAGE_CRL_SIGN))  
 
916
            fputs (" crlSign", fp);
 
917
          if ( (kusage & KSBA_KEYUSAGE_ENCIPHER_ONLY))
 
918
            fputs (" encipherOnly", fp);
 
919
          if ( (kusage & KSBA_KEYUSAGE_DECIPHER_ONLY))  
 
920
            fputs (" decipherOnly", fp);
 
921
        }
 
922
      putc ('\n', fp);
 
923
    }
 
924
 
 
925
  err = ksba_cert_get_ext_key_usages (cert, &string);
 
926
  if (gpg_err_code (err) != GPG_ERR_NO_DATA)
 
927
    { 
 
928
      fputs ("ext key usage: ", fp);
 
929
      if (err)
 
930
        fprintf (fp, "[error: %s]", gpg_strerror (err));
 
931
      else
 
932
        {
 
933
          p = string;
 
934
          while (p && (pend=strchr (p, ':')))
 
935
            {
 
936
              *pend++ = 0;
 
937
              for (i=0; key_purpose_map[i].oid; i++)
 
938
                if ( !strcmp (key_purpose_map[i].oid, p) )
 
939
                  break;
 
940
              fputs (key_purpose_map[i].oid?key_purpose_map[i].name:p, fp);
 
941
              p = pend;
 
942
              if (*p != 'C')
 
943
                fputs (" (suggested)", fp);
 
944
              if ((p = strchr (p, '\n')))
 
945
                {
 
946
                  p++;
 
947
                  fputs (", ", fp);
 
948
                }
 
949
            }
 
950
          xfree (string);
 
951
        }
 
952
      putc ('\n', fp);
 
953
    }
 
954
 
 
955
  err = ksba_cert_get_cert_policies (cert, &string);
 
956
  if (gpg_err_code (err) != GPG_ERR_NO_DATA)
 
957
    {
 
958
      fputs ("     policies: ", fp);
 
959
      if (err)
 
960
        fprintf (fp, "[error: %s]", gpg_strerror (err));
 
961
      else
 
962
        {
 
963
          for (p=string; *p; p++)
 
964
            {
 
965
              if (*p == '\n')
 
966
                *p = ',';
 
967
            }
 
968
          print_sanitized_string (fp, string, 0);
 
969
          xfree (string);
 
970
        }
 
971
      putc ('\n', fp);
 
972
    }
 
973
 
 
974
  err = ksba_cert_is_ca (cert, &is_ca, &chainlen);
 
975
  if (err || is_ca)
 
976
    {
 
977
      fputs (" chain length: ", fp);
 
978
      if (err)
 
979
        fprintf (fp, "[error: %s]", gpg_strerror (err));
 
980
      else if (chainlen == -1)
 
981
        fputs ("unlimited", fp);
 
982
      else
 
983
        fprintf (fp, "%d", chainlen);
 
984
      putc ('\n', fp);
 
985
    }
 
986
 
 
987
  if (opt.with_md5_fingerprint)
 
988
    {
 
989
      dn = gpgsm_get_fingerprint_string (cert, GCRY_MD_MD5);
 
990
      fprintf (fp, "      md5 fpr: %s\n", dn?dn:"error");
 
991
      xfree (dn);
 
992
    }
 
993
 
 
994
  dn = gpgsm_get_fingerprint_string (cert, 0);
 
995
  fprintf (fp, "  fingerprint: %s\n", dn?dn:"error");
 
996
  xfree (dn);
 
997
 
 
998
  if (with_validation)
 
999
    {
 
1000
      err = gpgsm_validate_chain (ctrl, cert, NULL, 1, fp, 0);
 
1001
      if (!err)
 
1002
        fprintf (fp, "  [certificate is good]\n");
 
1003
      else
 
1004
        fprintf (fp, "  [certificate is bad: %s]\n", gpg_strerror (err));
 
1005
    }
 
1006
}
 
1007
 
 
1008
 
 
1009
/* Same as standard mode mode list all certifying certs too. */
 
1010
static void
 
1011
list_cert_chain (ctrl_t ctrl, KEYDB_HANDLE hd,
 
1012
                 ksba_cert_t cert, int raw_mode,
 
1013
                 FILE *fp, int with_validation)
 
1014
{
 
1015
  ksba_cert_t next = NULL;
 
1016
 
 
1017
  if (raw_mode)
 
1018
    list_cert_raw (ctrl, hd, cert, fp, 0, with_validation);
 
1019
  else
 
1020
    list_cert_std (ctrl, cert, fp, 0, with_validation);
 
1021
  ksba_cert_ref (cert);
 
1022
  while (!gpgsm_walk_cert_chain (cert, &next))
 
1023
    {
 
1024
      ksba_cert_release (cert);
 
1025
      fputs ("Certified by\n", fp);
 
1026
      if (raw_mode)
 
1027
        list_cert_raw (ctrl, hd, next, fp, 0, with_validation);
 
1028
      else
 
1029
        list_cert_std (ctrl, next, fp, 0, with_validation);
 
1030
      cert = next;
 
1031
    }
 
1032
  ksba_cert_release (cert);
 
1033
  putc ('\n', fp);
 
1034
}
 
1035
 
 
1036
 
 
1037
 
 
1038
/* List all internal keys or just the keys given as NAMES.  MODE is a
 
1039
   bit vector to specify what keys are to be included; see
 
1040
   gpgsm_list_keys (below) for details.  If RAW_MODE is true, the raw
 
1041
   output mode will be used intead of the standard beautified one.
 
1042
 */
 
1043
static gpg_error_t
 
1044
list_internal_keys (ctrl_t ctrl, STRLIST names, FILE *fp,
 
1045
                    unsigned int mode, int raw_mode)
 
1046
{
 
1047
  KEYDB_HANDLE hd;
 
1048
  KEYDB_SEARCH_DESC *desc = NULL;
 
1049
  STRLIST sl;
 
1050
  int ndesc;
 
1051
  ksba_cert_t cert = NULL;
 
1052
  gpg_error_t rc = 0;
 
1053
  const char *lastresname, *resname;
 
1054
  int have_secret;
 
1055
 
 
1056
  hd = keydb_new (0);
 
1057
  if (!hd)
 
1058
    {
 
1059
      log_error ("keydb_new failed\n");
 
1060
      rc = gpg_error (GPG_ERR_GENERAL);
 
1061
      goto leave;
 
1062
    }
 
1063
 
 
1064
  if (!names)
 
1065
    ndesc = 1;
 
1066
  else
 
1067
    {
 
1068
      for (sl=names, ndesc=0; sl; sl = sl->next, ndesc++) 
 
1069
        ;
 
1070
    }
 
1071
 
 
1072
  desc = xtrycalloc (ndesc, sizeof *desc);
 
1073
  if (!ndesc)
 
1074
    {
 
1075
      rc = gpg_error_from_errno (errno);
 
1076
      log_error ("out of core\n");
 
1077
      goto leave;
 
1078
    }
 
1079
 
 
1080
  if (!names)
 
1081
    desc[0].mode = KEYDB_SEARCH_MODE_FIRST;
 
1082
  else 
 
1083
    {
 
1084
      for (ndesc=0, sl=names; sl; sl = sl->next) 
 
1085
        {
 
1086
          rc = keydb_classify_name (sl->d, desc+ndesc);
 
1087
          if (rc)
 
1088
            {
 
1089
              log_error ("key `%s' not found: %s\n",
 
1090
                         sl->d, gpg_strerror (rc));
 
1091
              rc = 0;
 
1092
            }
 
1093
          else
 
1094
            ndesc++;
 
1095
        }
 
1096
      
 
1097
    }
 
1098
 
 
1099
  if (opt.with_ephemeral_keys)
 
1100
    keydb_set_ephemeral (hd, 1);
 
1101
 
 
1102
  /* It would be nice to see which of the given users did actually
 
1103
     match one in the keyring.  To implement this we need to have a
 
1104
     found flag for each entry in desc and to set this we must check
 
1105
     all those entries after a match to mark all matched one -
 
1106
     currently we stop at the first match.  To do this we need an
 
1107
     extra flag to enable this feature so */
 
1108
 
 
1109
  lastresname = NULL;
 
1110
  while (!(rc = keydb_search (hd, desc, ndesc)))
 
1111
    {
 
1112
      unsigned int validity;
 
1113
 
 
1114
      if (!names) 
 
1115
        desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
 
1116
 
 
1117
      rc = keydb_get_flags (hd, KEYBOX_FLAG_VALIDITY, 0, &validity);
 
1118
      if (rc)
 
1119
        {
 
1120
          log_error ("keydb_get_flags failed: %s\n", gpg_strerror (rc));
 
1121
          goto leave;
 
1122
        }
 
1123
      rc = keydb_get_cert (hd, &cert);
 
1124
      if (rc) 
 
1125
        {
 
1126
          log_error ("keydb_get_cert failed: %s\n", gpg_strerror (rc));
 
1127
          goto leave;
 
1128
        }
 
1129
      
 
1130
      resname = keydb_get_resource_name (hd);
 
1131
      
 
1132
      if (lastresname != resname ) 
 
1133
        {
 
1134
          int i;
 
1135
          
 
1136
          if (ctrl->no_server)
 
1137
            {
 
1138
              fprintf (fp, "%s\n", resname );
 
1139
              for (i=strlen(resname); i; i-- )
 
1140
                putchar('-');
 
1141
              putc ('\n', fp);
 
1142
              lastresname = resname;
 
1143
            }
 
1144
        }
 
1145
 
 
1146
      have_secret = 0;
 
1147
      if (mode)
 
1148
        {
 
1149
          char *p = gpgsm_get_keygrip_hexstring (cert);
 
1150
          if (p)
 
1151
            {
 
1152
              rc = gpgsm_agent_havekey (ctrl, p); 
 
1153
             if (!rc)
 
1154
                have_secret = 1;
 
1155
              else if ( gpg_err_code (rc) != GPG_ERR_NO_SECKEY)
 
1156
                goto leave;
 
1157
              rc = 0;
 
1158
              xfree (p);
 
1159
            }
 
1160
        }
 
1161
 
 
1162
      if (!mode
 
1163
          || ((mode & 1) && !have_secret)
 
1164
          || ((mode & 2) && have_secret)  )
 
1165
        {
 
1166
          if (ctrl->with_colons)
 
1167
            list_cert_colon (ctrl, cert, validity, fp, have_secret);
 
1168
          else if (ctrl->with_chain)
 
1169
            list_cert_chain (ctrl, hd, cert,
 
1170
                             raw_mode, fp, ctrl->with_validation);
 
1171
          else
 
1172
            {
 
1173
              if (raw_mode)
 
1174
                list_cert_raw (ctrl, hd, cert, fp, have_secret,
 
1175
                               ctrl->with_validation);
 
1176
              else
 
1177
                list_cert_std (ctrl, cert, fp, have_secret,
 
1178
                               ctrl->with_validation);
 
1179
              putc ('\n', fp);
 
1180
            }
 
1181
        }
 
1182
      ksba_cert_release (cert); 
 
1183
      cert = NULL;
 
1184
    }
 
1185
  if (gpg_err_code (rc) == GPG_ERR_EOF || rc == -1 )
 
1186
    rc = 0;
 
1187
  if (rc)
 
1188
    log_error ("keydb_search failed: %s\n", gpg_strerror (rc));
 
1189
  
 
1190
 leave:
 
1191
  ksba_cert_release (cert);
 
1192
  xfree (desc);
 
1193
  keydb_release (hd);
 
1194
  return rc;
 
1195
}
 
1196
 
 
1197
 
 
1198
 
 
1199
static void
 
1200
list_external_cb (void *cb_value, ksba_cert_t cert)
 
1201
{
 
1202
  struct list_external_parm_s *parm = cb_value;
 
1203
 
 
1204
  if (keydb_store_cert (cert, 1, NULL))
 
1205
    log_error ("error storing certificate as ephemeral\n");
 
1206
 
 
1207
  if (parm->print_header)
 
1208
    {
 
1209
      const char *resname = "[external keys]";
 
1210
      int i;
 
1211
 
 
1212
      fprintf (parm->fp, "%s\n", resname );
 
1213
      for (i=strlen(resname); i; i-- )
 
1214
        putchar('-');
 
1215
      putc ('\n', parm->fp);
 
1216
      parm->print_header = 0;
 
1217
    }
 
1218
 
 
1219
  if (parm->with_colons)
 
1220
    list_cert_colon (parm->ctrl, cert, 0, parm->fp, 0);
 
1221
  else if (parm->with_chain)
 
1222
    list_cert_chain (parm->ctrl, NULL, cert, parm->raw_mode, parm->fp, 0);
 
1223
  else
 
1224
    {
 
1225
      if (parm->raw_mode)
 
1226
        list_cert_raw (parm->ctrl, NULL, cert, parm->fp, 0, 0);
 
1227
      else
 
1228
        list_cert_std (parm->ctrl, cert, parm->fp, 0, 0);
 
1229
      putc ('\n', parm->fp);
 
1230
    }
 
1231
}
 
1232
 
 
1233
 
 
1234
/* List external keys similar to internal one.  Note: mode does not
 
1235
   make sense here because it would be unwise to list external secret
 
1236
   keys */
 
1237
static gpg_error_t
 
1238
list_external_keys (CTRL ctrl, STRLIST names, FILE *fp, int raw_mode)
 
1239
{
 
1240
  int rc;
 
1241
  struct list_external_parm_s parm;
 
1242
 
 
1243
  parm.fp = fp;
 
1244
  parm.ctrl = ctrl,
 
1245
  parm.print_header = ctrl->no_server;
 
1246
  parm.with_colons = ctrl->with_colons;
 
1247
  parm.with_chain = ctrl->with_chain;
 
1248
  parm.raw_mode  = raw_mode;
 
1249
 
 
1250
  rc = gpgsm_dirmngr_lookup (ctrl, names, list_external_cb, &parm);
 
1251
  if (rc)
 
1252
    log_error ("listing external keys failed: %s\n", gpg_strerror (rc));
 
1253
  return rc;
 
1254
}
 
1255
 
 
1256
/* List all keys or just the key given as NAMES.
 
1257
   MODE controls the operation mode: 
 
1258
    Bit 0-2:
 
1259
      0 = list all public keys but don't flag secret ones
 
1260
      1 = list only public keys
 
1261
      2 = list only secret keys
 
1262
      3 = list secret and public keys
 
1263
    Bit 6: list internal keys
 
1264
    Bit 7: list external keys
 
1265
    Bit 8: Do a raw format dump.
 
1266
 */
 
1267
gpg_error_t
 
1268
gpgsm_list_keys (CTRL ctrl, STRLIST names, FILE *fp, unsigned int mode)
 
1269
{
 
1270
  gpg_error_t err = 0;
 
1271
 
 
1272
  if ((mode & (1<<6)))
 
1273
    err = list_internal_keys (ctrl, names, fp, (mode & 3), (mode&256));
 
1274
  if (!err && (mode & (1<<7)))
 
1275
    err = list_external_keys (ctrl, names, fp, (mode&256)); 
 
1276
  return err;
 
1277
}