Added qualified signature features.
[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%s\n", idx||indent_all?indent:0, "", p?p:s);
533       xfree (p);
534     }
535 }
536
537
538 /* List one certificate in raw mode useful to have a closer look at
539    the certificate.  This one does no beautification and only minimal
540    output sanitation.  It is mainly useful for debugging. */
541 static void
542 list_cert_raw (ctrl_t ctrl, KEYDB_HANDLE hd,
543                ksba_cert_t cert, FILE *fp, int have_secret,
544                int with_validation)
545 {
546   gpg_error_t err;
547   size_t off, len;
548   ksba_sexp_t sexp, keyid;
549   char *dn;
550   ksba_isotime_t t;
551   int idx, i;
552   int is_ca, chainlen;
553   unsigned int kusage;
554   char *string, *p, *pend;
555   const char *oid, *s;
556   ksba_name_t name, name2;
557   unsigned int reason;
558
559   sexp = ksba_cert_get_serial (cert);
560   fputs ("Serial number: ", fp);
561   gpgsm_print_serial (fp, sexp);
562   ksba_free (sexp);
563   putc ('\n', fp);
564
565   dn = ksba_cert_get_issuer (cert, 0);
566   fputs ("       Issuer: ", fp);
567   print_name_raw (fp, dn);
568   ksba_free (dn);
569   putc ('\n', fp);
570   for (idx=1; (dn = ksba_cert_get_issuer (cert, idx)); idx++)
571     {
572       fputs ("          aka: ", fp);
573       print_name_raw (fp, dn);
574       ksba_free (dn);
575       putc ('\n', fp);
576     }
577
578   dn = ksba_cert_get_subject (cert, 0);
579   fputs ("      Subject: ", fp);
580   print_name_raw (fp, dn);
581   ksba_free (dn);
582   putc ('\n', fp);
583   for (idx=1; (dn = ksba_cert_get_subject (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 = gpgsm_get_fingerprint_string (cert, 0);
592   fprintf (fp, "     sha1_fpr: %s\n", dn?dn:"error");
593   xfree (dn);
594
595   dn = gpgsm_get_fingerprint_string (cert, GCRY_MD_MD5);
596   fprintf (fp, "      md5_fpr: %s\n", dn?dn:"error");
597   xfree (dn);
598
599   dn = gpgsm_get_keygrip_hexstring (cert);
600   fprintf (fp, "      keygrip: %s\n", dn?dn:"error");
601   xfree (dn);
602
603   ksba_cert_get_validity (cert, 0, t);
604   fputs ("    notBefore: ", fp);
605   gpgsm_print_time (fp, t);
606   putc ('\n', fp);
607   fputs ("     notAfter: ", fp);
608   ksba_cert_get_validity (cert, 1, t);
609   gpgsm_print_time (fp, t);
610   putc ('\n', fp);
611
612   oid = ksba_cert_get_digest_algo (cert);
613   s = get_oid_desc (oid, NULL);
614   fprintf (fp, "     hashAlgo: %s%s%s%s\n", oid, s?" (":"",s?s:"",s?")":"");
615
616   {
617     const char *algoname;
618     unsigned int nbits;
619
620     algoname = gcry_pk_algo_name (gpgsm_get_key_algo_info (cert, &nbits));
621     fprintf (fp, "      keyType: %u bit %s\n",  nbits, algoname? algoname:"?");
622   }
623
624   /* subjectKeyIdentifier */
625   fputs ("    subjKeyId: ", fp);
626   err = ksba_cert_get_subj_key_id (cert, NULL, &keyid);
627   if (!err || gpg_err_code (err) == GPG_ERR_NO_DATA)
628     {
629       if (gpg_err_code (err) == GPG_ERR_NO_DATA)
630         fputs ("[none]\n", fp);
631       else
632         {
633           gpgsm_print_serial (fp, keyid);
634           ksba_free (keyid);
635           putc ('\n', fp);
636         }
637     }
638   else
639     fputs ("[?]\n", fp);
640
641
642   /* authorityKeyIdentifier */
643   fputs ("    authKeyId: ", fp);
644   err = ksba_cert_get_auth_key_id (cert, &keyid, &name, &sexp);
645   if (!err || gpg_err_code (err) == GPG_ERR_NO_DATA)
646     {
647       if (gpg_err_code (err) == GPG_ERR_NO_DATA || !name)
648         fputs ("[none]\n", fp);
649       else
650         {
651           gpgsm_print_serial (fp, sexp);
652           ksba_free (sexp);
653           putc ('\n', fp);
654           print_names_raw (fp, -15, name);
655           ksba_name_release (name);
656         }
657       if (keyid)
658         {
659           fputs (" authKeyId.ki: ", fp);
660           gpgsm_print_serial (fp, keyid);
661           ksba_free (keyid);
662           putc ('\n', fp);
663         }
664     }
665   else
666     fputs ("[?]\n", fp);
667
668   fputs ("     keyUsage:", fp);
669   err = ksba_cert_get_key_usage (cert, &kusage);
670   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
671     {
672       if (err)
673         fprintf (fp, " [error: %s]", gpg_strerror (err));
674       else
675         {
676           if ( (kusage & KSBA_KEYUSAGE_DIGITAL_SIGNATURE))
677             fputs (" digitalSignature", fp);
678           if ( (kusage & KSBA_KEYUSAGE_NON_REPUDIATION))  
679             fputs (" nonRepudiation", fp);
680           if ( (kusage & KSBA_KEYUSAGE_KEY_ENCIPHERMENT)) 
681             fputs (" keyEncipherment", fp);
682           if ( (kusage & KSBA_KEYUSAGE_DATA_ENCIPHERMENT))
683             fputs (" dataEncipherment", fp);
684           if ( (kusage & KSBA_KEYUSAGE_KEY_AGREEMENT))    
685             fputs (" keyAgreement", fp);
686           if ( (kusage & KSBA_KEYUSAGE_KEY_CERT_SIGN))
687             fputs (" certSign", fp);
688           if ( (kusage & KSBA_KEYUSAGE_CRL_SIGN))  
689             fputs (" crlSign", fp);
690           if ( (kusage & KSBA_KEYUSAGE_ENCIPHER_ONLY))
691             fputs (" encipherOnly", fp);
692           if ( (kusage & KSBA_KEYUSAGE_DECIPHER_ONLY))  
693             fputs (" decipherOnly", fp);
694         }
695       putc ('\n', fp);
696     }
697   else
698     fputs ("[none]\n", fp);
699
700   fputs ("  extKeyUsage: ", fp);
701   err = ksba_cert_get_ext_key_usages (cert, &string);
702   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
703     { 
704       if (err)
705         fprintf (fp, "[error: %s]", gpg_strerror (err));
706       else
707         {
708           p = string;
709           while (p && (pend=strchr (p, ':')))
710             {
711               *pend++ = 0;
712               for (i=0; key_purpose_map[i].oid; i++)
713                 if ( !strcmp (key_purpose_map[i].oid, p) )
714                   break;
715               fputs (key_purpose_map[i].oid?key_purpose_map[i].name:p, fp);
716               p = pend;
717               if (*p != 'C')
718                 fputs (" (suggested)", fp);
719               if ((p = strchr (p, '\n')))
720                 {
721                   p++;
722                   fputs ("\n               ", fp);
723                 }
724             }
725           xfree (string);
726         }
727       putc ('\n', fp);
728     }
729   else
730     fputs ("[none]\n", fp);
731
732
733   fputs ("     policies: ", fp);
734   err = ksba_cert_get_cert_policies (cert, &string);
735   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
736     {
737       if (err)
738         fprintf (fp, "[error: %s]", gpg_strerror (err));
739       else
740         {
741           p = string;
742           while (p && (pend=strchr (p, ':')))
743             {
744               *pend++ = 0;
745               for (i=0; key_purpose_map[i].oid; i++)
746                 if ( !strcmp (key_purpose_map[i].oid, p) )
747                   break;
748               fputs (p, fp);
749               p = pend;
750               if (*p == 'C')
751                 fputs (" (critical)", fp);
752               if ((p = strchr (p, '\n')))
753                 {
754                   p++;
755                   fputs ("\n               ", fp);
756                 }
757             }
758           xfree (string);
759         }
760       putc ('\n', fp);
761     }
762   else
763     fputs ("[none]\n", fp);
764
765   fputs ("  chainLength: ", fp);
766   err = ksba_cert_is_ca (cert, &is_ca, &chainlen);
767   if (err || is_ca)
768     {
769       if (err)
770         fprintf (fp, "[error: %s]", gpg_strerror (err));
771       else if (chainlen == -1)
772         fputs ("unlimited", fp);
773       else
774         fprintf (fp, "%d", chainlen);
775       putc ('\n', fp);
776     }
777   else
778     fputs ("not a CA\n", fp);
779
780
781   /* CRL distribution point */
782   for (idx=0; !(err=ksba_cert_get_crl_dist_point (cert, idx, &name, &name2,
783                                                   &reason)) ;idx++)
784     {
785       fputs ("        crlDP: ", fp);
786       print_names_raw (fp, 15, name);
787       if (reason)
788         {
789           fputs ("               reason: ", fp);
790           if ( (reason & KSBA_CRLREASON_UNSPECIFIED))
791             fputs (" unused", stdout);
792           if ( (reason & KSBA_CRLREASON_KEY_COMPROMISE))
793             fputs (" keyCompromise", stdout);
794           if ( (reason & KSBA_CRLREASON_CA_COMPROMISE))
795             fputs (" caCompromise", stdout);
796           if ( (reason & KSBA_CRLREASON_AFFILIATION_CHANGED))
797             fputs (" affiliationChanged", stdout);
798           if ( (reason & KSBA_CRLREASON_SUPERSEDED))
799             fputs (" superseded", stdout);
800           if ( (reason & KSBA_CRLREASON_CESSATION_OF_OPERATION))
801             fputs (" cessationOfOperation", stdout);
802           if ( (reason & KSBA_CRLREASON_CERTIFICATE_HOLD))
803             fputs (" certificateHold", stdout);
804           putchar ('\n');
805         }
806       fputs ("               issuer: ", fp);
807       print_names_raw (fp, 23, name2);
808       ksba_name_release (name);
809       ksba_name_release (name2);
810     }
811   if (err && gpg_err_code (err) != GPG_ERR_EOF)
812     fputs ("        crlDP: [error]\n", fp);
813   else if (!idx)
814     fputs ("        crlDP: [none]\n", fp);
815
816
817   /* authorityInfoAccess. */
818   for (idx=0; !(err=ksba_cert_get_authority_info_access (cert, idx, &string,
819                                                          &name)); idx++)
820     {
821       fputs ("     authInfo: ", fp);
822       s = get_oid_desc (string, NULL);
823       fprintf (fp, "%s%s%s%s\n", string, s?" (":"", s?s:"", s?")":"");
824       print_names_raw (fp, -15, name);
825       ksba_name_release (name);
826       ksba_free (string);
827     }
828   if (err && gpg_err_code (err) != GPG_ERR_EOF)
829     fputs ("     authInfo: [error]\n", fp);
830   else if (!idx)
831     fputs ("     authInfo: [none]\n", fp);
832
833   /* subjectInfoAccess. */
834   for (idx=0; !(err=ksba_cert_get_subject_info_access (cert, idx, &string,
835                                                          &name)); idx++)
836     {
837       fputs ("  subjectInfo: ", fp);
838       s = get_oid_desc (string, NULL);
839       fprintf (fp, "%s%s%s%s\n", string, s?" (":"", s?s:"", s?")":"");
840       print_names_raw (fp, -15, name);
841       ksba_name_release (name);
842       ksba_free (string);
843     }
844   if (err && gpg_err_code (err) != GPG_ERR_EOF)
845     fputs ("     subjInfo: [error]\n", fp);
846   else if (!idx)
847     fputs ("     subjInfo: [none]\n", fp);
848
849
850   for (idx=0; !(err=ksba_cert_get_extension (cert, idx,
851                                              &oid, &i, &off, &len));idx++)
852     {
853       unsigned int flag;
854
855       s = get_oid_desc (oid, &flag);
856
857       if (!(flag & 1))
858         fprintf (fp, "     %s: %s%s%s%s  [%d octets]\n",
859                  i? "critExtn":"    extn",
860                  oid, s?" (":"", s?s:"", s?")":"", (int)len);
861     }
862
863
864   if (with_validation)
865     {
866       err = gpgsm_validate_chain (ctrl, cert, NULL, 1, fp, 0);
867       if (!err)
868         fprintf (fp, "  [certificate is good]\n");
869       else
870         fprintf (fp, "  [certificate is bad: %s]\n", gpg_strerror (err));
871     }
872
873   if (opt.with_ephemeral_keys && hd)
874     {
875       unsigned int blobflags;
876
877       err = keydb_get_flags (hd, KEYBOX_FLAG_BLOB, 0, &blobflags);
878       if (err)
879         fprintf (fp, "  [error getting keyflags: %s]\n", gpg_strerror (err));
880       else if ((blobflags & 2))
881         fprintf (fp, "  [stored as ephemeral]\n");
882     }
883
884 }
885
886
887
888
889 /* List one certificate in standard mode */
890 static void
891 list_cert_std (ctrl_t ctrl, ksba_cert_t cert, FILE *fp, int have_secret,
892                int with_validation)
893 {
894   gpg_error_t err;
895   ksba_sexp_t sexp;
896   char *dn;
897   ksba_isotime_t t;
898   int idx, i;
899   int is_ca, chainlen;
900   unsigned int kusage;
901   char *string, *p, *pend;
902
903   sexp = ksba_cert_get_serial (cert);
904   fputs ("Serial number: ", fp);
905   gpgsm_print_serial (fp, sexp);
906   ksba_free (sexp);
907   putc ('\n', fp);
908
909   dn = ksba_cert_get_issuer (cert, 0);
910   fputs ("       Issuer: ", fp);
911   gpgsm_print_name (fp, dn);
912   ksba_free (dn);
913   putc ('\n', fp);
914   for (idx=1; (dn = ksba_cert_get_issuer (cert, idx)); idx++)
915     {
916       fputs ("          aka: ", fp);
917       gpgsm_print_name (fp, dn);
918       ksba_free (dn);
919       putc ('\n', fp);
920     }
921
922   dn = ksba_cert_get_subject (cert, 0);
923   fputs ("      Subject: ", fp);
924   gpgsm_print_name (fp, dn);
925   ksba_free (dn);
926   putc ('\n', fp);
927   for (idx=1; (dn = ksba_cert_get_subject (cert, idx)); idx++)
928     {
929       fputs ("          aka: ", fp);
930       gpgsm_print_name (fp, dn);
931       ksba_free (dn);
932       putc ('\n', fp);
933     }
934
935   ksba_cert_get_validity (cert, 0, t);
936   fputs ("     validity: ", fp);
937   gpgsm_print_time (fp, t);
938   fputs (" through ", fp);
939   ksba_cert_get_validity (cert, 1, t);
940   gpgsm_print_time (fp, t);
941   putc ('\n', fp);
942
943
944   {
945     const char *algoname;
946     unsigned int nbits;
947
948     algoname = gcry_pk_algo_name (gpgsm_get_key_algo_info (cert, &nbits));
949     fprintf (fp, "     key type: %u bit %s\n", nbits, algoname? algoname:"?");
950   }
951
952
953   err = ksba_cert_get_key_usage (cert, &kusage);
954   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
955     {
956       fputs ("    key usage:", fp);
957       if (err)
958         fprintf (fp, " [error: %s]", gpg_strerror (err));
959       else
960         {
961           if ( (kusage & KSBA_KEYUSAGE_DIGITAL_SIGNATURE))
962             fputs (" digitalSignature", fp);
963           if ( (kusage & KSBA_KEYUSAGE_NON_REPUDIATION))  
964             fputs (" nonRepudiation", fp);
965           if ( (kusage & KSBA_KEYUSAGE_KEY_ENCIPHERMENT)) 
966             fputs (" keyEncipherment", fp);
967           if ( (kusage & KSBA_KEYUSAGE_DATA_ENCIPHERMENT))
968             fputs (" dataEncipherment", fp);
969           if ( (kusage & KSBA_KEYUSAGE_KEY_AGREEMENT))    
970             fputs (" keyAgreement", fp);
971           if ( (kusage & KSBA_KEYUSAGE_KEY_CERT_SIGN))
972             fputs (" certSign", fp);
973           if ( (kusage & KSBA_KEYUSAGE_CRL_SIGN))  
974             fputs (" crlSign", fp);
975           if ( (kusage & KSBA_KEYUSAGE_ENCIPHER_ONLY))
976             fputs (" encipherOnly", fp);
977           if ( (kusage & KSBA_KEYUSAGE_DECIPHER_ONLY))  
978             fputs (" decipherOnly", fp);
979         }
980       putc ('\n', fp);
981     }
982
983   err = ksba_cert_get_ext_key_usages (cert, &string);
984   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
985     { 
986       fputs ("ext key usage: ", fp);
987       if (err)
988         fprintf (fp, "[error: %s]", gpg_strerror (err));
989       else
990         {
991           p = string;
992           while (p && (pend=strchr (p, ':')))
993             {
994               *pend++ = 0;
995               for (i=0; key_purpose_map[i].oid; i++)
996                 if ( !strcmp (key_purpose_map[i].oid, p) )
997                   break;
998               fputs (key_purpose_map[i].oid?key_purpose_map[i].name:p, fp);
999               p = pend;
1000               if (*p != 'C')
1001                 fputs (" (suggested)", fp);
1002               if ((p = strchr (p, '\n')))
1003                 {
1004                   p++;
1005                   fputs (", ", fp);
1006                 }
1007             }
1008           xfree (string);
1009         }
1010       putc ('\n', fp);
1011     }
1012
1013   err = ksba_cert_get_cert_policies (cert, &string);
1014   if (gpg_err_code (err) != GPG_ERR_NO_DATA)
1015     {
1016       fputs ("     policies: ", fp);
1017       if (err)
1018         fprintf (fp, "[error: %s]", gpg_strerror (err));
1019       else
1020         {
1021           for (p=string; *p; p++)
1022             {
1023               if (*p == '\n')
1024                 *p = ',';
1025             }
1026           print_sanitized_string (fp, string, 0);
1027           xfree (string);
1028         }
1029       putc ('\n', fp);
1030     }
1031
1032   err = ksba_cert_is_ca (cert, &is_ca, &chainlen);
1033   if (err || is_ca)
1034     {
1035       fputs (" chain length: ", fp);
1036       if (err)
1037         fprintf (fp, "[error: %s]", gpg_strerror (err));
1038       else if (chainlen == -1)
1039         fputs ("unlimited", fp);
1040       else
1041         fprintf (fp, "%d", chainlen);
1042       putc ('\n', fp);
1043     }
1044
1045   if (opt.with_md5_fingerprint)
1046     {
1047       dn = gpgsm_get_fingerprint_string (cert, GCRY_MD_MD5);
1048       fprintf (fp, "      md5 fpr: %s\n", dn?dn:"error");
1049       xfree (dn);
1050     }
1051
1052   dn = gpgsm_get_fingerprint_string (cert, 0);
1053   fprintf (fp, "  fingerprint: %s\n", dn?dn:"error");
1054   xfree (dn);
1055
1056
1057
1058   if (with_validation)
1059     {
1060       gpg_error_t tmperr;
1061       size_t buflen;
1062       char buffer[1];
1063       
1064       err = gpgsm_validate_chain (ctrl, cert, NULL, 1, fp, 0);
1065       tmperr = ksba_cert_get_user_data (cert, "is_qualified", 
1066                                         &buffer, sizeof (buffer), &buflen);
1067       if (!tmperr && buflen)
1068         {
1069           if (*buffer)
1070             fputs ("  [qualified]\n", fp);
1071         }    
1072       else if (gpg_err_code (tmperr) == GPG_ERR_NOT_FOUND)
1073         ; /* Don't know - will not get marked as 'q' */
1074       else
1075         log_debug ("get_user_data(is_qualified) failed: %s\n",
1076                    gpg_strerror (tmperr)); 
1077
1078       if (!err)
1079         fprintf (fp, "  [certificate is good]\n");
1080       else
1081         fprintf (fp, "  [certificate is bad: %s]\n", gpg_strerror (err));
1082     }
1083 }
1084
1085
1086 /* Same as standard mode mode list all certifying certs too. */
1087 static void
1088 list_cert_chain (ctrl_t ctrl, KEYDB_HANDLE hd,
1089                  ksba_cert_t cert, int raw_mode,
1090                  FILE *fp, int with_validation)
1091 {
1092   ksba_cert_t next = NULL;
1093
1094   if (raw_mode)
1095     list_cert_raw (ctrl, hd, cert, fp, 0, with_validation);
1096   else
1097     list_cert_std (ctrl, cert, fp, 0, with_validation);
1098   ksba_cert_ref (cert);
1099   while (!gpgsm_walk_cert_chain (cert, &next))
1100     {
1101       ksba_cert_release (cert);
1102       fputs ("Certified by\n", fp);
1103       if (raw_mode)
1104         list_cert_raw (ctrl, hd, next, fp, 0, with_validation);
1105       else
1106         list_cert_std (ctrl, next, fp, 0, with_validation);
1107       cert = next;
1108     }
1109   ksba_cert_release (cert);
1110   putc ('\n', fp);
1111 }
1112
1113
1114 \f
1115 /* List all internal keys or just the keys given as NAMES.  MODE is a
1116    bit vector to specify what keys are to be included; see
1117    gpgsm_list_keys (below) for details.  If RAW_MODE is true, the raw
1118    output mode will be used intead of the standard beautified one.
1119  */
1120 static gpg_error_t
1121 list_internal_keys (ctrl_t ctrl, STRLIST names, FILE *fp,
1122                     unsigned int mode, int raw_mode)
1123 {
1124   KEYDB_HANDLE hd;
1125   KEYDB_SEARCH_DESC *desc = NULL;
1126   STRLIST sl;
1127   int ndesc;
1128   ksba_cert_t cert = NULL;
1129   gpg_error_t rc = 0;
1130   const char *lastresname, *resname;
1131   int have_secret;
1132
1133   hd = keydb_new (0);
1134   if (!hd)
1135     {
1136       log_error ("keydb_new failed\n");
1137       rc = gpg_error (GPG_ERR_GENERAL);
1138       goto leave;
1139     }
1140
1141   if (!names)
1142     ndesc = 1;
1143   else
1144     {
1145       for (sl=names, ndesc=0; sl; sl = sl->next, ndesc++) 
1146         ;
1147     }
1148
1149   desc = xtrycalloc (ndesc, sizeof *desc);
1150   if (!ndesc)
1151     {
1152       rc = gpg_error_from_errno (errno);
1153       log_error ("out of core\n");
1154       goto leave;
1155     }
1156
1157   if (!names)
1158     desc[0].mode = KEYDB_SEARCH_MODE_FIRST;
1159   else 
1160     {
1161       for (ndesc=0, sl=names; sl; sl = sl->next) 
1162         {
1163           rc = keydb_classify_name (sl->d, desc+ndesc);
1164           if (rc)
1165             {
1166               log_error ("key `%s' not found: %s\n",
1167                          sl->d, gpg_strerror (rc));
1168               rc = 0;
1169             }
1170           else
1171             ndesc++;
1172         }
1173       
1174     }
1175
1176   if (opt.with_ephemeral_keys)
1177     keydb_set_ephemeral (hd, 1);
1178
1179   /* It would be nice to see which of the given users did actually
1180      match one in the keyring.  To implement this we need to have a
1181      found flag for each entry in desc and to set this we must check
1182      all those entries after a match to mark all matched one -
1183      currently we stop at the first match.  To do this we need an
1184      extra flag to enable this feature so */
1185
1186   lastresname = NULL;
1187   while (!(rc = keydb_search (hd, desc, ndesc)))
1188     {
1189       unsigned int validity;
1190
1191       if (!names) 
1192         desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
1193
1194       rc = keydb_get_flags (hd, KEYBOX_FLAG_VALIDITY, 0, &validity);
1195       if (rc)
1196         {
1197           log_error ("keydb_get_flags failed: %s\n", gpg_strerror (rc));
1198           goto leave;
1199         }
1200       rc = keydb_get_cert (hd, &cert);
1201       if (rc) 
1202         {
1203           log_error ("keydb_get_cert failed: %s\n", gpg_strerror (rc));
1204           goto leave;
1205         }
1206       
1207       resname = keydb_get_resource_name (hd);
1208       
1209       if (lastresname != resname ) 
1210         {
1211           int i;
1212           
1213           if (ctrl->no_server)
1214             {
1215               fprintf (fp, "%s\n", resname );
1216               for (i=strlen(resname); i; i-- )
1217                 putchar('-');
1218               putc ('\n', fp);
1219               lastresname = resname;
1220             }
1221         }
1222
1223       have_secret = 0;
1224       if (mode)
1225         {
1226           char *p = gpgsm_get_keygrip_hexstring (cert);
1227           if (p)
1228             {
1229               rc = gpgsm_agent_havekey (ctrl, p); 
1230              if (!rc)
1231                 have_secret = 1;
1232               else if ( gpg_err_code (rc) != GPG_ERR_NO_SECKEY)
1233                 goto leave;
1234               rc = 0;
1235               xfree (p);
1236             }
1237         }
1238
1239       if (!mode
1240           || ((mode & 1) && !have_secret)
1241           || ((mode & 2) && have_secret)  )
1242         {
1243           if (ctrl->with_colons)
1244             list_cert_colon (ctrl, cert, validity, fp, have_secret);
1245           else if (ctrl->with_chain)
1246             list_cert_chain (ctrl, hd, cert,
1247                              raw_mode, fp, ctrl->with_validation);
1248           else
1249             {
1250               if (raw_mode)
1251                 list_cert_raw (ctrl, hd, cert, fp, have_secret,
1252                                ctrl->with_validation);
1253               else
1254                 list_cert_std (ctrl, cert, fp, have_secret,
1255                                ctrl->with_validation);
1256               putc ('\n', fp);
1257             }
1258         }
1259       ksba_cert_release (cert); 
1260       cert = NULL;
1261     }
1262   if (gpg_err_code (rc) == GPG_ERR_EOF || rc == -1 )
1263     rc = 0;
1264   if (rc)
1265     log_error ("keydb_search failed: %s\n", gpg_strerror (rc));
1266   
1267  leave:
1268   ksba_cert_release (cert);
1269   xfree (desc);
1270   keydb_release (hd);
1271   return rc;
1272 }
1273
1274
1275
1276 static void
1277 list_external_cb (void *cb_value, ksba_cert_t cert)
1278 {
1279   struct list_external_parm_s *parm = cb_value;
1280
1281   if (keydb_store_cert (cert, 1, NULL))
1282     log_error ("error storing certificate as ephemeral\n");
1283
1284   if (parm->print_header)
1285     {
1286       const char *resname = "[external keys]";
1287       int i;
1288
1289       fprintf (parm->fp, "%s\n", resname );
1290       for (i=strlen(resname); i; i-- )
1291         putchar('-');
1292       putc ('\n', parm->fp);
1293       parm->print_header = 0;
1294     }
1295
1296   if (parm->with_colons)
1297     list_cert_colon (parm->ctrl, cert, 0, parm->fp, 0);
1298   else if (parm->with_chain)
1299     list_cert_chain (parm->ctrl, NULL, cert, parm->raw_mode, parm->fp, 0);
1300   else
1301     {
1302       if (parm->raw_mode)
1303         list_cert_raw (parm->ctrl, NULL, cert, parm->fp, 0, 0);
1304       else
1305         list_cert_std (parm->ctrl, cert, parm->fp, 0, 0);
1306       putc ('\n', parm->fp);
1307     }
1308 }
1309
1310
1311 /* List external keys similar to internal one.  Note: mode does not
1312    make sense here because it would be unwise to list external secret
1313    keys */
1314 static gpg_error_t
1315 list_external_keys (CTRL ctrl, STRLIST names, FILE *fp, int raw_mode)
1316 {
1317   int rc;
1318   struct list_external_parm_s parm;
1319
1320   parm.fp = fp;
1321   parm.ctrl = ctrl,
1322   parm.print_header = ctrl->no_server;
1323   parm.with_colons = ctrl->with_colons;
1324   parm.with_chain = ctrl->with_chain;
1325   parm.raw_mode  = raw_mode;
1326
1327   rc = gpgsm_dirmngr_lookup (ctrl, names, list_external_cb, &parm);
1328   if (rc)
1329     log_error ("listing external keys failed: %s\n", gpg_strerror (rc));
1330   return rc;
1331 }
1332
1333 /* List all keys or just the key given as NAMES.
1334    MODE controls the operation mode: 
1335     Bit 0-2:
1336       0 = list all public keys but don't flag secret ones
1337       1 = list only public keys
1338       2 = list only secret keys
1339       3 = list secret and public keys
1340     Bit 6: list internal keys
1341     Bit 7: list external keys
1342     Bit 8: Do a raw format dump.
1343  */
1344 gpg_error_t
1345 gpgsm_list_keys (CTRL ctrl, STRLIST names, FILE *fp, unsigned int mode)
1346 {
1347   gpg_error_t err = 0;
1348
1349   if ((mode & (1<<6)))
1350     err = list_internal_keys (ctrl, names, fp, (mode & 3), (mode&256));
1351   if (!err && (mode & (1<<7)))
1352     err = list_external_keys (ctrl, names, fp, (mode&256)); 
1353   return err;
1354 }