Marked all unused args on non-W32 platforms.
[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 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, &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   es_putc (':', fp);
485   es_putc ('\n', fp);
486
487   /* FPR record */
488   es_fprintf (fp, "fpr:::::::::%s:::", fpr);
489   /* Print chaining ID (field 13)*/
490   if (chain_id)
491     es_fputs (chain_id, fp);
492   es_putc (':', fp);
493   es_putc ('\n', fp);
494   xfree (fpr); fpr = NULL; chain_id = NULL;
495   xfree (chain_id_buffer); chain_id_buffer = NULL;
496
497   if (opt.with_key_data)
498     {
499       if ( (p = gpgsm_get_keygrip_hexstring (cert)))
500         {
501           es_fprintf (fp, "grp:::::::::%s:\n", p);
502           xfree (p);
503         }
504       print_key_data (cert, fp);
505     }
506
507   kludge_uid = NULL;
508   for (idx=0; (p = ksba_cert_get_subject (cert,idx)); idx++)
509     {
510       /* In the case that the same email address is in the subject DN
511          as well as in an alternate subject name we avoid printing it
512          a second time. */
513       if (kludge_uid && !strcmp (kludge_uid, p))
514         continue;
515
516       es_fprintf (fp, "uid:%s::::::::", truststring);
517       es_write_sanitized (fp, p, strlen (p), ":", NULL);
518       es_putc (':', fp);
519       es_putc (':', fp);
520       es_putc ('\n', fp);
521       if (!idx)
522         {
523           /* It would be better to get the faked email address from
524              the keydb.  But as long as we don't have a way to pass
525              the meta data back, we just check it the same way as the
526              code used to create the keybox meta data does */
527           kludge_uid = email_kludge (p);
528           if (kludge_uid)
529             {
530               es_fprintf (fp, "uid:%s::::::::", truststring);
531               es_write_sanitized (fp, kludge_uid, strlen (kludge_uid),
532                                   ":", NULL);
533               es_putc (':', fp);
534               es_putc (':', fp);
535               es_putc ('\n', fp);
536             }
537         }
538       xfree (p);
539     }
540   xfree (kludge_uid);
541 }
542
543
544 static void
545 print_name_raw (estream_t fp, const char *string)
546 {
547   if (!string)
548     es_fputs ("[error]", fp);
549   else
550     es_write_sanitized (fp, string, strlen (string), NULL, NULL);
551 }
552
553 static void
554 print_names_raw (estream_t fp, int indent, ksba_name_t name)
555 {
556   int idx;
557   const char *s;
558   int indent_all;
559
560   if ((indent_all = (indent < 0)))
561     indent = - indent;
562
563   if (!name)
564     {
565       es_fputs ("none\n", fp);
566       return;
567     }
568   
569   for (idx=0; (s = ksba_name_enum (name, idx)); idx++)
570     {
571       char *p = ksba_name_get_uri (name, idx);
572       es_fprintf (fp, "%*s", idx||indent_all?indent:0, "");
573       es_write_sanitized (fp, p?p:s, strlen (p?p:s), NULL, NULL);
574       es_putc ('\n', fp);
575       xfree (p);
576     }
577 }
578
579
580 static void
581 print_utf8_extn_raw (estream_t fp, int indent, 
582                      const unsigned char *der, size_t derlen)
583 {
584   gpg_error_t err;
585   int class, tag, constructed, ndef;
586   size_t objlen, hdrlen;
587
588   if (indent < 0)
589     indent = - indent;
590
591   err = parse_ber_header (&der, &derlen, &class, &tag, &constructed,
592                           &ndef, &objlen, &hdrlen);
593   if (!err && (objlen > derlen || tag != TAG_UTF8_STRING))
594     err = gpg_error (GPG_ERR_INV_OBJ);
595   if (err)
596     {
597       es_fprintf (fp, "%*s[%s]\n", indent, "", gpg_strerror (err));
598       return;
599     }
600   es_fprintf (fp, "%*s(%.*s)\n", indent, "", objlen, der);
601 }
602
603
604 static void
605 print_utf8_extn (estream_t fp, int indent, 
606                  const unsigned char *der, size_t derlen)
607 {
608   gpg_error_t err;
609   int class, tag, constructed, ndef;
610   size_t objlen, hdrlen;
611   int indent_all;
612
613   if ((indent_all = (indent < 0)))
614     indent = - indent;
615
616   err = parse_ber_header (&der, &derlen, &class, &tag, &constructed,
617                           &ndef, &objlen, &hdrlen);
618   if (!err && (objlen > derlen || tag != TAG_UTF8_STRING))
619     err = gpg_error (GPG_ERR_INV_OBJ);
620   if (err)
621     {
622       es_fprintf (fp, "%*s[%s%s]\n",
623                   indent_all? indent:0, "", _("Error - "), gpg_strerror (err));
624       return;
625     }
626   es_fprintf (fp, "%*s\"", indent_all? indent:0, "");
627   /* Fixme: we should implement word wrapping */
628   es_write_sanitized (fp, der, objlen, "\"", NULL);
629   es_fputs ("\"\n", fp);
630 }
631
632
633 /* List one certificate in raw mode useful to have a closer look at
634    the certificate.  This one does no beautification and only minimal
635    output sanitation.  It is mainly useful for debugging. */
636 static void
637 list_cert_raw (ctrl_t ctrl, KEYDB_HANDLE hd,
638                ksba_cert_t cert, estream_t fp, int have_secret,
639                int with_validation)
640 {
641   gpg_error_t err;
642   size_t off, len;
643   ksba_sexp_t sexp, keyid;
644   char *dn;
645   ksba_isotime_t t;
646   int idx, i;
647   int is_ca, chainlen;
648   unsigned int kusage;
649   char *string, *p, *pend;
650   const char *oid, *s;
651   ksba_name_t name, name2;
652   unsigned int reason;
653   const unsigned char *cert_der = NULL;
654
655   (void)have_secret;
656
657   es_fprintf (fp, "           ID: 0x%08lX\n",
658               gpgsm_get_short_fingerprint (cert));
659
660   sexp = ksba_cert_get_serial (cert);
661   es_fputs ("          S/N: ", fp);
662   gpgsm_print_serial (fp, sexp);
663   ksba_free (sexp);
664   es_putc ('\n', fp);
665
666   dn = ksba_cert_get_issuer (cert, 0);
667   es_fputs ("       Issuer: ", fp);
668   print_name_raw (fp, dn);
669   ksba_free (dn);
670   es_putc ('\n', fp);
671   for (idx=1; (dn = ksba_cert_get_issuer (cert, idx)); idx++)
672     {
673       es_fputs ("          aka: ", fp);
674       print_name_raw (fp, dn);
675       ksba_free (dn);
676       es_putc ('\n', fp);
677     }
678
679   dn = ksba_cert_get_subject (cert, 0);
680   es_fputs ("      Subject: ", fp);
681   print_name_raw (fp, dn);
682   ksba_free (dn);
683   es_putc ('\n', fp);
684   for (idx=1; (dn = ksba_cert_get_subject (cert, idx)); idx++)
685     {
686       es_fputs ("          aka: ", fp);
687       print_name_raw (fp, dn);
688       ksba_free (dn);
689       es_putc ('\n', fp);
690     }
691
692   dn = gpgsm_get_fingerprint_string (cert, 0);
693   es_fprintf (fp, "     sha1_fpr: %s\n", dn?dn:"error");
694   xfree (dn);
695
696   dn = gpgsm_get_fingerprint_string (cert, GCRY_MD_MD5);
697   es_fprintf (fp, "      md5_fpr: %s\n", dn?dn:"error");
698   xfree (dn);
699
700   dn = gpgsm_get_certid (cert);
701   es_fprintf (fp, "       certid: %s\n", dn?dn:"error");
702   xfree (dn);
703
704   dn = gpgsm_get_keygrip_hexstring (cert);
705   es_fprintf (fp, "      keygrip: %s\n", dn?dn:"error");
706   xfree (dn);
707
708   ksba_cert_get_validity (cert, 0, t);
709   es_fputs ("    notBefore: ", fp);
710   gpgsm_print_time (fp, t);
711   es_putc ('\n', fp);
712   es_fputs ("     notAfter: ", fp);
713   ksba_cert_get_validity (cert, 1, t);
714   gpgsm_print_time (fp, t);
715   es_putc ('\n', fp);
716
717   oid = ksba_cert_get_digest_algo (cert);
718   s = get_oid_desc (oid, NULL);
719   es_fprintf (fp, "     hashAlgo: %s%s%s%s\n", oid, s?" (":"",s?s:"",s?")":"");
720
721   {
722     const char *algoname;
723     unsigned int nbits;
724
725     algoname = gcry_pk_algo_name (gpgsm_get_key_algo_info (cert, &nbits));
726     es_fprintf (fp, "      keyType: %u bit %s\n",
727                 nbits, algoname? algoname:"?");
728   }
729
730   /* subjectKeyIdentifier */
731   es_fputs ("    subjKeyId: ", fp);
732   err = ksba_cert_get_subj_key_id (cert, NULL, &keyid);
733   if (!err || gpg_err_code (err) == GPG_ERR_NO_DATA)
734     {
735       if (gpg_err_code (err) == GPG_ERR_NO_DATA)
736         es_fputs ("[none]\n", fp);
737       else
738         {
739           gpgsm_print_serial (fp, keyid);
740           ksba_free (keyid);
741           es_putc ('\n', fp);
742         }
743     }
744   else
745     es_fputs ("[?]\n", fp);
746
747
748   /* authorityKeyIdentifier */
749   es_fputs ("    authKeyId: ", fp);
750   err = ksba_cert_get_auth_key_id (cert, &keyid, &name, &sexp);
751   if (!err || gpg_err_code (err) == GPG_ERR_NO_DATA)
752     {
753       if (gpg_err_code (err) == GPG_ERR_NO_DATA || !name)
754         es_fputs ("[none]\n", fp);
755       else
756         {
757           gpgsm_print_serial (fp, sexp);
758           ksba_free (sexp);
759           es_putc ('\n', fp);
760           print_names_raw (fp, -15, name);
761           ksba_name_release (name);
762         }
763       if (keyid)
764         {
765           es_fputs (" authKeyId.ki: ", fp);
766           gpgsm_print_serial (fp, keyid);
767           ksba_free (keyid);
768           es_putc ('\n', fp);
769         }
770     }
771   else
772     es_fputs ("[?]\n", fp);
773
774   es_fputs ("     keyUsage:", fp);
775   err = ksba_cert_get_key_usage (cert, &kusage);
776   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
777     {
778       if (err)
779         es_fprintf (fp, " [error: %s]", gpg_strerror (err));
780       else
781         {
782           if ( (kusage & KSBA_KEYUSAGE_DIGITAL_SIGNATURE))
783             es_fputs (" digitalSignature", fp);
784           if ( (kusage & KSBA_KEYUSAGE_NON_REPUDIATION))  
785             es_fputs (" nonRepudiation", fp);
786           if ( (kusage & KSBA_KEYUSAGE_KEY_ENCIPHERMENT)) 
787             es_fputs (" keyEncipherment", fp);
788           if ( (kusage & KSBA_KEYUSAGE_DATA_ENCIPHERMENT))
789             es_fputs (" dataEncipherment", fp);
790           if ( (kusage & KSBA_KEYUSAGE_KEY_AGREEMENT))    
791             es_fputs (" keyAgreement", fp);
792           if ( (kusage & KSBA_KEYUSAGE_KEY_CERT_SIGN))
793             es_fputs (" certSign", fp);
794           if ( (kusage & KSBA_KEYUSAGE_CRL_SIGN))  
795             es_fputs (" crlSign", fp);
796           if ( (kusage & KSBA_KEYUSAGE_ENCIPHER_ONLY))
797             es_fputs (" encipherOnly", fp);
798           if ( (kusage & KSBA_KEYUSAGE_DECIPHER_ONLY))  
799             es_fputs (" decipherOnly", fp);
800         }
801       es_putc ('\n', fp);
802     }
803   else
804     es_fputs (" [none]\n", fp);
805
806   es_fputs ("  extKeyUsage: ", fp);
807   err = ksba_cert_get_ext_key_usages (cert, &string);
808   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
809     { 
810       if (err)
811         es_fprintf (fp, "[error: %s]", gpg_strerror (err));
812       else
813         {
814           p = string;
815           while (p && (pend=strchr (p, ':')))
816             {
817               *pend++ = 0;
818               for (i=0; key_purpose_map[i].oid; i++)
819                 if ( !strcmp (key_purpose_map[i].oid, p) )
820                   break;
821               es_fputs (key_purpose_map[i].oid?key_purpose_map[i].name:p, fp);
822               p = pend;
823               if (*p != 'C')
824                 es_fputs (" (suggested)", fp);
825               if ((p = strchr (p, '\n')))
826                 {
827                   p++;
828                   es_fputs ("\n               ", fp);
829                 }
830             }
831           xfree (string);
832         }
833       es_putc ('\n', fp);
834     }
835   else
836     es_fputs ("[none]\n", fp);
837
838
839   es_fputs ("     policies: ", fp);
840   err = ksba_cert_get_cert_policies (cert, &string);
841   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
842     {
843       if (err)
844         es_fprintf (fp, "[error: %s]", gpg_strerror (err));
845       else
846         {
847           p = string;
848           while (p && (pend=strchr (p, ':')))
849             {
850               *pend++ = 0;
851               for (i=0; key_purpose_map[i].oid; i++)
852                 if ( !strcmp (key_purpose_map[i].oid, p) )
853                   break;
854               es_fputs (p, fp);
855               p = pend;
856               if (*p == 'C')
857                 es_fputs (" (critical)", fp);
858               if ((p = strchr (p, '\n')))
859                 {
860                   p++;
861                   es_fputs ("\n               ", fp);
862                 }
863             }
864           xfree (string);
865         }
866       es_putc ('\n', fp);
867     }
868   else
869     es_fputs ("[none]\n", fp);
870
871   es_fputs ("  chainLength: ", fp);
872   err = ksba_cert_is_ca (cert, &is_ca, &chainlen);
873   if (err || is_ca)
874     {
875       if (gpg_err_code (err) == GPG_ERR_NO_VALUE )
876         es_fprintf (fp, "[none]");
877       else if (err)
878         es_fprintf (fp, "[error: %s]", gpg_strerror (err));
879       else if (chainlen == -1)
880         es_fputs ("unlimited", fp);
881       else
882         es_fprintf (fp, "%d", chainlen);
883       es_putc ('\n', fp);
884     }
885   else
886     es_fputs ("not a CA\n", fp);
887
888
889   /* CRL distribution point */
890   for (idx=0; !(err=ksba_cert_get_crl_dist_point (cert, idx, &name, &name2,
891                                                   &reason)) ;idx++)
892     {
893       es_fputs ("        crlDP: ", fp);
894       print_names_raw (fp, 15, name);
895       if (reason)
896         {
897           es_fputs ("               reason: ", fp);
898           if ( (reason & KSBA_CRLREASON_UNSPECIFIED))
899             es_fputs (" unused", fp);
900           if ( (reason & KSBA_CRLREASON_KEY_COMPROMISE))
901             es_fputs (" keyCompromise", fp);
902           if ( (reason & KSBA_CRLREASON_CA_COMPROMISE))
903             es_fputs (" caCompromise", fp);
904           if ( (reason & KSBA_CRLREASON_AFFILIATION_CHANGED))
905             es_fputs (" affiliationChanged", fp);
906           if ( (reason & KSBA_CRLREASON_SUPERSEDED))
907             es_fputs (" superseded", fp);
908           if ( (reason & KSBA_CRLREASON_CESSATION_OF_OPERATION))
909             es_fputs (" cessationOfOperation", fp);
910           if ( (reason & KSBA_CRLREASON_CERTIFICATE_HOLD))
911             es_fputs (" certificateHold", fp);
912           es_putc ('\n', fp);
913         }
914       es_fputs ("               issuer: ", fp);
915       print_names_raw (fp, 23, name2);
916       ksba_name_release (name);
917       ksba_name_release (name2);
918     }
919   if (err && gpg_err_code (err) != GPG_ERR_EOF
920       && gpg_err_code (err) != GPG_ERR_NO_VALUE)
921     es_fputs ("        crlDP: [error]\n", fp);
922   else if (!idx)
923     es_fputs ("        crlDP: [none]\n", fp);
924
925
926   /* authorityInfoAccess. */
927   for (idx=0; !(err=ksba_cert_get_authority_info_access (cert, idx, &string,
928                                                          &name)); idx++)
929     {
930       es_fputs ("     authInfo: ", fp);
931       s = get_oid_desc (string, NULL);
932       es_fprintf (fp, "%s%s%s%s\n", string, s?" (":"", s?s:"", s?")":"");
933       print_names_raw (fp, -15, name);
934       ksba_name_release (name);
935       ksba_free (string);
936     }
937   if (err && gpg_err_code (err) != GPG_ERR_EOF
938       && gpg_err_code (err) != GPG_ERR_NO_VALUE)
939     es_fputs ("     authInfo: [error]\n", fp);
940   else if (!idx)
941     es_fputs ("     authInfo: [none]\n", fp);
942
943   /* subjectInfoAccess. */
944   for (idx=0; !(err=ksba_cert_get_subject_info_access (cert, idx, &string,
945                                                          &name)); idx++)
946     {
947       es_fputs ("  subjectInfo: ", 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 ("     subjInfo: [error]\n", fp);
957   else if (!idx)
958     es_fputs ("     subjInfo: [none]\n", fp);
959
960
961   for (idx=0; !(err=ksba_cert_get_extension (cert, idx,
962                                              &oid, &i, &off, &len));idx++)
963     {
964       unsigned int flag;
965
966       s = get_oid_desc (oid, &flag);
967       if ((flag & OID_FLAG_SKIP))
968         continue;
969
970       es_fprintf (fp, "     %s: %s%s%s%s  [%d octets]\n",
971                   i? "critExtn":"    extn",
972                   oid, s?" (":"", s?s:"", s?")":"", (int)len);
973       if ((flag & OID_FLAG_UTF8))
974         {
975           if (!cert_der)
976             cert_der = ksba_cert_get_image (cert, NULL);
977           assert (cert_der);
978           print_utf8_extn_raw (fp, -15, cert_der+off, len);
979         }
980     }
981
982
983   if (with_validation)
984     {
985       err = gpgsm_validate_chain (ctrl, cert, "", NULL, 1, fp, 0, NULL);
986       if (!err)
987         es_fprintf (fp, "  [certificate is good]\n");
988       else
989         es_fprintf (fp, "  [certificate is bad: %s]\n", gpg_strerror (err));
990     }
991
992   if (opt.with_ephemeral_keys && hd)
993     {
994       unsigned int blobflags;
995
996       err = keydb_get_flags (hd, KEYBOX_FLAG_BLOB, 0, &blobflags);
997       if (err)
998         es_fprintf (fp, "  [error getting keyflags: %s]\n",gpg_strerror (err));
999       else if ((blobflags & KEYBOX_FLAG_BLOB_EPHEMERAL))
1000         es_fprintf (fp, "  [stored as ephemeral]\n");
1001     }
1002
1003 }
1004
1005
1006
1007
1008 /* List one certificate in standard mode */
1009 static void
1010 list_cert_std (ctrl_t ctrl, ksba_cert_t cert, estream_t fp, int have_secret,
1011                int with_validation)
1012 {
1013   gpg_error_t err;
1014   ksba_sexp_t sexp;
1015   char *dn;
1016   ksba_isotime_t t;
1017   int idx, i;
1018   int is_ca, chainlen;
1019   unsigned int kusage;
1020   char *string, *p, *pend;
1021   size_t off, len;
1022   const char *oid;
1023   const unsigned char *cert_der = NULL;
1024
1025   (void)have_secret;
1026
1027   es_fprintf (fp, "           ID: 0x%08lX\n",
1028               gpgsm_get_short_fingerprint (cert));
1029
1030   sexp = ksba_cert_get_serial (cert);
1031   es_fputs ("          S/N: ", fp);
1032   gpgsm_print_serial (fp, sexp);
1033   ksba_free (sexp);
1034   es_putc ('\n', fp);
1035
1036   dn = ksba_cert_get_issuer (cert, 0);
1037   es_fputs ("       Issuer: ", fp);
1038   gpgsm_es_print_name (fp, dn);
1039   ksba_free (dn);
1040   es_putc ('\n', fp);
1041   for (idx=1; (dn = ksba_cert_get_issuer (cert, idx)); idx++)
1042     {
1043       es_fputs ("          aka: ", fp);
1044       gpgsm_es_print_name (fp, dn);
1045       ksba_free (dn);
1046       es_putc ('\n', fp);
1047     }
1048
1049   dn = ksba_cert_get_subject (cert, 0);
1050   es_fputs ("      Subject: ", fp);
1051   gpgsm_es_print_name (fp, dn);
1052   ksba_free (dn);
1053   es_putc ('\n', fp);
1054   for (idx=1; (dn = ksba_cert_get_subject (cert, idx)); idx++)
1055     {
1056       es_fputs ("          aka: ", fp);
1057       gpgsm_es_print_name (fp, dn);
1058       ksba_free (dn);
1059       es_putc ('\n', fp);
1060     }
1061
1062   ksba_cert_get_validity (cert, 0, t);
1063   es_fputs ("     validity: ", fp);
1064   gpgsm_print_time (fp, t);
1065   es_fputs (" through ", fp);
1066   ksba_cert_get_validity (cert, 1, t);
1067   gpgsm_print_time (fp, t);
1068   es_putc ('\n', fp);
1069
1070
1071   {
1072     const char *algoname;
1073     unsigned int nbits;
1074
1075     algoname = gcry_pk_algo_name (gpgsm_get_key_algo_info (cert, &nbits));
1076     es_fprintf (fp, "     key type: %u bit %s\n",
1077                 nbits, algoname? algoname:"?");
1078   }
1079
1080
1081   err = ksba_cert_get_key_usage (cert, &kusage);
1082   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
1083     {
1084       es_fputs ("    key usage:", fp);
1085       if (err)
1086         es_fprintf (fp, " [error: %s]", gpg_strerror (err));
1087       else
1088         {
1089           if ( (kusage & KSBA_KEYUSAGE_DIGITAL_SIGNATURE))
1090             es_fputs (" digitalSignature", fp);
1091           if ( (kusage & KSBA_KEYUSAGE_NON_REPUDIATION))  
1092             es_fputs (" nonRepudiation", fp);
1093           if ( (kusage & KSBA_KEYUSAGE_KEY_ENCIPHERMENT)) 
1094             es_fputs (" keyEncipherment", fp);
1095           if ( (kusage & KSBA_KEYUSAGE_DATA_ENCIPHERMENT))
1096             es_fputs (" dataEncipherment", fp);
1097           if ( (kusage & KSBA_KEYUSAGE_KEY_AGREEMENT))    
1098             es_fputs (" keyAgreement", fp);
1099           if ( (kusage & KSBA_KEYUSAGE_KEY_CERT_SIGN))
1100             es_fputs (" certSign", fp);
1101           if ( (kusage & KSBA_KEYUSAGE_CRL_SIGN))  
1102             es_fputs (" crlSign", fp);
1103           if ( (kusage & KSBA_KEYUSAGE_ENCIPHER_ONLY))
1104             es_fputs (" encipherOnly", fp);
1105           if ( (kusage & KSBA_KEYUSAGE_DECIPHER_ONLY))  
1106             es_fputs (" decipherOnly", fp);
1107         }
1108       es_putc ('\n', fp);
1109     }
1110
1111   err = ksba_cert_get_ext_key_usages (cert, &string);
1112   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
1113     { 
1114       es_fputs ("ext key usage: ", fp);
1115       if (err)
1116         es_fprintf (fp, "[error: %s]", gpg_strerror (err));
1117       else
1118         {
1119           p = string;
1120           while (p && (pend=strchr (p, ':')))
1121             {
1122               *pend++ = 0;
1123               for (i=0; key_purpose_map[i].oid; i++)
1124                 if ( !strcmp (key_purpose_map[i].oid, p) )
1125                   break;
1126               es_fputs (key_purpose_map[i].oid?key_purpose_map[i].name:p, fp);
1127               p = pend;
1128               if (*p != 'C')
1129                 es_fputs (" (suggested)", fp);
1130               if ((p = strchr (p, '\n')))
1131                 {
1132                   p++;
1133                   es_fputs (", ", fp);
1134                 }
1135             }
1136           xfree (string);
1137         }
1138       es_putc ('\n', fp);
1139     }
1140
1141   /* Print restrictions.  */
1142   for (idx=0; !(err=ksba_cert_get_extension (cert, idx,
1143                                              &oid, NULL, &off, &len));idx++)
1144     {
1145       if (!strcmp (oid, OIDSTR_restriction) )
1146         {
1147           if (!cert_der)
1148             cert_der = ksba_cert_get_image (cert, NULL);
1149           assert (cert_der);
1150           es_fputs ("  restriction: ", fp);
1151           print_utf8_extn (fp, 15, cert_der+off, len);
1152         }
1153     }
1154
1155   /* Print policies.  */
1156   err = ksba_cert_get_cert_policies (cert, &string);
1157   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
1158     {
1159       es_fputs ("     policies: ", fp);
1160       if (err)
1161         es_fprintf (fp, "[error: %s]", gpg_strerror (err));
1162       else
1163         {
1164           for (p=string; *p; p++)
1165             {
1166               if (*p == '\n')
1167                 *p = ',';
1168             }
1169           es_write_sanitized (fp, string, strlen (string), NULL, NULL);
1170           xfree (string);
1171         }
1172       es_putc ('\n', fp);
1173     }
1174
1175   err = ksba_cert_is_ca (cert, &is_ca, &chainlen);
1176   if (err || is_ca)
1177     {
1178       es_fputs (" chain length: ", fp);
1179       if (gpg_err_code (err) == GPG_ERR_NO_VALUE )
1180         es_fprintf (fp, "none");
1181       else if (err)
1182         es_fprintf (fp, "[error: %s]", gpg_strerror (err));
1183       else if (chainlen == -1)
1184         es_fputs ("unlimited", fp);
1185       else
1186         es_fprintf (fp, "%d", chainlen);
1187       es_putc ('\n', fp);
1188     }
1189
1190   if (opt.with_md5_fingerprint)
1191     {
1192       dn = gpgsm_get_fingerprint_string (cert, GCRY_MD_MD5);
1193       es_fprintf (fp, "      md5 fpr: %s\n", dn?dn:"error");
1194       xfree (dn);
1195     }
1196
1197   dn = gpgsm_get_fingerprint_string (cert, 0);
1198   es_fprintf (fp, "  fingerprint: %s\n", dn?dn:"error");
1199   xfree (dn);
1200
1201
1202
1203   if (with_validation)
1204     {
1205       gpg_error_t tmperr;
1206       size_t buflen;
1207       char buffer[1];
1208       
1209       err = gpgsm_validate_chain (ctrl, cert, "", NULL, 1, fp, 0, NULL);
1210       tmperr = ksba_cert_get_user_data (cert, "is_qualified", 
1211                                         &buffer, sizeof (buffer), &buflen);
1212       if (!tmperr && buflen)
1213         {
1214           if (*buffer)
1215             es_fputs ("  [qualified]\n", fp);
1216         }    
1217       else if (gpg_err_code (tmperr) == GPG_ERR_NOT_FOUND)
1218         ; /* Don't know - will not get marked as 'q' */
1219       else
1220         log_debug ("get_user_data(is_qualified) failed: %s\n",
1221                    gpg_strerror (tmperr)); 
1222
1223       if (!err)
1224         es_fprintf (fp, "  [certificate is good]\n");
1225       else
1226         es_fprintf (fp, "  [certificate is bad: %s]\n", gpg_strerror (err));
1227     }
1228 }
1229
1230
1231 /* Same as standard mode mode list all certifying certs too. */
1232 static void
1233 list_cert_chain (ctrl_t ctrl, KEYDB_HANDLE hd,
1234                  ksba_cert_t cert, int raw_mode,
1235                  estream_t fp, int with_validation)
1236 {
1237   ksba_cert_t next = NULL;
1238
1239   if (raw_mode)
1240     list_cert_raw (ctrl, hd, cert, fp, 0, with_validation);
1241   else
1242     list_cert_std (ctrl, cert, fp, 0, with_validation);
1243   ksba_cert_ref (cert);
1244   while (!gpgsm_walk_cert_chain (ctrl, cert, &next))
1245     {
1246       ksba_cert_release (cert);
1247       es_fputs ("Certified by\n", fp);
1248       if (raw_mode)
1249         list_cert_raw (ctrl, hd, next, fp, 0, with_validation);
1250       else
1251         list_cert_std (ctrl, next, fp, 0, with_validation);
1252       cert = next;
1253     }
1254   ksba_cert_release (cert);
1255   es_putc ('\n', fp);
1256 }
1257
1258
1259 \f
1260 /* List all internal keys or just the keys given as NAMES.  MODE is a
1261    bit vector to specify what keys are to be included; see
1262    gpgsm_list_keys (below) for details.  If RAW_MODE is true, the raw
1263    output mode will be used instead of the standard beautified one.
1264  */
1265 static gpg_error_t
1266 list_internal_keys (ctrl_t ctrl, strlist_t names, estream_t fp,
1267                     unsigned int mode, int raw_mode)
1268 {
1269   KEYDB_HANDLE hd;
1270   KEYDB_SEARCH_DESC *desc = NULL;
1271   strlist_t sl;
1272   int ndesc;
1273   ksba_cert_t cert = NULL;
1274   ksba_cert_t lastcert = NULL;
1275   gpg_error_t rc = 0;
1276   const char *lastresname, *resname;
1277   int have_secret;
1278
1279   hd = keydb_new (0);
1280   if (!hd)
1281     {
1282       log_error ("keydb_new failed\n");
1283       rc = gpg_error (GPG_ERR_GENERAL);
1284       goto leave;
1285     }
1286
1287   if (!names)
1288     ndesc = 1;
1289   else
1290     {
1291       for (sl=names, ndesc=0; sl; sl = sl->next, ndesc++) 
1292         ;
1293     }
1294
1295   desc = xtrycalloc (ndesc, sizeof *desc);
1296   if (!ndesc)
1297     {
1298       rc = gpg_error_from_syserror ();
1299       log_error ("out of core\n");
1300       goto leave;
1301     }
1302
1303   if (!names)
1304     desc[0].mode = KEYDB_SEARCH_MODE_FIRST;
1305   else 
1306     {
1307       for (ndesc=0, sl=names; sl; sl = sl->next) 
1308         {
1309           rc = keydb_classify_name (sl->d, desc+ndesc);
1310           if (rc)
1311             {
1312               log_error ("key `%s' not found: %s\n",
1313                          sl->d, gpg_strerror (rc));
1314               rc = 0;
1315             }
1316           else
1317             ndesc++;
1318         }
1319       
1320     }
1321
1322   if (opt.with_ephemeral_keys)
1323     keydb_set_ephemeral (hd, 1);
1324
1325   /* It would be nice to see which of the given users did actually
1326      match one in the keyring.  To implement this we need to have a
1327      found flag for each entry in desc and to set this we must check
1328      all those entries after a match to mark all matched one -
1329      currently we stop at the first match.  To do this we need an
1330      extra flag to enable this feature so */
1331
1332   /* Suppress duplicates at least when they follow each other.  */
1333   lastresname = NULL;
1334   while (!(rc = keydb_search (hd, desc, ndesc)))
1335     {
1336       unsigned int validity;
1337
1338       if (!names) 
1339         desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
1340
1341       rc = keydb_get_flags (hd, KEYBOX_FLAG_VALIDITY, 0, &validity);
1342       if (rc)
1343         {
1344           log_error ("keydb_get_flags failed: %s\n", gpg_strerror (rc));
1345           goto leave;
1346         }
1347       rc = keydb_get_cert (hd, &cert);
1348       if (rc) 
1349         {
1350           log_error ("keydb_get_cert failed: %s\n", gpg_strerror (rc));
1351           goto leave;
1352         }
1353       /* Skip duplicated certificates, at least if they follow each
1354          others.  This works best if a single key is searched for and
1355          expected.  FIXME: Non-sequential duplicates remain.  */
1356       if (gpgsm_certs_identical_p (cert, lastcert))
1357         {
1358           ksba_cert_release (cert);
1359           continue;
1360         }
1361
1362       resname = keydb_get_resource_name (hd);
1363       
1364       if (lastresname != resname ) 
1365         {
1366           int i;
1367           
1368           if (ctrl->no_server)
1369             {
1370               es_fprintf (fp, "%s\n", resname );
1371               for (i=strlen(resname); i; i-- )
1372                 es_putc ('-', fp);
1373               es_putc ('\n', fp);
1374               lastresname = resname;
1375             }
1376         }
1377
1378       have_secret = 0;
1379       if (mode)
1380         {
1381           char *p = gpgsm_get_keygrip_hexstring (cert);
1382           if (p)
1383             {
1384               rc = gpgsm_agent_havekey (ctrl, p); 
1385              if (!rc)
1386                 have_secret = 1;
1387               else if ( gpg_err_code (rc) != GPG_ERR_NO_SECKEY)
1388                 goto leave;
1389               rc = 0;
1390               xfree (p);
1391             }
1392         }
1393
1394       if (!mode
1395           || ((mode & 1) && !have_secret)
1396           || ((mode & 2) && have_secret)  )
1397         {
1398           if (ctrl->with_colons)
1399             list_cert_colon (ctrl, cert, validity, fp, have_secret);
1400           else if (ctrl->with_chain)
1401             list_cert_chain (ctrl, hd, cert,
1402                              raw_mode, fp, ctrl->with_validation);
1403           else
1404             {
1405               if (raw_mode)
1406                 list_cert_raw (ctrl, hd, cert, fp, have_secret,
1407                                ctrl->with_validation);
1408               else
1409                 list_cert_std (ctrl, cert, fp, have_secret,
1410                                ctrl->with_validation);
1411               es_putc ('\n', fp);
1412             }
1413         }
1414
1415       ksba_cert_release (lastcert); 
1416       lastcert = cert;
1417       cert = NULL;
1418     }
1419   if (gpg_err_code (rc) == GPG_ERR_EOF || rc == -1 )
1420     rc = 0;
1421   if (rc)
1422     log_error ("keydb_search failed: %s\n", gpg_strerror (rc));
1423   
1424  leave:
1425   ksba_cert_release (cert);
1426   ksba_cert_release (lastcert); 
1427   xfree (desc);
1428   keydb_release (hd);
1429   return rc;
1430 }
1431
1432
1433
1434 static void
1435 list_external_cb (void *cb_value, ksba_cert_t cert)
1436 {
1437   struct list_external_parm_s *parm = cb_value;
1438
1439   if (keydb_store_cert (cert, 1, NULL))
1440     log_error ("error storing certificate as ephemeral\n");
1441
1442   if (parm->print_header)
1443     {
1444       const char *resname = "[external keys]";
1445       int i;
1446
1447       es_fprintf (parm->fp, "%s\n", resname );
1448       for (i=strlen(resname); i; i-- )
1449         es_putc('-', parm->fp);
1450       es_putc ('\n', parm->fp);
1451       parm->print_header = 0;
1452     }
1453
1454   if (parm->with_colons)
1455     list_cert_colon (parm->ctrl, cert, 0, parm->fp, 0);
1456   else if (parm->with_chain)
1457     list_cert_chain (parm->ctrl, NULL, cert, parm->raw_mode, parm->fp, 0);
1458   else
1459     {
1460       if (parm->raw_mode)
1461         list_cert_raw (parm->ctrl, NULL, cert, parm->fp, 0, 0);
1462       else
1463         list_cert_std (parm->ctrl, cert, parm->fp, 0, 0);
1464       es_putc ('\n', parm->fp);
1465     }
1466 }
1467
1468
1469 /* List external keys similar to internal one.  Note: mode does not
1470    make sense here because it would be unwise to list external secret
1471    keys */
1472 static gpg_error_t
1473 list_external_keys (ctrl_t ctrl, strlist_t names, estream_t fp, int raw_mode)
1474 {
1475   int rc;
1476   struct list_external_parm_s parm;
1477
1478   parm.fp = fp;
1479   parm.ctrl = ctrl,
1480   parm.print_header = ctrl->no_server;
1481   parm.with_colons = ctrl->with_colons;
1482   parm.with_chain = ctrl->with_chain;
1483   parm.raw_mode  = raw_mode;
1484
1485   rc = gpgsm_dirmngr_lookup (ctrl, names, 0, list_external_cb, &parm);
1486   if (gpg_err_code (rc) == GPG_ERR_EOF || rc == -1 
1487       || gpg_err_code (rc) == GPG_ERR_NOT_FOUND)
1488     rc = 0; /* "Not found" is not an error here. */
1489   if (rc)
1490     log_error ("listing external keys failed: %s\n", gpg_strerror (rc));
1491   return rc;
1492 }
1493
1494 /* List all keys or just the key given as NAMES.
1495    MODE controls the operation mode: 
1496     Bit 0-2:
1497       0 = list all public keys but don't flag secret ones
1498       1 = list only public keys
1499       2 = list only secret keys
1500       3 = list secret and public keys
1501     Bit 6: list internal keys
1502     Bit 7: list external keys
1503     Bit 8: Do a raw format dump.
1504  */
1505 gpg_error_t
1506 gpgsm_list_keys (ctrl_t ctrl, strlist_t names, estream_t fp,
1507                  unsigned int mode)
1508 {
1509   gpg_error_t err = 0;
1510
1511   if ((mode & (1<<6)))
1512     err = list_internal_keys (ctrl, names, fp, (mode & 3), (mode&256));
1513   if (!err && (mode & (1<<7)))
1514     err = list_external_keys (ctrl, names, fp, (mode&256)); 
1515   return err;
1516 }