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