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