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