Correct punctuation in the ChangeLog summary line.
[gnupg.git] / sm / keylist.c
1 /* keylist.c - Print certificates in various formats.
2  * Copyright (C) 1998, 1999, 2000, 2001, 2003,
3  *               2004, 2005, 2008, 2009 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 3 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, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <unistd.h>
27 #include <time.h>
28 #include <assert.h>
29
30 #include "gpgsm.h"
31
32 #include <gcrypt.h>
33 #include <ksba.h>
34
35 #include "keydb.h"
36 #include "../kbx/keybox.h" /* for KEYBOX_FLAG_* */
37 #include "i18n.h"
38 #include "tlv.h"
39
40 struct list_external_parm_s
41 {
42   ctrl_t ctrl;
43   estream_t fp;
44   int print_header;
45   int with_colons;
46   int with_chain;
47   int raw_mode;
48 };
49
50
51 /* This table is to map Extended Key Usage OIDs to human readable
52    names.  */
53 struct
54 {
55   const char *oid;
56   const char *name;
57 } key_purpose_map[] = {
58   { "1.3.6.1.5.5.7.3.1",  "serverAuth" },
59   { "1.3.6.1.5.5.7.3.2",  "clientAuth" },
60   { "1.3.6.1.5.5.7.3.3",  "codeSigning" },
61   { "1.3.6.1.5.5.7.3.4",  "emailProtection" },
62   { "1.3.6.1.5.5.7.3.5",  "ipsecEndSystem" },
63   { "1.3.6.1.5.5.7.3.6",  "ipsecTunnel" },
64   { "1.3.6.1.5.5.7.3.7",  "ipsecUser" },
65   { "1.3.6.1.5.5.7.3.8",  "timeStamping" },
66   { "1.3.6.1.5.5.7.3.9",  "ocspSigning" },
67   { "1.3.6.1.5.5.7.3.10", "dvcs" },
68   { "1.3.6.1.5.5.7.3.11", "sbgpCertAAServerAuth" },
69   { "1.3.6.1.5.5.7.3.13", "eapOverPPP" },
70   { "1.3.6.1.5.5.7.3.14", "wlanSSID" },
71
72   { "2.16.840.1.113730.4.1", "serverGatedCrypto.ns" }, /* Netscape. */
73   { "1.3.6.1.4.1.311.10.3.3", "serverGatedCrypto.ms"}, /* Microsoft. */
74
75   { "1.3.6.1.5.5.7.48.1.5", "ocspNoCheck" },
76
77   { NULL, NULL }
78 };
79
80
81 /* Do not print this extension in the list of extensions.  This is set
82    for oids which are already available via ksba fucntions. */
83 #define OID_FLAG_SKIP 1
84 /* The extension is a simple UTF8String and should be printed.  */
85 #define OID_FLAG_UTF8 2
86
87 /* A table mapping OIDs to a descriptive string. */
88 static struct
89 {
90   char *oid;
91   char *name;
92   unsigned int flag; /* A flag as described above.  */
93 } oidtranstbl[] = {
94
95   /* Algorithms. */
96   { "1.2.840.10040.4.1", "dsa" },
97   { "1.2.840.10040.4.3", "dsaWithSha1" },
98
99   { "1.2.840.113549.1.1.1", "rsaEncryption" },
100   { "1.2.840.113549.1.1.2", "md2WithRSAEncryption" },
101   { "1.2.840.113549.1.1.3", "md4WithRSAEncryption" },
102   { "1.2.840.113549.1.1.4", "md5WithRSAEncryption" },
103   { "1.2.840.113549.1.1.5", "sha1WithRSAEncryption" },
104   { "1.2.840.113549.1.1.7", "rsaOAEP" },
105   { "1.2.840.113549.1.1.8", "rsaOAEP-MGF" },
106   { "1.2.840.113549.1.1.9", "rsaOAEP-pSpecified" },
107   { "1.2.840.113549.1.1.10", "rsaPSS" },
108   { "1.2.840.113549.1.1.11", "sha256WithRSAEncryption" },
109   { "1.2.840.113549.1.1.12", "sha384WithRSAEncryption" },
110   { "1.2.840.113549.1.1.13", "sha512WithRSAEncryption" },
111
112   { "1.3.14.3.2.26", "sha1" },
113   { "1.3.14.3.2.29",  "sha-1WithRSAEncryption" },
114   { "1.3.36.3.3.1.2", "rsaSignatureWithripemd160" },
115
116
117   /* Telesec extensions. */
118   { "0.2.262.1.10.12.0", "certExtensionLiabilityLimitationExt" },
119   { "0.2.262.1.10.12.1", "telesecCertIdExt" },
120   { "0.2.262.1.10.12.2", "telesecPolicyIdentifier" },
121   { "0.2.262.1.10.12.3", "telesecPolicyQualifierID" },
122   { "0.2.262.1.10.12.4", "telesecCRLFilteredExt" },
123   { "0.2.262.1.10.12.5", "telesecCRLFilterExt"},
124   { "0.2.262.1.10.12.6", "telesecNamingAuthorityExt" },
125 #define OIDSTR_restriction \
126     "1.3.36.8.3.8"
127   { OIDSTR_restriction,      "restriction", OID_FLAG_UTF8 },
128
129
130   /* PKIX private extensions. */
131   { "1.3.6.1.5.5.7.1.1", "authorityInfoAccess" },
132   { "1.3.6.1.5.5.7.1.2", "biometricInfo" },
133   { "1.3.6.1.5.5.7.1.3", "qcStatements" },
134   { "1.3.6.1.5.5.7.1.4", "acAuditIdentity" },
135   { "1.3.6.1.5.5.7.1.5", "acTargeting" },
136   { "1.3.6.1.5.5.7.1.6", "acAaControls" },
137   { "1.3.6.1.5.5.7.1.7", "sbgp-ipAddrBlock" },
138   { "1.3.6.1.5.5.7.1.8", "sbgp-autonomousSysNum" },
139   { "1.3.6.1.5.5.7.1.9", "sbgp-routerIdentifier" },
140   { "1.3.6.1.5.5.7.1.10", "acProxying" },
141   { "1.3.6.1.5.5.7.1.11", "subjectInfoAccess" },
142
143   { "1.3.6.1.5.5.7.48.1", "ocsp" },
144   { "1.3.6.1.5.5.7.48.2", "caIssuers" },
145   { "1.3.6.1.5.5.7.48.3", "timeStamping" },
146   { "1.3.6.1.5.5.7.48.5", "caRepository" },
147
148   /* X.509 id-ce */
149   { "2.5.29.14", "subjectKeyIdentifier", OID_FLAG_SKIP},
150   { "2.5.29.15", "keyUsage", OID_FLAG_SKIP},
151   { "2.5.29.16", "privateKeyUsagePeriod" },
152   { "2.5.29.17", "subjectAltName", OID_FLAG_SKIP},
153   { "2.5.29.18", "issuerAltName", OID_FLAG_SKIP},
154   { "2.5.29.19", "basicConstraints", OID_FLAG_SKIP},
155   { "2.5.29.20", "cRLNumber" },
156   { "2.5.29.21", "cRLReason" },
157   { "2.5.29.22", "expirationDate" },
158   { "2.5.29.23", "instructionCode" },
159   { "2.5.29.24", "invalidityDate" },
160   { "2.5.29.27", "deltaCRLIndicator" },
161   { "2.5.29.28", "issuingDistributionPoint" },
162   { "2.5.29.29", "certificateIssuer" },
163   { "2.5.29.30", "nameConstraints" },
164   { "2.5.29.31", "cRLDistributionPoints", OID_FLAG_SKIP},
165   { "2.5.29.32", "certificatePolicies", OID_FLAG_SKIP},
166   { "2.5.29.32.0", "anyPolicy" },
167   { "2.5.29.33", "policyMappings" },
168   { "2.5.29.35", "authorityKeyIdentifier", OID_FLAG_SKIP},
169   { "2.5.29.36", "policyConstraints" },
170   { "2.5.29.37", "extKeyUsage", OID_FLAG_SKIP},
171   { "2.5.29.46", "freshestCRL" },
172   { "2.5.29.54", "inhibitAnyPolicy" },
173
174   /* Netscape certificate extensions. */
175   { "2.16.840.1.113730.1.1", "netscape-cert-type" },
176   { "2.16.840.1.113730.1.2", "netscape-base-url" },
177   { "2.16.840.1.113730.1.3", "netscape-revocation-url" },
178   { "2.16.840.1.113730.1.4", "netscape-ca-revocation-url" },
179   { "2.16.840.1.113730.1.7", "netscape-cert-renewal-url" },
180   { "2.16.840.1.113730.1.8", "netscape-ca-policy-url" },
181   { "2.16.840.1.113730.1.9", "netscape-homePage-url" },
182   { "2.16.840.1.113730.1.10", "netscape-entitylogo" },
183   { "2.16.840.1.113730.1.11", "netscape-userPicture" },
184   { "2.16.840.1.113730.1.12", "netscape-ssl-server-name" },
185   { "2.16.840.1.113730.1.13", "netscape-comment" },
186
187   /* GnuPG extensions */
188   { "1.3.6.1.4.1.11591.2.1.1", "pkaAddress" },
189   { "1.3.6.1.4.1.11591.2.2.1", "standaloneCertificate" },
190   { "1.3.6.1.4.1.11591.2.2.2", "wellKnownPrivateKey" },
191
192   /* Extensions used by the Bundesnetzagentur.  */
193   { "1.3.6.1.4.1.8301.3.5", "validityModel" },
194
195   { NULL }
196 };
197
198
199 /* Return the description for OID; if no description is available
200    NULL is returned. */
201 static const char *
202 get_oid_desc (const char *oid, unsigned int *flag)
203 {
204   int i;
205
206   if (oid)
207     for (i=0; oidtranstbl[i].oid; i++)
208       if (!strcmp (oidtranstbl[i].oid, oid))
209         {
210           if (flag)
211             *flag = oidtranstbl[i].flag;
212           return oidtranstbl[i].name;
213         }
214   if (flag)
215     *flag = 0;
216   return NULL;
217 }
218
219
220 static void
221 print_key_data (ksba_cert_t cert, estream_t fp)
222 {
223 #if 0
224   int n = pk ? pubkey_get_npkey( pk->pubkey_algo ) : 0;
225   int i;
226
227   for(i=0; i < n; i++ )
228     {
229       es_fprintf (fp, "pkd:%d:%u:", i, mpi_get_nbits( pk->pkey[i] ) );
230       mpi_print(stdout, pk->pkey[i], 1 );
231       putchar(':');
232       putchar('\n');
233     }
234 #else
235   (void)cert;
236   (void)fp;
237 #endif
238 }
239
240 static void
241 print_capabilities (ksba_cert_t cert, estream_t fp)
242 {
243   gpg_error_t err;
244   unsigned int use;
245   size_t buflen;
246   char buffer[1];
247
248   err = ksba_cert_get_user_data (cert, "is_qualified",
249                                  &buffer, sizeof (buffer), &buflen);
250   if (!err && buflen)
251     {
252       if (*buffer)
253         es_putc ('q', fp);
254     }
255   else if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
256     ; /* Don't know - will not get marked as 'q' */
257   else
258     log_debug ("get_user_data(is_qualified) failed: %s\n",
259                gpg_strerror (err));
260
261   err = ksba_cert_get_key_usage (cert, &use);
262   if (gpg_err_code (err) == GPG_ERR_NO_DATA)
263     {
264       es_putc ('e', fp);
265       es_putc ('s', fp);
266       es_putc ('c', fp);
267       es_putc ('E', fp);
268       es_putc ('S', fp);
269       es_putc ('C', fp);
270       return;
271     }
272   if (err)
273     {
274       log_error (_("error getting key usage information: %s\n"),
275                  gpg_strerror (err));
276       return;
277     }
278
279   if ((use & (KSBA_KEYUSAGE_KEY_ENCIPHERMENT|KSBA_KEYUSAGE_DATA_ENCIPHERMENT)))
280     es_putc ('e', fp);
281   if ((use & (KSBA_KEYUSAGE_DIGITAL_SIGNATURE|KSBA_KEYUSAGE_NON_REPUDIATION)))
282     es_putc ('s', fp);
283   if ((use & KSBA_KEYUSAGE_KEY_CERT_SIGN))
284     es_putc ('c', fp);
285   if ((use & (KSBA_KEYUSAGE_KEY_ENCIPHERMENT|KSBA_KEYUSAGE_DATA_ENCIPHERMENT)))
286     es_putc ('E', fp);
287   if ((use & (KSBA_KEYUSAGE_DIGITAL_SIGNATURE|KSBA_KEYUSAGE_NON_REPUDIATION)))
288     es_putc ('S', fp);
289   if ((use & KSBA_KEYUSAGE_KEY_CERT_SIGN))
290     es_putc ('C', fp);
291
292   es_putc (':', fp);
293 }
294
295
296 static void
297 print_time (gnupg_isotime_t t, estream_t fp)
298 {
299   if (!t || !*t)
300     ;
301   else
302     es_fputs (t, fp);
303 }
304
305
306 /* Return an allocated string with the email address extracted from a
307    DN.  Note hat we use this code also in ../kbx/keybox-blob.c.  */
308 static char *
309 email_kludge (const char *name)
310 {
311   const char *p, *string;
312   unsigned char *buf;
313   int n;
314
315   string = name;
316   for (;;)
317     {
318       p = strstr (string, "1.2.840.113549.1.9.1=#");
319       if (!p)
320         return NULL;
321       if (p == name || (p > string+1 && p[-1] == ',' && p[-2] != '\\'))
322         {
323           name = p + 22;
324           break;
325         }
326       string = p + 22;
327     }
328
329
330   /* This looks pretty much like an email address in the subject's DN
331      we use this to add an additional user ID entry.  This way,
332      OpenSSL generated keys get a nicer and usable listing.  */
333   for (n=0, p=name; hexdigitp (p) && hexdigitp (p+1); p +=2, n++)
334     ;
335   if (!n)
336     return NULL;
337   buf = xtrymalloc (n+3);
338   if (!buf)
339     return NULL; /* oops, out of core */
340   *buf = '<';
341   for (n=1, p=name; hexdigitp (p); p +=2, n++)
342     buf[n] = xtoi_2 (p);
343   buf[n++] = '>';
344   buf[n] = 0;
345   return (char*)buf;
346 }
347
348
349
350
351 /* List one certificate in colon mode */
352 static void
353 list_cert_colon (ctrl_t ctrl, ksba_cert_t cert, unsigned int validity,
354                  estream_t fp, int have_secret)
355 {
356   int rc;
357   int idx;
358   char truststring[2];
359   char *p;
360   ksba_sexp_t sexp;
361   char *fpr;
362   ksba_isotime_t t;
363   gpg_error_t valerr;
364   int algo;
365   unsigned int nbits;
366   const char *chain_id;
367   char *chain_id_buffer = NULL;
368   int is_root = 0;
369   char *kludge_uid;
370
371   if (ctrl->with_validation)
372     valerr = gpgsm_validate_chain (ctrl, cert, "", NULL, 1, NULL, 0, NULL);
373   else
374     valerr = 0;
375
376
377   /* We need to get the fingerprint and the chaining ID in advance. */
378   fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1);
379   {
380     ksba_cert_t next;
381
382     rc = gpgsm_walk_cert_chain (ctrl, cert, &next);
383     if (!rc) /* We known the issuer's certificate. */
384       {
385         p = gpgsm_get_fingerprint_hexstring (next, GCRY_MD_SHA1);
386         chain_id_buffer = p;
387         chain_id = chain_id_buffer;
388         ksba_cert_release (next);
389       }
390     else if (rc == -1)  /* We have reached the root certificate. */
391       {
392         chain_id = fpr;
393         is_root = 1;
394       }
395     else
396       chain_id = NULL;
397   }
398
399
400   es_fputs (have_secret? "crs:":"crt:", fp);
401
402   /* Note: We can't use multiple flags, like "ei", because the
403      validation check does only return one error.  */
404   truststring[0] = 0;
405   truststring[1] = 0;
406   if ((validity & VALIDITY_REVOKED)
407       || gpg_err_code (valerr) == GPG_ERR_CERT_REVOKED)
408     *truststring = 'r';
409   else if (gpg_err_code (valerr) == GPG_ERR_CERT_EXPIRED)
410     *truststring = 'e';
411   else
412     {
413       /* Lets also check whether the certificate under question
414          expired.  This is merely a hack until we found a proper way
415          to store the expiration flag in the keybox. */
416       ksba_isotime_t current_time, not_after;
417
418       gnupg_get_isotime (current_time);
419       if (!opt.ignore_expiration
420           && !ksba_cert_get_validity (cert, 1, not_after)
421           && *not_after && strcmp (current_time, not_after) > 0 )
422         *truststring = 'e';
423       else if (valerr)
424         *truststring = 'i';
425       else if (ctrl->with_validation && !is_root)
426         *truststring = 'f';
427     }
428
429   /* If we have no truststring yet (i.e. the certificate might be
430      good) and this is a root certificate, we ask the agent whether
431      this is a trusted root certificate. */
432   if (!*truststring && is_root)
433     {
434       struct rootca_flags_s dummy_flags;
435
436       rc = gpgsm_agent_istrusted (ctrl, cert, NULL, &dummy_flags);
437       if (!rc)
438         *truststring = 'u';  /* Yes, we trust this one (ultimately). */
439       else if (gpg_err_code (rc) == GPG_ERR_NOT_TRUSTED)
440         *truststring = 'n';  /* No, we do not trust this one. */
441       /* (in case of an error we can't tell anything.) */
442     }
443
444   if (*truststring)
445     es_fputs (truststring, fp);
446
447   algo = gpgsm_get_key_algo_info (cert, &nbits);
448   es_fprintf (fp, ":%u:%d:%s:", nbits, algo, fpr+24);
449
450   /* We assume --fixed-list-mode for gpgsm */
451   ksba_cert_get_validity (cert, 0, t);
452   print_time (t, fp);
453   es_putc (':', fp);
454   ksba_cert_get_validity (cert, 1, t);
455   print_time ( t, fp);
456   es_putc (':', fp);
457   /* Field 8, serial number: */
458   if ((sexp = ksba_cert_get_serial (cert)))
459     {
460       int len;
461       const unsigned char *s = sexp;
462
463       if (*s == '(')
464         {
465           s++;
466           for (len=0; *s && *s != ':' && digitp (s); s++)
467             len = len*10 + atoi_1 (s);
468           if (*s == ':')
469             for (s++; len; len--, s++)
470               es_fprintf (fp,"%02X", *s);
471         }
472       xfree (sexp);
473     }
474   es_putc (':', fp);
475   /* Field 9, ownertrust - not used here */
476   es_putc (':', fp);
477   /* field 10, old user ID - we use it here for the issuer DN */
478   if ((p = ksba_cert_get_issuer (cert,0)))
479     {
480       es_write_sanitized (fp, p, strlen (p), ":", NULL);
481       xfree (p);
482     }
483   es_putc (':', fp);
484   /* Field 11, signature class - not used */
485   es_putc (':', fp);
486   /* Field 12, capabilities: */
487   print_capabilities (cert, fp);
488   /* Field 13, not used: */
489   es_putc (':', fp);
490   if (have_secret)
491     {
492       char *cardsn;
493
494       p = gpgsm_get_keygrip_hexstring (cert);
495       if (!gpgsm_agent_keyinfo (ctrl, p, &cardsn) && cardsn)
496         {
497           /* Field 14, not used: */
498           es_putc (':', fp);
499           /* Field 15:  Token serial number.  */
500           es_fputs (cardsn, fp);
501           es_putc (':', fp);
502         }
503       xfree (cardsn);
504       xfree (p);
505     }
506   es_putc ('\n', fp);
507
508   /* FPR record */
509   es_fprintf (fp, "fpr:::::::::%s:::", fpr);
510   /* Print chaining ID (field 13)*/
511   if (chain_id)
512     es_fputs (chain_id, fp);
513   es_putc (':', fp);
514   es_putc ('\n', fp);
515   xfree (fpr); fpr = NULL; chain_id = NULL;
516   xfree (chain_id_buffer); chain_id_buffer = NULL;
517
518   if (opt.with_key_data)
519     {
520       if ( (p = gpgsm_get_keygrip_hexstring (cert)))
521         {
522           es_fprintf (fp, "grp:::::::::%s:\n", p);
523           xfree (p);
524         }
525       print_key_data (cert, fp);
526     }
527
528   kludge_uid = NULL;
529   for (idx=0; (p = ksba_cert_get_subject (cert,idx)); idx++)
530     {
531       /* In the case that the same email address is in the subject DN
532          as well as in an alternate subject name we avoid printing it
533          a second time. */
534       if (kludge_uid && !strcmp (kludge_uid, p))
535         continue;
536
537       es_fprintf (fp, "uid:%s::::::::", truststring);
538       es_write_sanitized (fp, p, strlen (p), ":", NULL);
539       es_putc (':', fp);
540       es_putc (':', fp);
541       es_putc ('\n', fp);
542       if (!idx)
543         {
544           /* It would be better to get the faked email address from
545              the keydb.  But as long as we don't have a way to pass
546              the meta data back, we just check it the same way as the
547              code used to create the keybox meta data does */
548           kludge_uid = email_kludge (p);
549           if (kludge_uid)
550             {
551               es_fprintf (fp, "uid:%s::::::::", truststring);
552               es_write_sanitized (fp, kludge_uid, strlen (kludge_uid),
553                                   ":", NULL);
554               es_putc (':', fp);
555               es_putc (':', fp);
556               es_putc ('\n', fp);
557             }
558         }
559       xfree (p);
560     }
561   xfree (kludge_uid);
562 }
563
564
565 static void
566 print_name_raw (estream_t fp, const char *string)
567 {
568   if (!string)
569     es_fputs ("[error]", fp);
570   else
571     es_write_sanitized (fp, string, strlen (string), NULL, NULL);
572 }
573
574 static void
575 print_names_raw (estream_t fp, int indent, ksba_name_t name)
576 {
577   int idx;
578   const char *s;
579   int indent_all;
580
581   if ((indent_all = (indent < 0)))
582     indent = - indent;
583
584   if (!name)
585     {
586       es_fputs ("none\n", fp);
587       return;
588     }
589
590   for (idx=0; (s = ksba_name_enum (name, idx)); idx++)
591     {
592       char *p = ksba_name_get_uri (name, idx);
593       es_fprintf (fp, "%*s", idx||indent_all?indent:0, "");
594       es_write_sanitized (fp, p?p:s, strlen (p?p:s), NULL, NULL);
595       es_putc ('\n', fp);
596       xfree (p);
597     }
598 }
599
600
601 static void
602 print_utf8_extn_raw (estream_t fp, int indent,
603                      const unsigned char *der, size_t derlen)
604 {
605   gpg_error_t err;
606   int class, tag, constructed, ndef;
607   size_t objlen, hdrlen;
608
609   if (indent < 0)
610     indent = - indent;
611
612   err = parse_ber_header (&der, &derlen, &class, &tag, &constructed,
613                           &ndef, &objlen, &hdrlen);
614   if (!err && (objlen > derlen || tag != TAG_UTF8_STRING))
615     err = gpg_error (GPG_ERR_INV_OBJ);
616   if (err)
617     {
618       es_fprintf (fp, "%*s[%s]\n", indent, "", gpg_strerror (err));
619       return;
620     }
621   es_fprintf (fp, "%*s(%.*s)\n", indent, "", (int)objlen, der);
622 }
623
624
625 static void
626 print_utf8_extn (estream_t fp, int indent,
627                  const unsigned char *der, size_t derlen)
628 {
629   gpg_error_t err;
630   int class, tag, constructed, ndef;
631   size_t objlen, hdrlen;
632   int indent_all;
633
634   if ((indent_all = (indent < 0)))
635     indent = - indent;
636
637   err = parse_ber_header (&der, &derlen, &class, &tag, &constructed,
638                           &ndef, &objlen, &hdrlen);
639   if (!err && (objlen > derlen || tag != TAG_UTF8_STRING))
640     err = gpg_error (GPG_ERR_INV_OBJ);
641   if (err)
642     {
643       es_fprintf (fp, "%*s[%s%s]\n",
644                   indent_all? indent:0, "", _("Error - "), gpg_strerror (err));
645       return;
646     }
647   es_fprintf (fp, "%*s\"", indent_all? indent:0, "");
648   /* Fixme: we should implement word wrapping */
649   es_write_sanitized (fp, der, objlen, "\"", NULL);
650   es_fputs ("\"\n", fp);
651 }
652
653
654 /* List one certificate in raw mode useful to have a closer look at
655    the certificate.  This one does no beautification and only minimal
656    output sanitation.  It is mainly useful for debugging. */
657 static void
658 list_cert_raw (ctrl_t ctrl, KEYDB_HANDLE hd,
659                ksba_cert_t cert, estream_t fp, int have_secret,
660                int with_validation)
661 {
662   gpg_error_t err;
663   size_t off, len;
664   ksba_sexp_t sexp, keyid;
665   char *dn;
666   ksba_isotime_t t;
667   int idx, i;
668   int is_ca, chainlen;
669   unsigned int kusage;
670   char *string, *p, *pend;
671   const char *oid, *s;
672   ksba_name_t name, name2;
673   unsigned int reason;
674   const unsigned char *cert_der = NULL;
675
676   (void)have_secret;
677
678   es_fprintf (fp, "           ID: 0x%08lX\n",
679               gpgsm_get_short_fingerprint (cert, NULL));
680
681   sexp = ksba_cert_get_serial (cert);
682   es_fputs ("          S/N: ", fp);
683   gpgsm_print_serial (fp, sexp);
684   ksba_free (sexp);
685   es_putc ('\n', fp);
686
687   dn = ksba_cert_get_issuer (cert, 0);
688   es_fputs ("       Issuer: ", fp);
689   print_name_raw (fp, dn);
690   ksba_free (dn);
691   es_putc ('\n', fp);
692   for (idx=1; (dn = ksba_cert_get_issuer (cert, idx)); idx++)
693     {
694       es_fputs ("          aka: ", fp);
695       print_name_raw (fp, dn);
696       ksba_free (dn);
697       es_putc ('\n', fp);
698     }
699
700   dn = ksba_cert_get_subject (cert, 0);
701   es_fputs ("      Subject: ", fp);
702   print_name_raw (fp, dn);
703   ksba_free (dn);
704   es_putc ('\n', fp);
705   for (idx=1; (dn = ksba_cert_get_subject (cert, idx)); idx++)
706     {
707       es_fputs ("          aka: ", fp);
708       print_name_raw (fp, dn);
709       ksba_free (dn);
710       es_putc ('\n', fp);
711     }
712
713   dn = gpgsm_get_fingerprint_string (cert, 0);
714   es_fprintf (fp, "     sha1_fpr: %s\n", dn?dn:"error");
715   xfree (dn);
716
717   dn = gpgsm_get_fingerprint_string (cert, GCRY_MD_MD5);
718   es_fprintf (fp, "      md5_fpr: %s\n", dn?dn:"error");
719   xfree (dn);
720
721   dn = gpgsm_get_certid (cert);
722   es_fprintf (fp, "       certid: %s\n", dn?dn:"error");
723   xfree (dn);
724
725   dn = gpgsm_get_keygrip_hexstring (cert);
726   es_fprintf (fp, "      keygrip: %s\n", dn?dn:"error");
727   xfree (dn);
728
729   ksba_cert_get_validity (cert, 0, t);
730   es_fputs ("    notBefore: ", fp);
731   gpgsm_print_time (fp, t);
732   es_putc ('\n', fp);
733   es_fputs ("     notAfter: ", fp);
734   ksba_cert_get_validity (cert, 1, t);
735   gpgsm_print_time (fp, t);
736   es_putc ('\n', fp);
737
738   oid = ksba_cert_get_digest_algo (cert);
739   s = get_oid_desc (oid, NULL);
740   es_fprintf (fp, "     hashAlgo: %s%s%s%s\n", oid, s?" (":"",s?s:"",s?")":"");
741
742   {
743     const char *algoname;
744     unsigned int nbits;
745
746     algoname = gcry_pk_algo_name (gpgsm_get_key_algo_info (cert, &nbits));
747     es_fprintf (fp, "      keyType: %u bit %s\n",
748                 nbits, algoname? algoname:"?");
749   }
750
751   /* subjectKeyIdentifier */
752   es_fputs ("    subjKeyId: ", fp);
753   err = ksba_cert_get_subj_key_id (cert, NULL, &keyid);
754   if (!err || gpg_err_code (err) == GPG_ERR_NO_DATA)
755     {
756       if (gpg_err_code (err) == GPG_ERR_NO_DATA)
757         es_fputs ("[none]\n", fp);
758       else
759         {
760           gpgsm_print_serial (fp, keyid);
761           ksba_free (keyid);
762           es_putc ('\n', fp);
763         }
764     }
765   else
766     es_fputs ("[?]\n", fp);
767
768
769   /* authorityKeyIdentifier */
770   es_fputs ("    authKeyId: ", fp);
771   err = ksba_cert_get_auth_key_id (cert, &keyid, &name, &sexp);
772   if (!err || gpg_err_code (err) == GPG_ERR_NO_DATA)
773     {
774       if (gpg_err_code (err) == GPG_ERR_NO_DATA || !name)
775         es_fputs ("[none]\n", fp);
776       else
777         {
778           gpgsm_print_serial (fp, sexp);
779           ksba_free (sexp);
780           es_putc ('\n', fp);
781           print_names_raw (fp, -15, name);
782           ksba_name_release (name);
783         }
784       if (keyid)
785         {
786           es_fputs (" authKeyId.ki: ", fp);
787           gpgsm_print_serial (fp, keyid);
788           ksba_free (keyid);
789           es_putc ('\n', fp);
790         }
791     }
792   else
793     es_fputs ("[?]\n", fp);
794
795   es_fputs ("     keyUsage:", fp);
796   err = ksba_cert_get_key_usage (cert, &kusage);
797   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
798     {
799       if (err)
800         es_fprintf (fp, " [error: %s]", gpg_strerror (err));
801       else
802         {
803           if ( (kusage & KSBA_KEYUSAGE_DIGITAL_SIGNATURE))
804             es_fputs (" digitalSignature", fp);
805           if ( (kusage & KSBA_KEYUSAGE_NON_REPUDIATION))
806             es_fputs (" nonRepudiation", fp);
807           if ( (kusage & KSBA_KEYUSAGE_KEY_ENCIPHERMENT))
808             es_fputs (" keyEncipherment", fp);
809           if ( (kusage & KSBA_KEYUSAGE_DATA_ENCIPHERMENT))
810             es_fputs (" dataEncipherment", fp);
811           if ( (kusage & KSBA_KEYUSAGE_KEY_AGREEMENT))
812             es_fputs (" keyAgreement", fp);
813           if ( (kusage & KSBA_KEYUSAGE_KEY_CERT_SIGN))
814             es_fputs (" certSign", fp);
815           if ( (kusage & KSBA_KEYUSAGE_CRL_SIGN))
816             es_fputs (" crlSign", fp);
817           if ( (kusage & KSBA_KEYUSAGE_ENCIPHER_ONLY))
818             es_fputs (" encipherOnly", fp);
819           if ( (kusage & KSBA_KEYUSAGE_DECIPHER_ONLY))
820             es_fputs (" decipherOnly", fp);
821         }
822       es_putc ('\n', fp);
823     }
824   else
825     es_fputs (" [none]\n", fp);
826
827   es_fputs ("  extKeyUsage: ", fp);
828   err = ksba_cert_get_ext_key_usages (cert, &string);
829   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
830     {
831       if (err)
832         es_fprintf (fp, "[error: %s]", gpg_strerror (err));
833       else
834         {
835           p = string;
836           while (p && (pend=strchr (p, ':')))
837             {
838               *pend++ = 0;
839               for (i=0; key_purpose_map[i].oid; i++)
840                 if ( !strcmp (key_purpose_map[i].oid, p) )
841                   break;
842               es_fputs (key_purpose_map[i].oid?key_purpose_map[i].name:p, fp);
843               p = pend;
844               if (*p != 'C')
845                 es_fputs (" (suggested)", fp);
846               if ((p = strchr (p, '\n')))
847                 {
848                   p++;
849                   es_fputs ("\n               ", fp);
850                 }
851             }
852           xfree (string);
853         }
854       es_putc ('\n', fp);
855     }
856   else
857     es_fputs ("[none]\n", fp);
858
859
860   es_fputs ("     policies: ", fp);
861   err = ksba_cert_get_cert_policies (cert, &string);
862   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
863     {
864       if (err)
865         es_fprintf (fp, "[error: %s]", gpg_strerror (err));
866       else
867         {
868           p = string;
869           while (p && (pend=strchr (p, ':')))
870             {
871               *pend++ = 0;
872               for (i=0; key_purpose_map[i].oid; i++)
873                 if ( !strcmp (key_purpose_map[i].oid, p) )
874                   break;
875               es_fputs (p, fp);
876               p = pend;
877               if (*p == 'C')
878                 es_fputs (" (critical)", fp);
879               if ((p = strchr (p, '\n')))
880                 {
881                   p++;
882                   es_fputs ("\n               ", fp);
883                 }
884             }
885           xfree (string);
886         }
887       es_putc ('\n', fp);
888     }
889   else
890     es_fputs ("[none]\n", fp);
891
892   es_fputs ("  chainLength: ", fp);
893   err = ksba_cert_is_ca (cert, &is_ca, &chainlen);
894   if (err || is_ca)
895     {
896       if (gpg_err_code (err) == GPG_ERR_NO_VALUE )
897         es_fprintf (fp, "[none]");
898       else if (err)
899         es_fprintf (fp, "[error: %s]", gpg_strerror (err));
900       else if (chainlen == -1)
901         es_fputs ("unlimited", fp);
902       else
903         es_fprintf (fp, "%d", chainlen);
904       es_putc ('\n', fp);
905     }
906   else
907     es_fputs ("not a CA\n", fp);
908
909
910   /* CRL distribution point */
911   for (idx=0; !(err=ksba_cert_get_crl_dist_point (cert, idx, &name, &name2,
912                                                   &reason)) ;idx++)
913     {
914       es_fputs ("        crlDP: ", fp);
915       print_names_raw (fp, 15, name);
916       if (reason)
917         {
918           es_fputs ("               reason: ", fp);
919           if ( (reason & KSBA_CRLREASON_UNSPECIFIED))
920             es_fputs (" unused", fp);
921           if ( (reason & KSBA_CRLREASON_KEY_COMPROMISE))
922             es_fputs (" keyCompromise", fp);
923           if ( (reason & KSBA_CRLREASON_CA_COMPROMISE))
924             es_fputs (" caCompromise", fp);
925           if ( (reason & KSBA_CRLREASON_AFFILIATION_CHANGED))
926             es_fputs (" affiliationChanged", fp);
927           if ( (reason & KSBA_CRLREASON_SUPERSEDED))
928             es_fputs (" superseded", fp);
929           if ( (reason & KSBA_CRLREASON_CESSATION_OF_OPERATION))
930             es_fputs (" cessationOfOperation", fp);
931           if ( (reason & KSBA_CRLREASON_CERTIFICATE_HOLD))
932             es_fputs (" certificateHold", fp);
933           es_putc ('\n', fp);
934         }
935       es_fputs ("               issuer: ", fp);
936       print_names_raw (fp, 23, name2);
937       ksba_name_release (name);
938       ksba_name_release (name2);
939     }
940   if (err && gpg_err_code (err) != GPG_ERR_EOF
941       && gpg_err_code (err) != GPG_ERR_NO_VALUE)
942     es_fputs ("        crlDP: [error]\n", fp);
943   else if (!idx)
944     es_fputs ("        crlDP: [none]\n", fp);
945
946
947   /* authorityInfoAccess. */
948   for (idx=0; !(err=ksba_cert_get_authority_info_access (cert, idx, &string,
949                                                          &name)); idx++)
950     {
951       es_fputs ("     authInfo: ", fp);
952       s = get_oid_desc (string, NULL);
953       es_fprintf (fp, "%s%s%s%s\n", string, s?" (":"", s?s:"", s?")":"");
954       print_names_raw (fp, -15, name);
955       ksba_name_release (name);
956       ksba_free (string);
957     }
958   if (err && gpg_err_code (err) != GPG_ERR_EOF
959       && gpg_err_code (err) != GPG_ERR_NO_VALUE)
960     es_fputs ("     authInfo: [error]\n", fp);
961   else if (!idx)
962     es_fputs ("     authInfo: [none]\n", fp);
963
964   /* subjectInfoAccess. */
965   for (idx=0; !(err=ksba_cert_get_subject_info_access (cert, idx, &string,
966                                                          &name)); idx++)
967     {
968       es_fputs ("  subjectInfo: ", fp);
969       s = get_oid_desc (string, NULL);
970       es_fprintf (fp, "%s%s%s%s\n", string, s?" (":"", s?s:"", s?")":"");
971       print_names_raw (fp, -15, name);
972       ksba_name_release (name);
973       ksba_free (string);
974     }
975   if (err && gpg_err_code (err) != GPG_ERR_EOF
976       && gpg_err_code (err) != GPG_ERR_NO_VALUE)
977     es_fputs ("     subjInfo: [error]\n", fp);
978   else if (!idx)
979     es_fputs ("     subjInfo: [none]\n", fp);
980
981
982   for (idx=0; !(err=ksba_cert_get_extension (cert, idx,
983                                              &oid, &i, &off, &len));idx++)
984     {
985       unsigned int flag;
986
987       s = get_oid_desc (oid, &flag);
988       if ((flag & OID_FLAG_SKIP))
989         continue;
990
991       es_fprintf (fp, "     %s: %s%s%s%s  [%d octets]\n",
992                   i? "critExtn":"    extn",
993                   oid, s?" (":"", s?s:"", s?")":"", (int)len);
994       if ((flag & OID_FLAG_UTF8))
995         {
996           if (!cert_der)
997             cert_der = ksba_cert_get_image (cert, NULL);
998           assert (cert_der);
999           print_utf8_extn_raw (fp, -15, cert_der+off, len);
1000         }
1001     }
1002
1003
1004   if (with_validation)
1005     {
1006       err = gpgsm_validate_chain (ctrl, cert, "", NULL, 1, fp, 0, NULL);
1007       if (!err)
1008         es_fprintf (fp, "  [certificate is good]\n");
1009       else
1010         es_fprintf (fp, "  [certificate is bad: %s]\n", gpg_strerror (err));
1011     }
1012
1013   if (hd)
1014     {
1015       unsigned int blobflags;
1016
1017       err = keydb_get_flags (hd, KEYBOX_FLAG_BLOB, 0, &blobflags);
1018       if (err)
1019         es_fprintf (fp, "  [error getting keyflags: %s]\n",gpg_strerror (err));
1020       else if ((blobflags & KEYBOX_FLAG_BLOB_EPHEMERAL))
1021         es_fprintf (fp, "  [stored as ephemeral]\n");
1022     }
1023
1024 }
1025
1026
1027
1028
1029 /* List one certificate in standard mode */
1030 static void
1031 list_cert_std (ctrl_t ctrl, ksba_cert_t cert, estream_t fp, int have_secret,
1032                int with_validation)
1033 {
1034   gpg_error_t err;
1035   ksba_sexp_t sexp;
1036   char *dn;
1037   ksba_isotime_t t;
1038   int idx, i;
1039   int is_ca, chainlen;
1040   unsigned int kusage;
1041   char *string, *p, *pend;
1042   size_t off, len;
1043   const char *oid;
1044   const unsigned char *cert_der = NULL;
1045
1046
1047   es_fprintf (fp, "           ID: 0x%08lX\n",
1048               gpgsm_get_short_fingerprint (cert, NULL));
1049
1050   sexp = ksba_cert_get_serial (cert);
1051   es_fputs ("          S/N: ", fp);
1052   gpgsm_print_serial (fp, sexp);
1053   ksba_free (sexp);
1054   es_putc ('\n', fp);
1055
1056   dn = ksba_cert_get_issuer (cert, 0);
1057   es_fputs ("       Issuer: ", fp);
1058   gpgsm_es_print_name (fp, dn);
1059   ksba_free (dn);
1060   es_putc ('\n', fp);
1061   for (idx=1; (dn = ksba_cert_get_issuer (cert, idx)); idx++)
1062     {
1063       es_fputs ("          aka: ", fp);
1064       gpgsm_es_print_name (fp, dn);
1065       ksba_free (dn);
1066       es_putc ('\n', fp);
1067     }
1068
1069   dn = ksba_cert_get_subject (cert, 0);
1070   es_fputs ("      Subject: ", fp);
1071   gpgsm_es_print_name (fp, dn);
1072   ksba_free (dn);
1073   es_putc ('\n', fp);
1074   for (idx=1; (dn = ksba_cert_get_subject (cert, idx)); idx++)
1075     {
1076       es_fputs ("          aka: ", fp);
1077       gpgsm_es_print_name (fp, dn);
1078       ksba_free (dn);
1079       es_putc ('\n', fp);
1080     }
1081
1082   ksba_cert_get_validity (cert, 0, t);
1083   es_fputs ("     validity: ", fp);
1084   gpgsm_print_time (fp, t);
1085   es_fputs (" through ", fp);
1086   ksba_cert_get_validity (cert, 1, t);
1087   gpgsm_print_time (fp, t);
1088   es_putc ('\n', fp);
1089
1090
1091   {
1092     const char *algoname;
1093     unsigned int nbits;
1094
1095     algoname = gcry_pk_algo_name (gpgsm_get_key_algo_info (cert, &nbits));
1096     es_fprintf (fp, "     key type: %u bit %s\n",
1097                 nbits, algoname? algoname:"?");
1098   }
1099
1100
1101   err = ksba_cert_get_key_usage (cert, &kusage);
1102   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
1103     {
1104       es_fputs ("    key usage:", fp);
1105       if (err)
1106         es_fprintf (fp, " [error: %s]", gpg_strerror (err));
1107       else
1108         {
1109           if ( (kusage & KSBA_KEYUSAGE_DIGITAL_SIGNATURE))
1110             es_fputs (" digitalSignature", fp);
1111           if ( (kusage & KSBA_KEYUSAGE_NON_REPUDIATION))
1112             es_fputs (" nonRepudiation", fp);
1113           if ( (kusage & KSBA_KEYUSAGE_KEY_ENCIPHERMENT))
1114             es_fputs (" keyEncipherment", fp);
1115           if ( (kusage & KSBA_KEYUSAGE_DATA_ENCIPHERMENT))
1116             es_fputs (" dataEncipherment", fp);
1117           if ( (kusage & KSBA_KEYUSAGE_KEY_AGREEMENT))
1118             es_fputs (" keyAgreement", fp);
1119           if ( (kusage & KSBA_KEYUSAGE_KEY_CERT_SIGN))
1120             es_fputs (" certSign", fp);
1121           if ( (kusage & KSBA_KEYUSAGE_CRL_SIGN))
1122             es_fputs (" crlSign", fp);
1123           if ( (kusage & KSBA_KEYUSAGE_ENCIPHER_ONLY))
1124             es_fputs (" encipherOnly", fp);
1125           if ( (kusage & KSBA_KEYUSAGE_DECIPHER_ONLY))
1126             es_fputs (" decipherOnly", fp);
1127         }
1128       es_putc ('\n', fp);
1129     }
1130
1131   err = ksba_cert_get_ext_key_usages (cert, &string);
1132   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
1133     {
1134       es_fputs ("ext key usage: ", fp);
1135       if (err)
1136         es_fprintf (fp, "[error: %s]", gpg_strerror (err));
1137       else
1138         {
1139           p = string;
1140           while (p && (pend=strchr (p, ':')))
1141             {
1142               *pend++ = 0;
1143               for (i=0; key_purpose_map[i].oid; i++)
1144                 if ( !strcmp (key_purpose_map[i].oid, p) )
1145                   break;
1146               es_fputs (key_purpose_map[i].oid?key_purpose_map[i].name:p, fp);
1147               p = pend;
1148               if (*p != 'C')
1149                 es_fputs (" (suggested)", fp);
1150               if ((p = strchr (p, '\n')))
1151                 {
1152                   p++;
1153                   es_fputs (", ", fp);
1154                 }
1155             }
1156           xfree (string);
1157         }
1158       es_putc ('\n', fp);
1159     }
1160
1161   /* Print restrictions.  */
1162   for (idx=0; !(err=ksba_cert_get_extension (cert, idx,
1163                                              &oid, NULL, &off, &len));idx++)
1164     {
1165       if (!strcmp (oid, OIDSTR_restriction) )
1166         {
1167           if (!cert_der)
1168             cert_der = ksba_cert_get_image (cert, NULL);
1169           assert (cert_der);
1170           es_fputs ("  restriction: ", fp);
1171           print_utf8_extn (fp, 15, cert_der+off, len);
1172         }
1173     }
1174
1175   /* Print policies.  */
1176   err = ksba_cert_get_cert_policies (cert, &string);
1177   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
1178     {
1179       es_fputs ("     policies: ", fp);
1180       if (err)
1181         es_fprintf (fp, "[error: %s]", gpg_strerror (err));
1182       else
1183         {
1184           for (p=string; *p; p++)
1185             {
1186               if (*p == '\n')
1187                 *p = ',';
1188             }
1189           es_write_sanitized (fp, string, strlen (string), NULL, NULL);
1190           xfree (string);
1191         }
1192       es_putc ('\n', fp);
1193     }
1194
1195   err = ksba_cert_is_ca (cert, &is_ca, &chainlen);
1196   if (err || is_ca)
1197     {
1198       es_fputs (" chain length: ", fp);
1199       if (gpg_err_code (err) == GPG_ERR_NO_VALUE )
1200         es_fprintf (fp, "none");
1201       else if (err)
1202         es_fprintf (fp, "[error: %s]", gpg_strerror (err));
1203       else if (chainlen == -1)
1204         es_fputs ("unlimited", fp);
1205       else
1206         es_fprintf (fp, "%d", chainlen);
1207       es_putc ('\n', fp);
1208     }
1209
1210   if (opt.with_md5_fingerprint)
1211     {
1212       dn = gpgsm_get_fingerprint_string (cert, GCRY_MD_MD5);
1213       es_fprintf (fp, "      md5 fpr: %s\n", dn?dn:"error");
1214       xfree (dn);
1215     }
1216
1217   dn = gpgsm_get_fingerprint_string (cert, 0);
1218   es_fprintf (fp, "  fingerprint: %s\n", dn?dn:"error");
1219   xfree (dn);
1220
1221   if (opt.with_keygrip)
1222     {
1223       dn = gpgsm_get_keygrip_hexstring (cert);
1224       if (dn)
1225         {
1226           es_fprintf (fp, "      keygrip: %s\n", dn);
1227           xfree (dn);
1228         }
1229     }
1230
1231   if (have_secret)
1232     {
1233       char *cardsn;
1234
1235       p = gpgsm_get_keygrip_hexstring (cert);
1236       if (!gpgsm_agent_keyinfo (ctrl, p, &cardsn) && cardsn)
1237         es_fprintf (fp, "     card s/n: %s\n", cardsn);
1238       xfree (cardsn);
1239       xfree (p);
1240     }
1241
1242   if (with_validation)
1243     {
1244       gpg_error_t tmperr;
1245       size_t buflen;
1246       char buffer[1];
1247
1248       err = gpgsm_validate_chain (ctrl, cert, "", NULL, 1, fp, 0, NULL);
1249       tmperr = ksba_cert_get_user_data (cert, "is_qualified",
1250                                         &buffer, sizeof (buffer), &buflen);
1251       if (!tmperr && buflen)
1252         {
1253           if (*buffer)
1254             es_fputs ("  [qualified]\n", fp);
1255         }
1256       else if (gpg_err_code (tmperr) == GPG_ERR_NOT_FOUND)
1257         ; /* Don't know - will not get marked as 'q' */
1258       else
1259         log_debug ("get_user_data(is_qualified) failed: %s\n",
1260                    gpg_strerror (tmperr));
1261
1262       if (!err)
1263         es_fprintf (fp, "  [certificate is good]\n");
1264       else
1265         es_fprintf (fp, "  [certificate is bad: %s]\n", gpg_strerror (err));
1266     }
1267 }
1268
1269
1270 /* Same as standard mode mode list all certifying certs too. */
1271 static void
1272 list_cert_chain (ctrl_t ctrl, KEYDB_HANDLE hd,
1273                  ksba_cert_t cert, int raw_mode,
1274                  estream_t fp, int with_validation)
1275 {
1276   ksba_cert_t next = NULL;
1277
1278   if (raw_mode)
1279     list_cert_raw (ctrl, hd, cert, fp, 0, with_validation);
1280   else
1281     list_cert_std (ctrl, cert, fp, 0, with_validation);
1282   ksba_cert_ref (cert);
1283   while (!gpgsm_walk_cert_chain (ctrl, cert, &next))
1284     {
1285       ksba_cert_release (cert);
1286       es_fputs ("Certified by\n", fp);
1287       if (raw_mode)
1288         list_cert_raw (ctrl, hd, next, fp, 0, with_validation);
1289       else
1290         list_cert_std (ctrl, next, fp, 0, with_validation);
1291       cert = next;
1292     }
1293   ksba_cert_release (cert);
1294   es_putc ('\n', fp);
1295 }
1296
1297
1298 \f
1299 /* List all internal keys or just the keys given as NAMES.  MODE is a
1300    bit vector to specify what keys are to be included; see
1301    gpgsm_list_keys (below) for details.  If RAW_MODE is true, the raw
1302    output mode will be used instead of the standard beautified one.
1303  */
1304 static gpg_error_t
1305 list_internal_keys (ctrl_t ctrl, strlist_t names, estream_t fp,
1306                     unsigned int mode, int raw_mode)
1307 {
1308   KEYDB_HANDLE hd;
1309   KEYDB_SEARCH_DESC *desc = NULL;
1310   strlist_t sl;
1311   int ndesc;
1312   ksba_cert_t cert = NULL;
1313   ksba_cert_t lastcert = NULL;
1314   gpg_error_t rc = 0;
1315   const char *lastresname, *resname;
1316   int have_secret;
1317   int want_ephemeral = ctrl->with_ephemeral_keys;
1318
1319   hd = keydb_new (0);
1320   if (!hd)
1321     {
1322       log_error ("keydb_new failed\n");
1323       rc = gpg_error (GPG_ERR_GENERAL);
1324       goto leave;
1325     }
1326
1327   if (!names)
1328     ndesc = 1;
1329   else
1330     {
1331       for (sl=names, ndesc=0; sl; sl = sl->next, ndesc++)
1332         ;
1333     }
1334
1335   desc = xtrycalloc (ndesc, sizeof *desc);
1336   if (!ndesc)
1337     {
1338       rc = gpg_error_from_syserror ();
1339       log_error ("out of core\n");
1340       goto leave;
1341     }
1342
1343   if (!names)
1344     desc[0].mode = KEYDB_SEARCH_MODE_FIRST;
1345   else
1346     {
1347       for (ndesc=0, sl=names; sl; sl = sl->next)
1348         {
1349           rc = classify_user_id (sl->d, desc+ndesc, 0);
1350           if (rc)
1351             {
1352               log_error ("key `%s' not found: %s\n",
1353                          sl->d, gpg_strerror (rc));
1354               rc = 0;
1355             }
1356           else
1357             ndesc++;
1358         }
1359
1360     }
1361
1362   /* If all specifications are done by fingerprint or keygrip, we
1363      switch to ephemeral mode so that _all_ currently available and
1364      matching certificates are listed.  */
1365   if (!want_ephemeral && names && ndesc)
1366     {
1367       int i;
1368
1369       for (i=0; (i < ndesc
1370                  && (desc[i].mode == KEYDB_SEARCH_MODE_FPR
1371                      || desc[i].mode == KEYDB_SEARCH_MODE_FPR20
1372                      || desc[i].mode == KEYDB_SEARCH_MODE_FPR16
1373                      || desc[i].mode == KEYDB_SEARCH_MODE_KEYGRIP)); i++)
1374         ;
1375       if (i == ndesc)
1376         want_ephemeral = 1;
1377     }
1378
1379   if (want_ephemeral)
1380     keydb_set_ephemeral (hd, 1);
1381
1382   /* It would be nice to see which of the given users did actually
1383      match one in the keyring.  To implement this we need to have a
1384      found flag for each entry in desc and to set this we must check
1385      all those entries after a match to mark all matched one -
1386      currently we stop at the first match.  To do this we need an
1387      extra flag to enable this feature so */
1388
1389   /* Suppress duplicates at least when they follow each other.  */
1390   lastresname = NULL;
1391   while (!(rc = keydb_search (hd, desc, ndesc)))
1392     {
1393       unsigned int validity;
1394
1395       if (!names)
1396         desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
1397
1398       rc = keydb_get_flags (hd, KEYBOX_FLAG_VALIDITY, 0, &validity);
1399       if (rc)
1400         {
1401           log_error ("keydb_get_flags failed: %s\n", gpg_strerror (rc));
1402           goto leave;
1403         }
1404       rc = keydb_get_cert (hd, &cert);
1405       if (rc)
1406         {
1407           log_error ("keydb_get_cert failed: %s\n", gpg_strerror (rc));
1408           goto leave;
1409         }
1410       /* Skip duplicated certificates, at least if they follow each
1411          others.  This works best if a single key is searched for and
1412          expected.  FIXME: Non-sequential duplicates remain.  */
1413       if (gpgsm_certs_identical_p (cert, lastcert))
1414         {
1415           ksba_cert_release (cert);
1416           cert = NULL;
1417           continue;
1418         }
1419
1420       resname = keydb_get_resource_name (hd);
1421
1422       if (lastresname != resname )
1423         {
1424           int i;
1425
1426           if (ctrl->no_server)
1427             {
1428               es_fprintf (fp, "%s\n", resname );
1429               for (i=strlen(resname); i; i-- )
1430                 es_putc ('-', fp);
1431               es_putc ('\n', fp);
1432               lastresname = resname;
1433             }
1434         }
1435
1436       have_secret = 0;
1437       if (mode)
1438         {
1439           char *p = gpgsm_get_keygrip_hexstring (cert);
1440           if (p)
1441             {
1442               rc = gpgsm_agent_havekey (ctrl, p);
1443               if (!rc)
1444                 have_secret = 1;
1445               else if ( gpg_err_code (rc) != GPG_ERR_NO_SECKEY)
1446                 goto leave;
1447               rc = 0;
1448               xfree (p);
1449             }
1450         }
1451
1452       if (!mode
1453           || ((mode & 1) && !have_secret)
1454           || ((mode & 2) && have_secret)  )
1455         {
1456           if (ctrl->with_colons)
1457             list_cert_colon (ctrl, cert, validity, fp, have_secret);
1458           else if (ctrl->with_chain)
1459             list_cert_chain (ctrl, hd, cert,
1460                              raw_mode, fp, ctrl->with_validation);
1461           else
1462             {
1463               if (raw_mode)
1464                 list_cert_raw (ctrl, hd, cert, fp, have_secret,
1465                                ctrl->with_validation);
1466               else
1467                 list_cert_std (ctrl, cert, fp, have_secret,
1468                                ctrl->with_validation);
1469               es_putc ('\n', fp);
1470             }
1471         }
1472
1473       ksba_cert_release (lastcert);
1474       lastcert = cert;
1475       cert = NULL;
1476     }
1477   if (gpg_err_code (rc) == GPG_ERR_EOF || rc == -1 )
1478     rc = 0;
1479   if (rc)
1480     log_error ("keydb_search failed: %s\n", gpg_strerror (rc));
1481
1482  leave:
1483   ksba_cert_release (cert);
1484   ksba_cert_release (lastcert);
1485   xfree (desc);
1486   keydb_release (hd);
1487   return rc;
1488 }
1489
1490
1491
1492 static void
1493 list_external_cb (void *cb_value, ksba_cert_t cert)
1494 {
1495   struct list_external_parm_s *parm = cb_value;
1496
1497   if (keydb_store_cert (cert, 1, NULL))
1498     log_error ("error storing certificate as ephemeral\n");
1499
1500   if (parm->print_header)
1501     {
1502       const char *resname = "[external keys]";
1503       int i;
1504
1505       es_fprintf (parm->fp, "%s\n", resname );
1506       for (i=strlen(resname); i; i-- )
1507         es_putc('-', parm->fp);
1508       es_putc ('\n', parm->fp);
1509       parm->print_header = 0;
1510     }
1511
1512   if (parm->with_colons)
1513     list_cert_colon (parm->ctrl, cert, 0, parm->fp, 0);
1514   else if (parm->with_chain)
1515     list_cert_chain (parm->ctrl, NULL, cert, parm->raw_mode, parm->fp, 0);
1516   else
1517     {
1518       if (parm->raw_mode)
1519         list_cert_raw (parm->ctrl, NULL, cert, parm->fp, 0, 0);
1520       else
1521         list_cert_std (parm->ctrl, cert, parm->fp, 0, 0);
1522       es_putc ('\n', parm->fp);
1523     }
1524 }
1525
1526
1527 /* List external keys similar to internal one.  Note: mode does not
1528    make sense here because it would be unwise to list external secret
1529    keys */
1530 static gpg_error_t
1531 list_external_keys (ctrl_t ctrl, strlist_t names, estream_t fp, int raw_mode)
1532 {
1533   int rc;
1534   struct list_external_parm_s parm;
1535
1536   parm.fp = fp;
1537   parm.ctrl = ctrl,
1538   parm.print_header = ctrl->no_server;
1539   parm.with_colons = ctrl->with_colons;
1540   parm.with_chain = ctrl->with_chain;
1541   parm.raw_mode  = raw_mode;
1542
1543   rc = gpgsm_dirmngr_lookup (ctrl, names, 0, list_external_cb, &parm);
1544   if (gpg_err_code (rc) == GPG_ERR_EOF || rc == -1
1545       || gpg_err_code (rc) == GPG_ERR_NOT_FOUND)
1546     rc = 0; /* "Not found" is not an error here. */
1547   if (rc)
1548     log_error ("listing external keys failed: %s\n", gpg_strerror (rc));
1549   return rc;
1550 }
1551
1552 /* List all keys or just the key given as NAMES.
1553    MODE controls the operation mode:
1554     Bit 0-2:
1555       0 = list all public keys but don't flag secret ones
1556       1 = list only public keys
1557       2 = list only secret keys
1558       3 = list secret and public keys
1559     Bit 6: list internal keys
1560     Bit 7: list external keys
1561     Bit 8: Do a raw format dump.
1562  */
1563 gpg_error_t
1564 gpgsm_list_keys (ctrl_t ctrl, strlist_t names, estream_t fp,
1565                  unsigned int mode)
1566 {
1567   gpg_error_t err = 0;
1568
1569   if ((mode & (1<<6)))
1570     err = list_internal_keys (ctrl, names, fp, (mode & 3), (mode&256));
1571   if (!err && (mode & (1<<7)))
1572     err = list_external_keys (ctrl, names, fp, (mode&256));
1573   return err;
1574 }