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