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